Simplify event loop start-up

Move the layout constraint tracker into the window where we can apply
the constraints right before drawing, instead of doing that from within
the event loop. This allows to remove the component parameter from the
run function.
This commit is contained in:
Simon Hausmann 2020-11-12 11:14:04 +01:00
parent f8e5982ab4
commit c258a907f0
8 changed files with 57 additions and 66 deletions

View file

@ -84,9 +84,7 @@ public:
template<typename Component>
void run(const Component *c) const
{
auto self_rc = c->self_weak.lock().value();
sixtyfps_component_window_run(&inner,
reinterpret_cast<cbindgen_private::ComponentRc *>(&self_rc));
sixtyfps_component_window_run(&inner);
}
float scale_factor() const { return sixtyfps_component_window_get_scale_factor(&inner); }

View file

@ -329,7 +329,7 @@ declare_types! {
let component = cx.borrow(&mut this, |x| x.0.clone());
let component = component.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
run_scoped(&mut cx,this.downcast().unwrap(), || {
component.window().run(&vtable::VRc::into_dyn(component));
component.window().run();
Ok(())
})?;
Ok(JsUndefined::new().as_value(&mut cx))

View file

@ -127,6 +127,6 @@ impl WrappedCompiledComp {
#[wasm_bindgen]
pub fn run(&self, canvas_id: String) {
let component = self.0.clone().create(canvas_id);
component.window().run(&vtable::VRc::into_dyn(component));
component.window().run();
}
}

View file

@ -584,8 +584,7 @@ fn generate_component(
}
impl sixtyfps::Component for #component_id {
fn run(self: ::core::pin::Pin<&Self>) {
use sixtyfps::re_exports::*;
self.as_ref().window.run(&VRc::into_dyn(self.as_ref().self_weak.get().unwrap().upgrade().unwrap()));
self.as_ref().window.run();
}
}
))

View file

@ -22,10 +22,7 @@ use std::{
};
use vtable::*;
use crate::{
input::{KeyEvent, MouseEventType},
properties::PropertyTracker,
};
use crate::input::{KeyEvent, MouseEventType};
#[cfg(not(target_arch = "wasm32"))]
use winit::platform::desktop::EventLoopExtDesktop;
@ -91,8 +88,6 @@ pub trait GenericWindow {
fn set_height(&self, height: f32);
/// Returns the geometry of the window
fn get_geometry(&self) -> crate::graphics::Rect;
/// apply the constraints
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo);
/// This function is called by the generated code when a component and therefore its tree of items are destroyed. The
/// implementation typically uses this to free the underlying graphics resources cached via [`crate::graphics::RenderingCache`].
@ -134,12 +129,12 @@ impl ComponentWindow {
Self(window_impl)
}
/// Spins an event loop and renders the items of the provided component in this window.
pub fn run(&self, component: &ComponentRc) {
pub fn run(&self) {
let event_loop = crate::eventloop::EventLoop::new();
self.0.clone().map_window(&event_loop);
event_loop.run(ComponentRc::borrow_pin(component));
event_loop.run();
self.0.clone().unmap_window();
}
@ -242,10 +237,9 @@ impl EventLoop {
/// Runs the event loop and renders the items in the provided `component` in its
/// own window.
#[allow(unused_mut)] // mut need changes for wasm
pub fn run(mut self, component: core::pin::Pin<crate::component::ComponentRef>) {
pub fn run(mut self) {
use winit::event::Event;
use winit::event_loop::{ControlFlow, EventLoopWindowTarget};
let layout_listener = Rc::pin(PropertyTracker::default());
let mut cursor_pos = winit::dpi::PhysicalPosition::new(0., 0.);
let mut pressed = false;
@ -265,14 +259,6 @@ impl EventLoop {
if let Some(Some(window)) =
windows.borrow().get(&id).map(|weakref| weakref.upgrade())
{
if layout_listener.as_ref().is_dirty() {
layout_listener.as_ref().evaluate(|| {
window.apply_geometry_constraint(
component.as_ref().layout_info(),
);
component.as_ref().apply_layout(window.get_geometry())
})
}
window.draw();
}
});
@ -569,12 +555,9 @@ pub mod ffi {
/// Spins an event loop and renders the items of the provided component in this window.
#[no_mangle]
pub unsafe extern "C" fn sixtyfps_component_window_run(
handle: *const ComponentWindowOpaque,
component: &ComponentRc,
) {
pub unsafe extern "C" fn sixtyfps_component_window_run(handle: *const ComponentWindowOpaque) {
let window = &*(handle as *const ComponentWindow);
window.run(component);
window.run();
}
/// Returns the window scale factor.

View file

@ -23,7 +23,7 @@ extern crate alloc;
use crate::component::{ComponentRc, ComponentWeak};
use crate::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType};
use crate::items::ItemRef;
use crate::properties::{InterpolatedPropertyValue, Property};
use crate::properties::{InterpolatedPropertyValue, Property, PropertyTracker};
#[cfg(feature = "rtti")]
use crate::rtti::{BuiltinItem, FieldInfo, PropertyInfo, ValueType};
use crate::SharedArray;
@ -522,6 +522,7 @@ pub struct GraphicsWindow<Backend: GraphicsBackend + 'static> {
cursor_blinker: std::cell::RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
keyboard_modifiers: std::cell::Cell<KeyboardModifiers>,
component: std::cell::RefCell<ComponentWeak>,
layout_listener: Pin<Rc<PropertyTracker>>,
}
impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
@ -542,6 +543,7 @@ impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
cursor_blinker: Default::default(),
keyboard_modifiers: Default::default(),
component: Default::default(),
layout_listener: Rc::pin(Default::default()),
})
}
@ -549,6 +551,39 @@ impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
pub fn id(&self) -> Option<winit::window::WindowId> {
Some(self.map_state.borrow().as_mapped().backend.borrow().window().id())
}
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo) {
match &*self.map_state.borrow() {
GraphicsWindowBackendState::Unmapped => {}
GraphicsWindowBackendState::Mapped(window) => {
if constraints != window.constraints.get() {
let min_width = constraints.min_width.min(constraints.max_width);
let min_height = constraints.min_height.min(constraints.max_height);
let max_width = constraints.max_width.max(constraints.min_width);
let max_height = constraints.max_height.max(constraints.min_height);
window.backend.borrow().window().set_min_inner_size(
if min_width > 0. || min_height > 0. {
Some(winit::dpi::PhysicalSize::new(min_width, min_height))
} else {
None
},
);
window.backend.borrow().window().set_max_inner_size(
if max_width < f32::MAX || max_height < f32::MAX {
Some(winit::dpi::PhysicalSize::new(
max_width.min(65535.),
max_height.min(65535.),
))
} else {
None
},
);
window.constraints.set(constraints);
}
}
}
}
}
impl<Backend: GraphicsBackend> Drop for GraphicsWindow<Backend> {
@ -574,6 +609,15 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
let component = self.component.borrow().upgrade().unwrap();
let component = ComponentRc::borrow_pin(&component);
{
if self.layout_listener.as_ref().is_dirty() {
self.layout_listener.as_ref().evaluate(|| {
self.apply_geometry_constraint(component.as_ref().layout_info());
component.as_ref().apply_layout(self.get_geometry())
})
}
}
{
let map_state = self.map_state.borrow();
let window = map_state.as_mapped();
@ -776,39 +820,6 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
)
}
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo) {
match &*self.map_state.borrow() {
GraphicsWindowBackendState::Unmapped => {}
GraphicsWindowBackendState::Mapped(window) => {
if constraints != window.constraints.get() {
let min_width = constraints.min_width.min(constraints.max_width);
let min_height = constraints.min_height.min(constraints.max_height);
let max_width = constraints.max_width.max(constraints.min_width);
let max_height = constraints.max_height.max(constraints.min_height);
window.backend.borrow().window().set_min_inner_size(
if min_width > 0. || min_height > 0. {
Some(winit::dpi::PhysicalSize::new(min_width, min_height))
} else {
None
},
);
window.backend.borrow().window().set_max_inner_size(
if max_width < f32::MAX || max_height < f32::MAX {
Some(winit::dpi::PhysicalSize::new(
max_width.min(65535.),
max_height.min(65535.),
))
} else {
None
},
);
window.constraints.set(constraints);
}
}
}
}
fn free_graphics_resources(
self: Rc<Self>,
component: core::pin::Pin<crate::component::ComponentRef>,

View file

@ -72,7 +72,7 @@ impl<'id> ComponentBox<'id> {
pub fn run(self) {
let rc_box = vtable::VRc::new(ErasedComponentBox::from(self));
let window = rc_box.0.window();
window.run(&vtable::VRc::into_dyn(rc_box));
window.run();
}
}

View file

@ -44,6 +44,6 @@ fn main() -> std::io::Result<()> {
};
let component = c.create();
component.window().run(&vtable::VRc::into_dyn(component));
component.window().run();
Ok(())
}