desktop: Take ownership of `EventLoop` on `App::run`
Change `App::event_loop` to an `Option` that will be taken on `App::run` so that `App::run` can continue to call methods on `self` later. This is a little awkward, and better might be to remove `App::new` and make `App:run` return `Result<!, Error>,` but `!` types are experimental.
This commit is contained in:
parent
c00b4bf55c
commit
3f878cc869
|
@ -46,7 +46,7 @@ use winit::event::{
|
||||||
ElementState, KeyboardInput, ModifiersState, MouseButton, MouseScrollDelta, VirtualKeyCode,
|
ElementState, KeyboardInput, ModifiersState, MouseButton, MouseScrollDelta, VirtualKeyCode,
|
||||||
WindowEvent,
|
WindowEvent,
|
||||||
};
|
};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy};
|
||||||
use winit::window::{Fullscreen, Icon, Window, WindowBuilder};
|
use winit::window::{Fullscreen, Icon, Window, WindowBuilder};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
@ -278,7 +278,8 @@ fn get_screen_size(event_loop: &EventLoop<RuffleEvent>) -> PhysicalSize<u32> {
|
||||||
struct App {
|
struct App {
|
||||||
opt: Opt,
|
opt: Opt,
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
event_loop: EventLoop<RuffleEvent>,
|
event_loop: Option<EventLoop<RuffleEvent>>,
|
||||||
|
event_loop_proxy: EventLoopProxy<RuffleEvent>,
|
||||||
executor: Arc<Mutex<GlutinAsyncExecutor>>,
|
executor: Arc<Mutex<GlutinAsyncExecutor>>,
|
||||||
gui: Arc<Mutex<GuiController>>,
|
gui: Arc<Mutex<GuiController>>,
|
||||||
player: Arc<Mutex<Player>>,
|
player: Arc<Mutex<Player>>,
|
||||||
|
@ -416,7 +417,8 @@ impl App {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opt,
|
opt,
|
||||||
window,
|
window,
|
||||||
event_loop,
|
event_loop_proxy: event_loop.create_proxy(),
|
||||||
|
event_loop: Some(event_loop),
|
||||||
executor,
|
executor,
|
||||||
gui,
|
gui,
|
||||||
player,
|
player,
|
||||||
|
@ -425,7 +427,7 @@ impl App {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(self) -> ! {
|
fn run(mut self) -> ! {
|
||||||
enum LoadingState {
|
enum LoadingState {
|
||||||
Loading,
|
Loading,
|
||||||
WaitingForResize,
|
WaitingForResize,
|
||||||
|
@ -440,294 +442,288 @@ impl App {
|
||||||
let mut fullscreen_down = false;
|
let mut fullscreen_down = false;
|
||||||
|
|
||||||
// Poll UI events.
|
// Poll UI events.
|
||||||
self.event_loop
|
let event_loop = self.event_loop.take().expect("App already running");
|
||||||
.run(move |event, _window_target, control_flow| {
|
event_loop.run(move |event, _window_target, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
winit::event::Event::LoopDestroyed => {
|
winit::event::Event::LoopDestroyed => {
|
||||||
self.player
|
self.player
|
||||||
.lock()
|
.lock()
|
||||||
.expect("Cannot reenter")
|
.expect("Cannot reenter")
|
||||||
.flush_shared_objects();
|
.flush_shared_objects();
|
||||||
shutdown();
|
shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Core loop
|
||||||
|
winit::event::Event::MainEventsCleared
|
||||||
|
if matches!(loaded, LoadingState::Loaded) =>
|
||||||
|
{
|
||||||
|
let new_time = Instant::now();
|
||||||
|
let dt = new_time.duration_since(time).as_micros();
|
||||||
|
if dt > 0 {
|
||||||
|
time = new_time;
|
||||||
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
|
player_lock.tick(dt as f64 / 1000.0);
|
||||||
|
next_frame_time = new_time + player_lock.time_til_next_frame();
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
self.window.request_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render
|
||||||
|
winit::event::Event::RedrawRequested(_) => {
|
||||||
|
// Don't render when minimized to avoid potential swap chain errors in `wgpu`.
|
||||||
|
if !minimized {
|
||||||
|
self.player.lock().expect("Cannot reenter").render();
|
||||||
|
#[cfg(feature = "tracy")]
|
||||||
|
tracing_tracy::client::Client::running()
|
||||||
|
.expect("tracy client must be running")
|
||||||
|
.frame_mark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
winit::event::Event::WindowEvent { event, .. } => {
|
||||||
|
if self.gui.lock().expect("Gui lock").handle_event(&event) {
|
||||||
|
// Event consumed by GUI.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
match event {
|
||||||
|
WindowEvent::CloseRequested => {
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WindowEvent::Resized(size) => {
|
||||||
|
// TODO: Change this when winit adds a `Window::minimzed` or `WindowEvent::Minimize`.
|
||||||
|
minimized = size.width == 0 && size.height == 0;
|
||||||
|
|
||||||
// Core loop
|
let viewport_scale_factor = self.window.scale_factor();
|
||||||
winit::event::Event::MainEventsCleared
|
|
||||||
if matches!(loaded, LoadingState::Loaded) =>
|
|
||||||
{
|
|
||||||
let new_time = Instant::now();
|
|
||||||
let dt = new_time.duration_since(time).as_micros();
|
|
||||||
if dt > 0 {
|
|
||||||
time = new_time;
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
player_lock.tick(dt as f64 / 1000.0);
|
player_lock.set_viewport_dimensions(ViewportDimensions {
|
||||||
next_frame_time = new_time + player_lock.time_til_next_frame();
|
width: size.width,
|
||||||
|
height: size.height,
|
||||||
|
scale_factor: viewport_scale_factor,
|
||||||
|
});
|
||||||
|
self.window.request_redraw();
|
||||||
|
if matches!(loaded, LoadingState::WaitingForResize) {
|
||||||
|
loaded = LoadingState::Loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowEvent::CursorMoved { position, .. } => {
|
||||||
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
|
mouse_pos = position;
|
||||||
|
let event = PlayerEvent::MouseMove {
|
||||||
|
x: position.x,
|
||||||
|
y: position.y,
|
||||||
|
};
|
||||||
|
player_lock.handle_event(event);
|
||||||
if player_lock.needs_render() {
|
if player_lock.needs_render() {
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
WindowEvent::MouseInput { button, state, .. } => {
|
||||||
|
use ruffle_core::events::MouseButton as RuffleMouseButton;
|
||||||
// Render
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
winit::event::Event::RedrawRequested(_) => {
|
let x = mouse_pos.x;
|
||||||
// Don't render when minimized to avoid potential swap chain errors in `wgpu`.
|
let y = mouse_pos.y;
|
||||||
if !minimized {
|
let button = match button {
|
||||||
self.player.lock().expect("Cannot reenter").render();
|
MouseButton::Left => RuffleMouseButton::Left,
|
||||||
#[cfg(feature = "tracy")]
|
MouseButton::Right => RuffleMouseButton::Right,
|
||||||
tracing_tracy::client::Client::running()
|
MouseButton::Middle => RuffleMouseButton::Middle,
|
||||||
.expect("tracy client must be running")
|
MouseButton::Other(_) => RuffleMouseButton::Unknown,
|
||||||
.frame_mark();
|
};
|
||||||
}
|
let event = match state {
|
||||||
}
|
ElementState::Pressed => PlayerEvent::MouseDown { x, y, button },
|
||||||
|
ElementState::Released => PlayerEvent::MouseUp { x, y, button },
|
||||||
winit::event::Event::WindowEvent { event, .. } => {
|
};
|
||||||
if self.gui.lock().expect("Gui lock").handle_event(&event) {
|
player_lock.handle_event(event);
|
||||||
// Event consumed by GUI.
|
if player_lock.needs_render() {
|
||||||
return;
|
|
||||||
}
|
|
||||||
match event {
|
|
||||||
WindowEvent::CloseRequested => {
|
|
||||||
*control_flow = ControlFlow::Exit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WindowEvent::Resized(size) => {
|
|
||||||
// TODO: Change this when winit adds a `Window::minimzed` or `WindowEvent::Minimize`.
|
|
||||||
minimized = size.width == 0 && size.height == 0;
|
|
||||||
|
|
||||||
let viewport_scale_factor = self.window.scale_factor();
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
|
||||||
player_lock.set_viewport_dimensions(ViewportDimensions {
|
|
||||||
width: size.width,
|
|
||||||
height: size.height,
|
|
||||||
scale_factor: viewport_scale_factor,
|
|
||||||
});
|
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
if matches!(loaded, LoadingState::WaitingForResize) {
|
|
||||||
loaded = LoadingState::Loaded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
}
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
WindowEvent::MouseWheel { delta, .. } => {
|
||||||
mouse_pos = position;
|
use ruffle_core::events::MouseWheelDelta;
|
||||||
let event = PlayerEvent::MouseMove {
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
x: position.x,
|
let delta = match delta {
|
||||||
y: position.y,
|
MouseScrollDelta::LineDelta(_, dy) => {
|
||||||
};
|
MouseWheelDelta::Lines(dy.into())
|
||||||
player_lock.handle_event(event);
|
|
||||||
if player_lock.needs_render() {
|
|
||||||
self.window.request_redraw();
|
|
||||||
}
|
}
|
||||||
|
MouseScrollDelta::PixelDelta(pos) => MouseWheelDelta::Pixels(pos.y),
|
||||||
|
};
|
||||||
|
let event = PlayerEvent::MouseWheel { delta };
|
||||||
|
player_lock.handle_event(event);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
WindowEvent::MouseInput { button, state, .. } => {
|
}
|
||||||
use ruffle_core::events::MouseButton as RuffleMouseButton;
|
WindowEvent::CursorEntered { .. } => {
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
let x = mouse_pos.x;
|
player_lock.set_mouse_in_stage(true);
|
||||||
let y = mouse_pos.y;
|
if player_lock.needs_render() {
|
||||||
let button = match button {
|
self.window.request_redraw();
|
||||||
MouseButton::Left => RuffleMouseButton::Left,
|
}
|
||||||
MouseButton::Right => RuffleMouseButton::Right,
|
}
|
||||||
MouseButton::Middle => RuffleMouseButton::Middle,
|
WindowEvent::CursorLeft { .. } => {
|
||||||
MouseButton::Other(_) => RuffleMouseButton::Unknown,
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
};
|
player_lock.set_mouse_in_stage(false);
|
||||||
let event = match state {
|
player_lock.handle_event(PlayerEvent::MouseLeave);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
self.window.request_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||||
|
modifiers = new_modifiers;
|
||||||
|
}
|
||||||
|
WindowEvent::KeyboardInput { input, .. } => {
|
||||||
|
// Handle fullscreen keyboard shortcuts: Alt+Return, Escape.
|
||||||
|
match input {
|
||||||
|
KeyboardInput {
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(VirtualKeyCode::Return),
|
||||||
|
..
|
||||||
|
} if modifiers.alt() => {
|
||||||
|
if !fullscreen_down {
|
||||||
|
self.player.lock().expect("Cannot reenter").update(|uc| {
|
||||||
|
uc.stage.toggle_display_state(uc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fullscreen_down = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
KeyboardInput {
|
||||||
|
state: ElementState::Released,
|
||||||
|
virtual_keycode: Some(VirtualKeyCode::Return),
|
||||||
|
..
|
||||||
|
} if fullscreen_down => {
|
||||||
|
fullscreen_down = false;
|
||||||
|
}
|
||||||
|
KeyboardInput {
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||||
|
..
|
||||||
|
} => self.player.lock().expect("Cannot reenter").update(|uc| {
|
||||||
|
uc.stage.set_display_state(uc, StageDisplayState::Normal);
|
||||||
|
}),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
|
if let Some(key) = input.virtual_keycode {
|
||||||
|
let key_code = winit_to_ruffle_key_code(key);
|
||||||
|
let key_char = winit_key_to_char(key, modifiers.shift());
|
||||||
|
match input.state {
|
||||||
ElementState::Pressed => {
|
ElementState::Pressed => {
|
||||||
PlayerEvent::MouseDown { x, y, button }
|
player_lock.handle_event(PlayerEvent::KeyDown {
|
||||||
}
|
key_code,
|
||||||
ElementState::Released => PlayerEvent::MouseUp { x, y, button },
|
key_char,
|
||||||
};
|
});
|
||||||
player_lock.handle_event(event);
|
if let Some(control_code) =
|
||||||
if player_lock.needs_render() {
|
winit_to_ruffle_text_control(key, modifiers)
|
||||||
self.window.request_redraw();
|
{
|
||||||
}
|
player_lock.handle_event(PlayerEvent::TextControl {
|
||||||
}
|
code: control_code,
|
||||||
WindowEvent::MouseWheel { delta, .. } => {
|
|
||||||
use ruffle_core::events::MouseWheelDelta;
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
|
||||||
let delta = match delta {
|
|
||||||
MouseScrollDelta::LineDelta(_, dy) => {
|
|
||||||
MouseWheelDelta::Lines(dy.into())
|
|
||||||
}
|
|
||||||
MouseScrollDelta::PixelDelta(pos) => {
|
|
||||||
MouseWheelDelta::Pixels(pos.y)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let event = PlayerEvent::MouseWheel { delta };
|
|
||||||
player_lock.handle_event(event);
|
|
||||||
if player_lock.needs_render() {
|
|
||||||
self.window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::CursorEntered { .. } => {
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
|
||||||
player_lock.set_mouse_in_stage(true);
|
|
||||||
if player_lock.needs_render() {
|
|
||||||
self.window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::CursorLeft { .. } => {
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
|
||||||
player_lock.set_mouse_in_stage(false);
|
|
||||||
player_lock.handle_event(PlayerEvent::MouseLeave);
|
|
||||||
if player_lock.needs_render() {
|
|
||||||
self.window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
|
||||||
modifiers = new_modifiers;
|
|
||||||
}
|
|
||||||
WindowEvent::KeyboardInput { input, .. } => {
|
|
||||||
// Handle fullscreen keyboard shortcuts: Alt+Return, Escape.
|
|
||||||
match input {
|
|
||||||
KeyboardInput {
|
|
||||||
state: ElementState::Pressed,
|
|
||||||
virtual_keycode: Some(VirtualKeyCode::Return),
|
|
||||||
..
|
|
||||||
} if modifiers.alt() => {
|
|
||||||
if !fullscreen_down {
|
|
||||||
self.player.lock().expect("Cannot reenter").update(
|
|
||||||
|uc| {
|
|
||||||
uc.stage.toggle_display_state(uc);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fullscreen_down = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
KeyboardInput {
|
|
||||||
state: ElementState::Released,
|
|
||||||
virtual_keycode: Some(VirtualKeyCode::Return),
|
|
||||||
..
|
|
||||||
} if fullscreen_down => {
|
|
||||||
fullscreen_down = false;
|
|
||||||
}
|
|
||||||
KeyboardInput {
|
|
||||||
state: ElementState::Pressed,
|
|
||||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
|
||||||
..
|
|
||||||
} => self.player.lock().expect("Cannot reenter").update(|uc| {
|
|
||||||
uc.stage.set_display_state(uc, StageDisplayState::Normal);
|
|
||||||
}),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
|
||||||
if let Some(key) = input.virtual_keycode {
|
|
||||||
let key_code = winit_to_ruffle_key_code(key);
|
|
||||||
let key_char = winit_key_to_char(key, modifiers.shift());
|
|
||||||
match input.state {
|
|
||||||
ElementState::Pressed => {
|
|
||||||
player_lock.handle_event(PlayerEvent::KeyDown {
|
|
||||||
key_code,
|
|
||||||
key_char,
|
|
||||||
});
|
|
||||||
if let Some(control_code) =
|
|
||||||
winit_to_ruffle_text_control(key, modifiers)
|
|
||||||
{
|
|
||||||
player_lock.handle_event(
|
|
||||||
PlayerEvent::TextControl { code: control_code },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ElementState::Released => {
|
|
||||||
player_lock.handle_event(PlayerEvent::KeyUp {
|
|
||||||
key_code,
|
|
||||||
key_char,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if player_lock.needs_render() {
|
|
||||||
self.window.request_redraw();
|
|
||||||
}
|
}
|
||||||
}
|
ElementState::Released => {
|
||||||
}
|
player_lock.handle_event(PlayerEvent::KeyUp {
|
||||||
WindowEvent::ReceivedCharacter(codepoint) => {
|
key_code,
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
key_char,
|
||||||
let event = PlayerEvent::TextInput { codepoint };
|
});
|
||||||
player_lock.handle_event(event);
|
}
|
||||||
|
};
|
||||||
if player_lock.needs_render() {
|
if player_lock.needs_render() {
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
WindowEvent::ReceivedCharacter(codepoint) => {
|
||||||
winit::event::Event::UserEvent(RuffleEvent::TaskPoll) => self
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
.executor
|
let event = PlayerEvent::TextInput { codepoint };
|
||||||
.lock()
|
player_lock.handle_event(event);
|
||||||
.expect("active executor reference")
|
if player_lock.needs_render() {
|
||||||
.poll_all(),
|
self.window.request_redraw();
|
||||||
winit::event::Event::UserEvent(RuffleEvent::OnMetadata(swf_header)) => {
|
|
||||||
let movie_width = swf_header.stage_size().width().to_pixels();
|
|
||||||
let movie_height = swf_header.stage_size().height().to_pixels();
|
|
||||||
|
|
||||||
let window_size: Size = match (self.opt.width, self.opt.height) {
|
|
||||||
(None, None) => LogicalSize::new(movie_width, movie_height).into(),
|
|
||||||
(Some(width), None) => {
|
|
||||||
let scale = width / movie_width;
|
|
||||||
let height = movie_height * scale;
|
|
||||||
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
|
||||||
}
|
}
|
||||||
(None, Some(height)) => {
|
|
||||||
let scale = height / movie_height;
|
|
||||||
let width = movie_width * scale;
|
|
||||||
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
|
||||||
}
|
|
||||||
(Some(width), Some(height)) => {
|
|
||||||
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let window_size = Size::clamp(
|
|
||||||
window_size,
|
|
||||||
self.min_window_size.into(),
|
|
||||||
self.max_window_size.into(),
|
|
||||||
self.window.scale_factor(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.window.set_inner_size(window_size);
|
|
||||||
self.window.set_fullscreen(if self.opt.fullscreen {
|
|
||||||
Some(Fullscreen::Borderless(None))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
});
|
|
||||||
self.window.set_visible(true);
|
|
||||||
|
|
||||||
let viewport_size = self.window.inner_size();
|
|
||||||
|
|
||||||
// On X11 (and possibly other platforms), the window size is not updated immediately.
|
|
||||||
// Wait for the window to be resized to the requested size before we start running
|
|
||||||
// the SWF (which can observe the viewport size in "noScale" mode)
|
|
||||||
if window_size != viewport_size.into() {
|
|
||||||
loaded = LoadingState::WaitingForResize;
|
|
||||||
} else {
|
|
||||||
loaded = LoadingState::Loaded;
|
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
winit::event::Event::UserEvent(RuffleEvent::TaskPoll) => self
|
||||||
|
.executor
|
||||||
|
.lock()
|
||||||
|
.expect("active executor reference")
|
||||||
|
.poll_all(),
|
||||||
|
winit::event::Event::UserEvent(RuffleEvent::OnMetadata(swf_header)) => {
|
||||||
|
let movie_width = swf_header.stage_size().width().to_pixels();
|
||||||
|
let movie_height = swf_header.stage_size().height().to_pixels();
|
||||||
|
|
||||||
let viewport_scale_factor = self.window.scale_factor();
|
let window_size: Size = match (self.opt.width, self.opt.height) {
|
||||||
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
(None, None) => LogicalSize::new(movie_width, movie_height).into(),
|
||||||
player_lock.set_viewport_dimensions(ViewportDimensions {
|
(Some(width), None) => {
|
||||||
width: viewport_size.width,
|
let scale = width / movie_width;
|
||||||
height: viewport_size.height,
|
let height = movie_height * scale;
|
||||||
scale_factor: viewport_scale_factor,
|
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
||||||
});
|
}
|
||||||
|
(None, Some(height)) => {
|
||||||
|
let scale = height / movie_height;
|
||||||
|
let width = movie_width * scale;
|
||||||
|
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
||||||
|
}
|
||||||
|
(Some(width), Some(height)) => {
|
||||||
|
PhysicalSize::new(width.max(1.0), height.max(1.0)).into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let window_size = Size::clamp(
|
||||||
|
window_size,
|
||||||
|
self.min_window_size.into(),
|
||||||
|
self.max_window_size.into(),
|
||||||
|
self.window.scale_factor(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.window.set_inner_size(window_size);
|
||||||
|
self.window.set_fullscreen(if self.opt.fullscreen {
|
||||||
|
Some(Fullscreen::Borderless(None))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
});
|
||||||
|
self.window.set_visible(true);
|
||||||
|
|
||||||
|
let viewport_size = self.window.inner_size();
|
||||||
|
|
||||||
|
// On X11 (and possibly other platforms), the window size is not updated immediately.
|
||||||
|
// Wait for the window to be resized to the requested size before we start running
|
||||||
|
// the SWF (which can observe the viewport size in "noScale" mode)
|
||||||
|
if window_size != viewport_size.into() {
|
||||||
|
loaded = LoadingState::WaitingForResize;
|
||||||
|
} else {
|
||||||
|
loaded = LoadingState::Loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
winit::event::Event::UserEvent(RuffleEvent::ExitRequested) => {
|
let viewport_scale_factor = self.window.scale_factor();
|
||||||
*control_flow = ControlFlow::Exit;
|
let mut player_lock = self.player.lock().expect("Cannot reenter");
|
||||||
return;
|
player_lock.set_viewport_dimensions(ViewportDimensions {
|
||||||
}
|
width: viewport_size.width,
|
||||||
|
height: viewport_size.height,
|
||||||
_ => (),
|
scale_factor: viewport_scale_factor,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// After polling events, sleep the event loop until the next event or the next frame.
|
winit::event::Event::UserEvent(RuffleEvent::ExitRequested) => {
|
||||||
*control_flow = if matches!(loaded, LoadingState::Loaded) {
|
*control_flow = ControlFlow::Exit;
|
||||||
ControlFlow::WaitUntil(next_frame_time)
|
return;
|
||||||
} else {
|
}
|
||||||
ControlFlow::Wait
|
|
||||||
};
|
_ => (),
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// After polling events, sleep the event loop until the next event or the next frame.
|
||||||
|
*control_flow = if matches!(loaded, LoadingState::Loaded) {
|
||||||
|
ControlFlow::WaitUntil(next_frame_time)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Wait
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue