diff --git a/examples/benchmark.rs b/examples/benchmark.rs index 2346ff4..110860d 100644 --- a/examples/benchmark.rs +++ b/examples/benchmark.rs @@ -17,14 +17,7 @@ pub fn main() { let handle = thread::spawn(move || { let res = engine - .run(move |cx| { - rsx! { - for _ in (0..items) { - "Hello, world!" - } - } - .view(cx.clone()) - }) + .run(BenchmarkApp(items)) .expect("Failed to run engine"); tx.send((items, res)).expect("Failed to send result"); @@ -46,5 +39,18 @@ pub fn main() { for (items, bench) in results { println!("Results for {items} items:\n{bench}"); } - +} + +struct BenchmarkApp(pub usize); + +impl ComponentImpl for BenchmarkApp { + fn call(&self, cx: &Arc) -> View { + let items = self.0.clone(); + rsx! { + for _ in (0..items) { + "Hello, world!" + } + } + .view(cx.clone()) + } } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index eb1056f..9807544 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -4,12 +4,16 @@ use osui::prelude::*; pub fn main() { let engine = Console::new(); - engine.run(app).expect("Failed to run engine"); + engine.run(App).expect("Failed to run engine"); } -fn app(cx: &Arc) -> View { - rsx! { - "Hello, world!" +struct App; + +impl ComponentImpl for App { + fn call(&self, cx: &Arc) -> View { + rsx! { + "Hello, world!" + } + .view(cx.clone()) } - .view(cx.clone()) } diff --git a/examples/simple_benchmark.rs b/examples/simple_benchmark.rs index 811120e..ece76c0 100644 --- a/examples/simple_benchmark.rs +++ b/examples/simple_benchmark.rs @@ -4,7 +4,7 @@ use osui::prelude::*; pub fn main() { let engine = Benchmark::new(Console::new()); - let benchmark_result = engine.run(app).expect("Failed to run engine"); + let benchmark_result = engine.run(App).expect("Failed to run engine"); println!("Avg: {} μs", benchmark_result.average); println!("Min: {} μs", benchmark_result.min); println!("Max: {} μs", benchmark_result.max); @@ -12,9 +12,13 @@ pub fn main() { println!("Tot Render: {} μs", benchmark_result.total_render); } -fn app(cx: &Arc) -> View { - rsx! { - "Hello, world!" +struct App; + +impl ComponentImpl for App { + fn call(&self, cx: &Arc) -> View { + rsx! { + "Hello, world!" + } + .view(cx.clone()) } - .view(cx.clone()) } diff --git a/src/component.rs b/src/component.rs index 90c910a..9928804 100644 --- a/src/component.rs +++ b/src/component.rs @@ -11,9 +11,13 @@ use crate::{ View, ViewWrapper, }; -pub type Component = Arc) -> View + Send + Sync>; +pub type Component = Arc; pub type EventHandler = Arc, &dyn Any) + Send + Sync>>; +pub trait ComponentImpl: Send + Sync { + fn call(&self, cx: &Arc) -> View; +} + pub struct Scope { pub children: Mutex, Option)>>, executor: Arc, @@ -28,7 +32,7 @@ pub struct Context { } impl Context { - pub fn new) -> View + Send + Sync + 'static>( + pub fn new( component: F, executor: Arc, ) -> Arc { @@ -48,7 +52,7 @@ impl Context { move || { s.event_handlers.lock().unwrap().clear(); let c = s.component.lock().unwrap().clone(); - *s.view.lock().unwrap() = (c)(&s); + *s.view.lock().unwrap() = c.call(&s); } }); } @@ -62,7 +66,7 @@ impl Context { move || { s.event_handlers.lock().unwrap().clear(); let c = s.component.lock().unwrap().clone(); - *s.view.lock().unwrap() = (c)(&s); + *s.view.lock().unwrap() = c.call(&s); *done.lock().unwrap() = true; } }); @@ -194,7 +198,7 @@ impl Scope { }) } - pub fn child) -> View + Send + Sync + 'static>( + pub fn child( self: &Arc, child: F, view_wrapper: Option, @@ -207,10 +211,25 @@ impl Scope { } pub fn view(self: &Arc, view: View) { - let ctx = Context::new(move |_| view.clone(), self.executor.clone()); + let ctx = Context::new(view, self.executor.clone()); ctx.refresh(); self.children.lock().unwrap().push((ctx, None)); } } + +impl ComponentImpl for View { + fn call(&self, _: &Arc) -> View { + self.clone() + } +} + +impl ComponentImpl for F +where + F: Fn(&Arc) -> View + Send + Sync, +{ + fn call(&self, ctx: &Arc) -> View { + self(ctx) + } +} diff --git a/src/engine/benchmark.rs b/src/engine/benchmark.rs index 99a7722..a371bf5 100644 --- a/src/engine/benchmark.rs +++ b/src/engine/benchmark.rs @@ -2,7 +2,11 @@ use std::{io::stdout, sync::Arc, time::Instant}; use crossterm::{cursor::MoveTo, execute, terminal::Clear}; -use crate::{prelude::Context, render::Area, DrawContext, View}; +use crate::{ + prelude::{ComponentImpl, Context}, + render::Area, + DrawContext, View, +}; use super::Engine; @@ -24,10 +28,7 @@ impl Benchmark { } impl Engine for Benchmark { - fn run) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> crate::Result { + fn run(&self, component: F) -> crate::Result { let mut times: Vec = Vec::new(); let cx = self.init(component); @@ -59,10 +60,7 @@ impl Engine for Benchmark { }) } - fn init) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> Arc { + fn init(&self, component: F) -> Arc { self.0.init(component) } diff --git a/src/engine/console.rs b/src/engine/console.rs index 592ca01..7f82d54 100644 --- a/src/engine/console.rs +++ b/src/engine/console.rs @@ -7,7 +7,7 @@ use crossterm::{cursor::MoveTo, execute, terminal::Clear}; use crate::{ engine::{commands, CommandExecutor}, - prelude::Context, + prelude::{ComponentImpl, Context}, render::Area, DrawContext, View, }; @@ -79,10 +79,7 @@ impl Engine for Console { )); } - fn init) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> Arc { + fn init(&self, component: C) -> Arc { let cx = Context::new(component, self.executor.clone()); cx.refresh(); @@ -102,10 +99,7 @@ impl Engine for Console { self.executor.clone() } - fn run) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> crate::Result<()> { + fn run(&self, component: F) -> crate::Result<()> { let cx = self.init(component); while self.executor.is_running() { diff --git a/src/engine/mod.rs b/src/engine/mod.rs index b2f039f..c0f5525 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -7,18 +7,15 @@ pub use console::*; use std::{any::Any, sync::Arc}; -use crate::{prelude::Context, render::Area, DrawContext, View}; +use crate::{ + prelude::{ComponentImpl, Context}, + render::Area, + DrawContext, View, +}; pub trait Engine { - fn run) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> crate::Result; - - fn init) -> View + Send + Sync + 'static>( - &self, - component: F, - ) -> Arc; + fn run(&self, component: C) -> crate::Result; + fn init(&self, component: C) -> Arc; fn render(&self, cx: &Arc); fn render_delay(&self) { std::thread::sleep(std::time::Duration::from_millis(16))