diff --git a/src/dependency.rs b/src/dependency.rs index 8e599a3..5d1e94d 100644 --- a/src/dependency.rs +++ b/src/dependency.rs @@ -1,19 +1,19 @@ use std::sync::Arc; -use crate::{widget::Element}; +use crate::widget::Element; pub trait DependencyHandler: std::fmt::Debug + Send + Sync { fn add(&self); fn check(&self) -> bool; } -pub struct Dependency { +pub struct Dependency { handlers: Vec>, element: T, element_reset: Box T + Send + Sync>, } -impl Dependency { +impl Dependency { pub fn new T + Send + Sync + 'static>(mut f: F) -> Self { Self { handlers: Vec::new(), @@ -22,6 +22,21 @@ impl Dependency { } } + pub fn from( + mut f: Box T + Send + Sync>, + handlers: Vec>, + ) -> Self { + for h in &handlers { + h.add(); + } + + Self { + handlers, + element: f(), + element_reset: f, + } + } + pub fn auto_reset(&mut self) { for i in &self.handlers { if i.check() { @@ -37,6 +52,26 @@ impl Dependency { } } +impl Element for Dependency> { + fn render(&mut self, scope: &mut crate::render_scope::RenderScope) { + self.element.render(scope); + self.auto_reset(); + } + + fn after_render(&mut self, scope: &crate::render_scope::RenderScope) { + self.element.after_render(scope); + self.auto_reset(); + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } +} + impl Element for Dependency { fn render(&mut self, scope: &mut crate::render_scope::RenderScope) { self.element.render(scope); diff --git a/src/frontend.rs b/src/frontend.rs new file mode 100644 index 0000000..0293e14 --- /dev/null +++ b/src/frontend.rs @@ -0,0 +1,23 @@ +use std::sync::Arc; + +use crate::{ + dependency::{Dependency, DependencyHandler}, + widget::{Element, Widget}, + Screen, +}; + +pub struct Rsx( + pub Vec<( + Box Box + Send + Sync>, + Vec>, + )>, +); + +impl Rsx { + pub fn draw(self, screen: &Arc) { + for i in self.0 { + let d = Dependency::from(i.0, i.1); + screen.draw_widget(Widget::new(Box::new(d))); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index a1d827a..0edf1fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ use crate::{ pub mod dependency; pub mod elements; pub mod extensions; +pub mod frontend; pub mod macros; pub mod render_scope; pub mod style; @@ -46,6 +47,12 @@ impl Screen { w } + pub fn draw_widget(self: &Arc, w: Widget) -> Arc { + let w = Arc::new(w); + self.widgets.lock().unwrap().push(w.clone()); + w + } + pub fn extension(self: &Arc, ext: E) { self.extensions .lock() diff --git a/src/macros.rs b/src/macros.rs index 9d29000..3be9741 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -125,5 +125,20 @@ macro_rules! event_handler { #[macro_export] macro_rules! rsx { - () => {}; + ($($inner:tt)*) => {{ + let mut r = Rsx(Vec::new()); + + $crate::rsx_inner! { r, $($inner)* }; + + r + }}; +} + +#[macro_export] +macro_rules! rsx_inner { + ($r:expr, $(%$dep:ident)* $s:literal $($rest:tt)*) => { + $r.0.push((Box::new({ $(let $dep = $dep.clone();)* move || Box::new(format!($s)) }), vec![$(Arc::new($dep.clone()),)*])); + $crate::rsx_inner!{ $r, $($rest)* }; + }; + ($r:expr,) => {}; } diff --git a/src/main.rs b/src/main.rs index 530bffe..36dc21d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,27 @@ -use osui::{dependency::Dependency, elements::state::use_state, style::Transform, Screen}; +use std::sync::Arc; + +use osui::{elements::state::use_state, frontend::Rsx, rsx, Screen}; fn main() -> std::io::Result<()> { let screen = Screen::new(); + + app().draw(&screen); + + screen.run() +} + +fn app() -> Rsx { let count = use_state(0); std::thread::spawn({ let count = count.clone(); move || loop { - std::thread::sleep(std::time::Duration::from_millis(1000)); - **count.get() += 500; + std::thread::sleep(std::time::Duration::from_millis(50)); + **count.get() += 1; } }); - screen - .draw( - Dependency::new({ - let count = count.clone(); - move || format!("{count}") - }) - .add(count.clone()), - ) - .component(Transform::center()); - - screen.run() + rsx! { + %count "{count}" + } }