Skip to content

Commit

Permalink
Split up ComponentWindow::run() into show(), hide() and sixtyfps::run…
Browse files Browse the repository at this point in the history
…_event_loop()

This allows creating multiple windows for example, and it will allow for
showing windows in those tests that require a mapped window.

As a bonus, the run() function on generated components is not consuming
anymore.
  • Loading branch information
tronical committed Jan 19, 2021
1 parent 2b7a1ee commit 5f265ff
Show file tree
Hide file tree
Showing 23 changed files with 186 additions and 32 deletions.
6 changes: 5 additions & 1 deletion api/sixtyfps-cpp/docs/generated_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ file. This header file will contain a `class` with the same name as the componen
This class will have the following public member functions:

- A default constructor and a destructor.
- A `run` function which will show the component and starts the event loop
- A `show` function, which will show the component on the screen. Note that in order to render
and react to user input, it's still necessary to spin the event loop, by calling `sixtyfps::run_event_loop()`
or using the convenience `fun` function in this class.
- A `hide` function, which de-registers the component from the windowing system.
- A `run` convenience function, which will show the component and starts the event loop.
- for each properties:
* A getter `get_<property_name>` returning the property type.
* A setter `set_<property_name>` taking the new value of the property by const reference
Expand Down
8 changes: 7 additions & 1 deletion api/sixtyfps-cpp/include/sixtyfps.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ class ComponentWindow
ComponentWindow(ComponentWindow &&) = delete;
ComponentWindow &operator=(const ComponentWindow &) = delete;

void run() const { sixtyfps_component_window_run(&inner); }
void show() const { sixtyfps_component_window_show(&inner); }
void hide() const { sixtyfps_component_window_hide(&inner); }

float scale_factor() const { return sixtyfps_component_window_get_scale_factor(&inner); }
void set_scale_factor(float value) const
Expand Down Expand Up @@ -624,4 +625,9 @@ struct VersionCheckHelper
};
}

void run_event_loop()
{
cbindgen_private::sixtyfps_run_event_loop();
}

} // namespace sixtyfps
2 changes: 1 addition & 1 deletion api/sixtyfps-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Combining these two steps leads us to the obligator "Hello World" example:
require("sixtyfps");
let ui = require("../ui/main.60");
let main = new ui.Main();
main.show();
main.run();
```

See [/examples/printerdemo/node](/examples/printerdemo/node) for a full example.
Expand Down
8 changes: 8 additions & 0 deletions api/sixtyfps-node/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ class Component {
this.comp = comp;
}

run() {
this.comp.run();
}

show() {
this.comp.show();
}

hide() {
this.comp.hide();
}

send_mouse_click(x: number, y: number) {
this.comp.send_mouse_click(x, y)
}
Expand Down
24 changes: 23 additions & 1 deletion api/sixtyfps-node/native/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,34 @@ declare_types! {
init(_) {
Ok(WrappedComponentRc(None))
}
method run(mut cx) {
let mut this = cx.this();
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().show();
sixtyfps_interpreter::run_event_loop();
component.window().hide();
Ok(())
})?;
Ok(JsUndefined::new().as_value(&mut cx))
}
method show(mut cx) {
let mut this = cx.this();
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();
component.window().show();
Ok(())
})?;
Ok(JsUndefined::new().as_value(&mut cx))
}
method hide(mut cx) {
let mut this = cx.this();
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().hide();
Ok(())
})?;
Ok(JsUndefined::new().as_value(&mut cx))
Expand Down
17 changes: 17 additions & 0 deletions api/sixtyfps-rs/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ pub mod generated_code {
pub fn new() -> Self {
unimplemented!()
}
/// Marks the window of this component to be shown on the screen. This registers
/// the window with the windowing system. In order to react to events from the windowing system,
/// such as draw requests or mouse/touch input, it is still necessary to spin the event loop,
/// using [`crate::run_event_loop`].
pub fn show(&self) {
unimplemented!()
}
/// Marks the window of this component to be hidden on the screen. This de-registers
/// the window from the windowing system and it will not receive any further events.
pub fn hide(&self) {
unimplemented!()
}
/// This is a convenience function that first calls [`Self::show`], followed by [`crate::run_event_loop()`]
/// and [`Self::hide`].
pub fn run(&self) {
unimplemented!()
}
/// A getter is generated for each property declared at the root of the component.
/// In this case, this is the getter that returns the value of the `counter`
/// property declared in the `.60` design markup.
Expand Down
17 changes: 16 additions & 1 deletion api/sixtyfps-rs/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn main() {
### Generated components
As of now, only the last component of a .60 source is generated. It is planed to generate all exported components.
As of now, only the last component of a .60 source is generated. It is planned to generate all exported components.
The component is generated and re-exported at the location of the [`include_modules!`] or [`sixtyfps!`] macro.
it consist of a struct of the same name of the component.
Expand All @@ -99,6 +99,10 @@ This documentation contains a documented generated component: [`docs::generated_
The following associated function are added to the component:
- [`fn new() -> Self`](docs::generated_code::SampleComponent::new): to instantiate the component.
- [`fn show(&self)`]()docs::generated_code::SampleComponent::show): to show the window of the component.
- [`fn hide(&self)`]()docs::generated_code::SampleComponent::hide): to hide the window of the component.
- [`fn run(&self)`]()docs::generated_code::SampleComponent::run): a convenience function that first calls `show()`,
followed by spinning the event loop, and `hide()` when returning from the event loop.
For each top-level property
- A setter [`fn set_<property_name>(&self, value: <PropertyType>)`](docs::generated_code::SampleComponent::set_counter)
Expand All @@ -108,6 +112,10 @@ For each top-level callback
- [`fn emit_<callback_name>(&self)`](docs::generated_code::SampleComponent::emit_hello): to emit the callback
- [`fn on_<callback_name>(&self, callback: impl Fn(<CallbackArgs>) + 'static)`](docs::generated_code::SampleComponent::on_hello): to set the callback handler.
After instantiating the component you can call just [`fn run(&self)`] on it, in order to show it and spin the event loop to
render and react to input events. If you want to show multiple components simultaneously, then you can also call just
`show()` first. When you're ready to enter the event loop, just call [`run_event_loop()`].
### Type Mappings
The types used for properties in `.60` design markup each translate to specific types in Rust.
Expand Down Expand Up @@ -219,6 +227,13 @@ pub fn create_window() -> re_exports::ComponentWindow {
sixtyfps_rendering_backend_default::backend().create_window()
}

/// Enters the main event loop. This is necessary in order to receive
/// events from the windowing system in order to render to the screen
/// and react to user input.
pub fn run_event_loop() {
sixtyfps_rendering_backend_default::backend().run_event_loop();
}

/// This trait describes the conversion of a strongly referenced SixtyFPS component,
/// held by a [vtable::VRc] into a weak reference.
pub trait IntoWeak {
Expand Down
3 changes: 2 additions & 1 deletion api/sixtyfps-wasm-interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl WrappedCompiledComp {
#[wasm_bindgen]
pub fn run(&self, canvas_id: String) {
let component = self.0.clone().create(canvas_id);
component.window().run();
component.window().show();
sixtyfps_interpreter::run_event_loop();
}
}
2 changes: 1 addition & 1 deletion examples/memory/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ window.check_if_pair_solved.setHandler(function () {
}
})

window.comp.show();
window.comp.run();

2 changes: 1 addition & 1 deletion examples/printerdemo/node/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ window.fax_send.setHandler(function () {
window.fax_number = "";
})

window.show();
window.run();

27 changes: 26 additions & 1 deletion sixtyfps_compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,14 +906,39 @@ fn generate_component(
}),
));

component_struct.members.push((
Access::Public,
Declaration::Function(Function {
name: "show".into(),
signature: "() const".into(),
statements: Some(vec![
"window.set_component(**self_weak.lock());".into(),
"window.show();".into(),
]),
..Default::default()
}),
));

component_struct.members.push((
Access::Public,
Declaration::Function(Function {
name: "hide".into(),
signature: "() const".into(),
statements: Some(vec!["window.hide();".into()]),
..Default::default()
}),
));

component_struct.members.push((
Access::Public,
Declaration::Function(Function {
name: "run".into(),
signature: "() const".into(),
statements: Some(vec![
"window.set_component(**self_weak.lock());".into(),
"window.run();".into(),
"show();".into(),
"sixtyfps::run_event_loop();".into(),
"hide();".into(),
]),
..Default::default()
}),
Expand Down
14 changes: 12 additions & 2 deletions sixtyfps_compiler/generator/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,18 @@ fn generate_component(

let run_fun = if component.parent_element.upgrade().is_none() {
Some(quote!(
pub fn run(self) {
vtable::VRc::as_pin_ref(&self.0).window.run();
pub fn run(&self) {
self.show();
sixtyfps::run_event_loop();
self.hide();
}

pub fn show(&self) {
vtable::VRc::as_pin_ref(&self.0).window.show();
}

pub fn hide(&self) {
vtable::VRc::as_pin_ref(&self.0).window.hide();
}
))
} else {
Expand Down
3 changes: 3 additions & 0 deletions sixtyfps_runtime/corelib/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub trait Backend: Send + Sync {
/// FIXME: should return a Box<dyn PlatformWindow>
fn create_window(&'static self) -> ComponentWindow;

/// Spins an event loop and renders the items of the provided component in this window.
fn run_event_loop(&'static self);

/// This function can be used to register a custom TrueType font with SixtyFPS,
/// for use with the `font-family` property. The provided slice must be a valid TrueType
/// font.
Expand Down
31 changes: 23 additions & 8 deletions sixtyfps_runtime/corelib/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ use std::rc::Rc;
/// require in order to implement functionality such as device-independent pixels,
/// window resizing and other typicaly windowing system related tasks.
pub trait PlatformWindow {
/// Spins an event loop and renders the items of the provided component in this window.
/// FIXME: replace by a show() function, and move run() in the backend
fn run(self: Rc<Self>);
/// Registers the window with the windowing system.
fn show(self: Rc<Self>);
/// Deregisters the window from the windowing system.
fn hide(self: Rc<Self>);
/// Issue a request to the windowing system to re-render the contents of the window. This is typically an asynchronous
/// request.
fn request_redraw(&self);
Expand Down Expand Up @@ -207,9 +208,16 @@ impl ComponentWindow {
pub fn new(window_impl: std::rc::Rc<Window>) -> Self {
Self(window_impl)
}
/// Spins an event loop and renders the items of the provided component in this window.
pub fn run(&self) {
self.0.platform_window.clone().run();

/// Registers the window with the windowing system, in order to render the component's items and react
/// to input events once the event loop spins.
pub fn show(&self) {
self.0.platform_window.clone().show();
}

/// De-registers the window with the windowing system.
pub fn hide(&self) {
self.0.platform_window.clone().hide();
}

/// Returns the scale factor set on the window.
Expand Down Expand Up @@ -298,9 +306,16 @@ 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) {
pub unsafe extern "C" fn sixtyfps_component_window_show(handle: *const ComponentWindowOpaque) {
let window = &*(handle as *const ComponentWindow);
window.show();
}

/// 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_hide(handle: *const ComponentWindowOpaque) {
let window = &*(handle as *const ComponentWindow);
window.run();
window.hide();
}

/// Returns the window scale factor.
Expand Down
6 changes: 0 additions & 6 deletions sixtyfps_runtime/interpreter/dynamic_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ impl<'id> ComponentBox<'id> {
.unwrap())
.clone()
}

pub fn run(self) {
let rc_box = vtable::VRc::new(ErasedComponentBox::from(self));
let window = rc_box.0.window();
window.run();
}
}

impl<'id> Drop for ComponentBox<'id> {
Expand Down
4 changes: 4 additions & 0 deletions sixtyfps_runtime/interpreter/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,7 @@ pub async fn load(
})
.await
}

pub fn run_event_loop() {
sixtyfps_rendering_backend_default::backend().run_event_loop();
}
5 changes: 5 additions & 0 deletions sixtyfps_runtime/rendering_backends/default/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,9 @@ pub mod ffi {
);
core::ptr::write(out as *mut ComponentWindow, crate::backend().create_window());
}

#[no_mangle]
pub unsafe extern "C" fn sixtyfps_run_event_loop() {
crate::backend().run_event_loop();
}
}
8 changes: 5 additions & 3 deletions sixtyfps_runtime/rendering_backends/gl/graphics_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,11 @@ impl PlatformWindow for GraphicsWindow {
*self.active_popup.borrow_mut() = None;
}

fn run(self: Rc<Self>) {
self.clone().map_window();
crate::eventloop::run();
fn show(self: Rc<Self>) {
self.map_window();
}

fn hide(self: Rc<Self>) {
self.unmap_window();
}

Expand Down
4 changes: 4 additions & 0 deletions sixtyfps_runtime/rendering_backends/gl/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,10 @@ impl sixtyfps_corelib::backend::Backend for Backend {
ComponentWindow(window)
}

fn run_event_loop(&'static self) {
crate::eventloop::run();
}

fn register_application_font_from_memory(
&'static self,
data: &'static [u8],
Expand Down
10 changes: 10 additions & 0 deletions sixtyfps_runtime/rendering_backends/qt/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ impl sixtyfps_corelib::backend::Backend for Backend {
}
}

fn run_event_loop(&'static self) {
#[cfg(not(no_qt))]
{
use cpp::cpp;
cpp! {unsafe [] {
qApp->exec();
} }
};
}

fn register_application_font_from_memory(
&'static self,
_data: &'static [u8],
Expand Down
Loading

0 comments on commit 5f265ff

Please sign in to comment.