Merge pull request #540 from Herschel/event-loop-clean
core: Clean up core loop
This commit is contained in:
commit
9c503cecc9
|
@ -103,6 +103,7 @@ pub struct Player {
|
||||||
swf: Arc<SwfMovie>,
|
swf: Arc<SwfMovie>,
|
||||||
|
|
||||||
is_playing: bool,
|
is_playing: bool,
|
||||||
|
needs_render: bool,
|
||||||
|
|
||||||
audio: Audio,
|
audio: Audio,
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
@ -168,6 +169,7 @@ impl Player {
|
||||||
swf: movie.clone(),
|
swf: movie.clone(),
|
||||||
|
|
||||||
is_playing: false,
|
is_playing: false,
|
||||||
|
needs_render: true,
|
||||||
|
|
||||||
background_color: Color {
|
background_color: Color {
|
||||||
r: 255,
|
r: 255,
|
||||||
|
@ -264,8 +266,6 @@ impl Player {
|
||||||
self.global_time += dt as u64;
|
self.global_time += dt as u64;
|
||||||
let frame_time = 1000.0 / self.frame_rate;
|
let frame_time = 1000.0 / self.frame_rate;
|
||||||
|
|
||||||
let needs_render = self.frame_accumulator >= frame_time;
|
|
||||||
|
|
||||||
const MAX_FRAMES_PER_TICK: u32 = 5; // Sanity cap on frame tick.
|
const MAX_FRAMES_PER_TICK: u32 = 5; // Sanity cap on frame tick.
|
||||||
let mut frame = 0;
|
let mut frame = 0;
|
||||||
while frame < MAX_FRAMES_PER_TICK && self.frame_accumulator >= frame_time {
|
while frame < MAX_FRAMES_PER_TICK && self.frame_accumulator >= frame_time {
|
||||||
|
@ -280,10 +280,6 @@ impl Player {
|
||||||
self.frame_accumulator = 0.0;
|
self.frame_accumulator = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if needs_render {
|
|
||||||
self.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.audio.tick();
|
self.audio.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,6 +310,10 @@ impl Player {
|
||||||
self.is_playing = v;
|
self.is_playing = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn needs_render(&self) -> bool {
|
||||||
|
self.needs_render
|
||||||
|
}
|
||||||
|
|
||||||
pub fn movie_width(&self) -> u32 {
|
pub fn movie_width(&self) -> u32 {
|
||||||
self.movie_width
|
self.movie_width
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_event(&mut self, event: PlayerEvent) {
|
pub fn handle_event(&mut self, event: PlayerEvent) {
|
||||||
let mut needs_render = false;
|
let mut needs_render = self.needs_render;
|
||||||
|
|
||||||
// Update mouse position from mouse events.
|
// Update mouse position from mouse events.
|
||||||
if let PlayerEvent::MouseMove { x, y }
|
if let PlayerEvent::MouseMove { x, y }
|
||||||
|
@ -442,10 +442,7 @@ impl Player {
|
||||||
Self::run_actions(avm, context);
|
Self::run_actions(avm, context);
|
||||||
});
|
});
|
||||||
self.is_mouse_down = is_mouse_down;
|
self.is_mouse_down = is_mouse_down;
|
||||||
if needs_render {
|
self.needs_render = needs_render;
|
||||||
// Update display after mouse events.
|
|
||||||
self.render();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update dragged object, if any.
|
/// Update dragged object, if any.
|
||||||
|
@ -568,7 +565,8 @@ impl Player {
|
||||||
for mut level in levels {
|
for mut level in levels {
|
||||||
level.run_frame(avm, update_context);
|
level.run_frame(avm, update_context);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
self.needs_render = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
|
@ -608,6 +606,7 @@ impl Player {
|
||||||
|
|
||||||
self.renderer.draw_letterbox(self.letterbox);
|
self.renderer.draw_letterbox(self.letterbox);
|
||||||
self.renderer.end_frame();
|
self.renderer.end_frame();
|
||||||
|
self.needs_render = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio(&self) -> &Audio {
|
pub fn audio(&self) -> &Audio {
|
||||||
|
|
|
@ -98,12 +98,31 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let mut mouse_pos = PhysicalPosition::new(0.0, 0.0);
|
let mut mouse_pos = PhysicalPosition::new(0.0, 0.0);
|
||||||
let mut time = Instant::now();
|
let mut time = Instant::now();
|
||||||
|
let mut next_frame_time = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
// Poll UI events
|
// Poll UI events
|
||||||
event_loop.run(move |event, _window_target, control_flow| {
|
event_loop.run(move |event, _window_target, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
|
||||||
match event {
|
match event {
|
||||||
winit::event::Event::LoopDestroyed => return,
|
winit::event::Event::LoopDestroyed => return,
|
||||||
|
|
||||||
|
// Core loop
|
||||||
|
winit::event::Event::MainEventsCleared => {
|
||||||
|
let new_time = Instant::now();
|
||||||
|
let dt = new_time.duration_since(time).as_micros();
|
||||||
|
if dt > 0 {
|
||||||
|
time = new_time;
|
||||||
|
let mut player_lock = player.lock().unwrap();
|
||||||
|
player_lock.tick(dt as f64 / 1000.0);
|
||||||
|
next_frame_time = new_time + player_lock.time_til_next_frame();
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render
|
||||||
|
winit::event::Event::RedrawRequested(_) => player.lock().unwrap().render(),
|
||||||
|
|
||||||
winit::event::Event::WindowEvent { event, .. } => match event {
|
winit::event::Event::WindowEvent { event, .. } => match event {
|
||||||
WindowEvent::Resized(size) => {
|
WindowEvent::Resized(size) => {
|
||||||
let mut player_lock = player.lock().unwrap();
|
let mut player_lock = player.lock().unwrap();
|
||||||
|
@ -111,6 +130,7 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
player_lock
|
player_lock
|
||||||
.renderer_mut()
|
.renderer_mut()
|
||||||
.set_viewport_dimensions(size.width, size.height);
|
.set_viewport_dimensions(size.width, size.height);
|
||||||
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
WindowEvent::CursorMoved { position, .. } => {
|
||||||
let mut player_lock = player.lock().unwrap();
|
let mut player_lock = player.lock().unwrap();
|
||||||
|
@ -120,6 +140,9 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
y: position.y,
|
y: position.y,
|
||||||
};
|
};
|
||||||
player_lock.handle_event(event);
|
player_lock.handle_event(event);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::MouseInput {
|
WindowEvent::MouseInput {
|
||||||
button: MouseButton::Left,
|
button: MouseButton::Left,
|
||||||
|
@ -139,10 +162,16 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
player_lock.handle_event(event);
|
player_lock.handle_event(event);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::CursorLeft { .. } => {
|
WindowEvent::CursorLeft { .. } => {
|
||||||
let mut player_lock = player.lock().unwrap();
|
let mut player_lock = player.lock().unwrap();
|
||||||
player_lock.handle_event(ruffle_core::PlayerEvent::MouseLeft)
|
player_lock.handle_event(ruffle_core::PlayerEvent::MouseLeft);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
WindowEvent::KeyboardInput { .. } | WindowEvent::ReceivedCharacter(_) => {
|
WindowEvent::KeyboardInput { .. } | WindowEvent::ReceivedCharacter(_) => {
|
||||||
|
@ -154,6 +183,9 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.handle_event(event)
|
.handle_event(event)
|
||||||
{
|
{
|
||||||
player_lock.handle_event(event);
|
player_lock.handle_event(event);
|
||||||
|
if player_lock.needs_render() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -166,16 +198,8 @@ fn run_player(input_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// After polling events, sleep the event loop until the next event or the next frame.
|
// After polling events, sleep the event loop until the next event or the next frame.
|
||||||
if *control_flow == ControlFlow::Wait {
|
if *control_flow != ControlFlow::Exit {
|
||||||
let new_time = Instant::now();
|
*control_flow = ControlFlow::WaitUntil(next_frame_time);
|
||||||
let dt = new_time.duration_since(time).as_micros();
|
|
||||||
if dt > 0 {
|
|
||||||
time = new_time;
|
|
||||||
player.lock().unwrap().tick(dt as f64 / 1000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
*control_flow =
|
|
||||||
ControlFlow::WaitUntil(new_time + player.lock().unwrap().time_til_next_frame());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,7 +414,9 @@ impl Ruffle {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
instance.core.lock().unwrap().tick(dt);
|
let mut core_lock = instance.core.lock().unwrap();
|
||||||
|
core_lock.tick(dt);
|
||||||
|
let mut needs_render = core_lock.needs_render();
|
||||||
|
|
||||||
// Check for canvas resize.
|
// Check for canvas resize.
|
||||||
let canvas_width = instance.canvas.client_width();
|
let canvas_width = instance.canvas.client_width();
|
||||||
|
@ -439,16 +441,17 @@ impl Ruffle {
|
||||||
instance.canvas.set_width(viewport_width);
|
instance.canvas.set_width(viewport_width);
|
||||||
instance.canvas.set_height(viewport_height);
|
instance.canvas.set_height(viewport_height);
|
||||||
|
|
||||||
let mut core_lock = instance.core.lock().unwrap();
|
|
||||||
core_lock.set_viewport_dimensions(viewport_width, viewport_height);
|
core_lock.set_viewport_dimensions(viewport_width, viewport_height);
|
||||||
core_lock
|
core_lock
|
||||||
.renderer_mut()
|
.renderer_mut()
|
||||||
.set_viewport_dimensions(viewport_width, viewport_height);
|
.set_viewport_dimensions(viewport_width, viewport_height);
|
||||||
|
|
||||||
// Force a re-render if we resize.
|
// Force a re-render if we resize.
|
||||||
core_lock.render();
|
needs_render = true;
|
||||||
|
}
|
||||||
|
|
||||||
drop(core_lock);
|
if needs_render {
|
||||||
|
core_lock.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request next animation frame.
|
// Request next animation frame.
|
||||||
|
|
Loading…
Reference in New Issue