Skip to content

Commit

Permalink
Merge pull request #317 from HenrySwanson/master
Browse files Browse the repository at this point in the history
Remove `RenderLoopClosure` trait
  • Loading branch information
donkeyteethUX authored Feb 1, 2023
2 parents 87a668f + 9662bd1 commit 2e3f29c
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 41 deletions.
11 changes: 2 additions & 9 deletions src/window/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl Canvas {
}

/// Run the platform-specific render loop.
pub fn render_loop(data: impl RenderLoopClosure) {
pub fn render_loop(data: impl FnMut(f64) -> bool + 'static) {
CanvasImpl::render_loop(data)
}

Expand Down Expand Up @@ -148,13 +148,6 @@ impl Canvas {
}
}

/// Note: the closure must have static lifetime because of the constraints imposed by wasm-bindgen:
/// https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/closure/struct.Closure.html
pub trait RenderLoopClosure: 'static {
/// Call the closure
fn call(&mut self, x: f64) -> bool;
}

pub(crate) trait AbstractCanvas {
fn open(
title: &str,
Expand All @@ -164,7 +157,7 @@ pub(crate) trait AbstractCanvas {
window_setup: Option<CanvasSetup>,
out_events: Sender<WindowEvent>,
) -> Self;
fn render_loop(data: impl RenderLoopClosure);
fn render_loop(data: impl FnMut(f64) -> bool + 'static);
fn poll_events(&mut self);
fn swap_buffers(&mut self);
fn size(&self) -> (u32, u32);
Expand Down
6 changes: 3 additions & 3 deletions src/window/gl_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::mpsc::Sender;

use crate::context::Context;
use crate::event::{Action, Key, Modifiers, MouseButton, TouchAction, WindowEvent};
use crate::window::canvas::{CanvasSetup, NumSamples, RenderLoopClosure};
use crate::window::canvas::{CanvasSetup, NumSamples};
use crate::window::AbstractCanvas;
use glutin::{
self,
Expand Down Expand Up @@ -97,9 +97,9 @@ impl AbstractCanvas for GLCanvas {
}
}

fn render_loop(mut callback: impl RenderLoopClosure) {
fn render_loop(mut callback: impl FnMut(f64) -> bool + 'static) {
loop {
if !callback.call(0.0) {
if !callback(0.0) {
break;
} // XXX: timestamp
}
Expand Down
2 changes: 1 addition & 1 deletion src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod window;
mod window_cache;

pub(crate) use canvas::AbstractCanvas;
pub use canvas::{Canvas, CanvasSetup, NumSamples, RenderLoopClosure};
pub use canvas::{Canvas, CanvasSetup, NumSamples};
#[cfg(not(target_arch = "wasm32"))]
pub use gl_canvas::GLCanvas;
pub use state::State;
Expand Down
6 changes: 3 additions & 3 deletions src/window/webgl_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;

use crate::context::Context;
use crate::event::{Action, Key, Modifiers, MouseButton, TouchAction, WindowEvent};
use crate::window::{AbstractCanvas, CanvasSetup, RenderLoopClosure};
use crate::window::{AbstractCanvas, CanvasSetup};
use image::{GenericImage, Pixel};
use wasm_bindgen::closure::Closure;
use wasm_bindgen::{JsCast, JsValue};
Expand Down Expand Up @@ -424,13 +424,13 @@ impl AbstractCanvas for WebGLCanvas {
}
}

fn render_loop(mut callback: impl RenderLoopClosure) {
fn render_loop(mut callback: impl FnMut(f64) -> bool + 'static) {
// See https://rustwasm.github.io/docs/wasm-bindgen/examples/request-animation-frame.html
if let Some(window) = web_sys::window() {
let f = Rc::new(RefCell::new(None));
let g: Rc<RefCell<Option<Closure<_>>>> = f.clone();
*g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
if callback.call(0.0) {
if callback(0.0) {
let _ = window.request_animation_frame(
f.borrow().as_ref().unwrap().as_ref().unchecked_ref(),
);
Expand Down
46 changes: 21 additions & 25 deletions src/window/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::resource::{
use crate::scene::{PlanarSceneNode, SceneNode};
use crate::text::{Font, TextRenderer};
use crate::window::canvas::CanvasSetup;
use crate::window::{Canvas, RenderLoopClosure, State};
use crate::window::{Canvas, State};
use image::imageops;
use image::{GenericImage, Pixel};
use image::{ImageBuffer, Rgb};
Expand Down Expand Up @@ -59,26 +59,6 @@ impl ConrodContext {
}
}

// Note: this struct, and the RenderLoopClosure trait it implements, were created solely to control
// the drop order of its members.
// Since the Window contains the OpenGL context, it must be dropped _after_ the state, and there's
// no way to control that in a plain old closure.
struct RenderLoopClosureImpl<S: State, F: Fn(f64, &mut Window, &mut S) -> bool> {
pub state: S,
pub window: Window,
pub closure: F,
}

impl<S, F> RenderLoopClosure for RenderLoopClosureImpl<S, F>
where
S: State,
F: Fn(f64, &mut Window, &mut S) -> bool + 'static,
{
fn call(&mut self, x: f64) -> bool {
(self.closure)(x, &mut self.window, &mut self.state)
}
}

/// Structure representing a window and a 3D scene.
///
/// This is the main interface with the 3d engine.
Expand Down Expand Up @@ -943,11 +923,27 @@ impl Window {

/// Runs the render and event loop until the window is closed.
pub fn render_loop<S: State>(self, state: S) {
Canvas::render_loop(RenderLoopClosureImpl {
window: self,
// We have to be really careful here about drop order.
//
// The State may contain various OpenGL objects (for example, shaders),
// that, when dropped, make calls to the OpenGL context.
// Since the Window contains the OpenGL context, we must not drop it
// until we are done dropping the state.
//
// Since we can't directly control the drop order of fields in a closure,
// we instead put the relevant objects into a struct, for which the
// drop order _is_ controllable (top-to-bottom).
struct DropControl<S> {
state: S,
window: Window,
}

let mut dc = DropControl {
state,
closure: |_, window, state| window.do_render_with_state(state),
});
window: self,
};

Canvas::render_loop(move |_| dc.window.do_render_with_state(&mut dc.state));
}

/// Render one frame using the specified state.
Expand Down

0 comments on commit 2e3f29c

Please sign in to comment.