diff --git a/src/frontend.rs b/src/frontend.rs index 58d4eff..cbc7037 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -7,7 +7,7 @@ use crate::{ }; pub enum RsxElement { - Element(Arc, Rsx), + Element(StaticWidget, Rsx), DynElement( Box WidgetLoad + Send + Sync>, @@ -68,7 +68,7 @@ impl Rsx { )); } - pub fn create_element_static(&mut self, element: Arc, children: Rsx) { + pub fn create_element_static(&mut self, element: StaticWidget, children: Rsx) { self.0.push(RsxElement::Element(element, children)); } diff --git a/src/lib.rs b/src/lib.rs index 4786975..5e3801e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,15 +54,13 @@ impl Screen { } pub fn draw(self: &Arc, element: E) -> Arc { - let w = Arc::new(Widget::Static(Arc::new(StaticWidget::new(Box::new( - element, - ))))); + let w = Arc::new(Widget::Static(StaticWidget::new(Box::new(element)))); self.widgets.lock().unwrap().push(w.clone()); w } pub fn draw_box(self: &Arc, element: BoxedElement) -> Arc { - let w = Arc::new(Widget::Static(Arc::new(StaticWidget::new(element)))); + let w = Arc::new(Widget::Static(StaticWidget::new(element))); self.widgets.lock().unwrap().push(w.clone()); w } @@ -75,7 +73,7 @@ impl Screen { self: &Arc, element: F, ) -> Arc { - let w = Arc::new(Widget::Dynamic(Arc::new(DynWidget::new(element)))); + let w = Arc::new(Widget::Dynamic(DynWidget::new(element))); self.widgets.lock().unwrap().push(w.clone()); w } @@ -84,7 +82,7 @@ impl Screen { self: &Arc, element: Box WidgetLoad + Send + Sync>, ) -> Arc { - let w = Arc::new(Widget::Dynamic(Arc::new(DynWidget::new(element)))); + let w = Arc::new(Widget::Dynamic(DynWidget::new(element))); self.widgets.lock().unwrap().push(w.clone()); w } diff --git a/src/macros.rs b/src/macros.rs index dbdc403..0bc9ed9 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -147,7 +147,9 @@ macro_rules! rsx { macro_rules! rsx_inner { // static ($r:expr, $(@$comp:expr;)* static $s:literal $($rest:tt)*) => { - $r.create_element_static(std::sync::Arc::new($crate::widget::StaticWidget::new(Box::new(format!($s)))) $(.component($comp))* .clone(), $crate::frontend::Rsx(Vec::new())); + let w = $crate::widget::StaticWidget::new(Box::new(format!($s))); + $(w.component($comp);)* + $r.create_element_static(w, $crate::frontend::Rsx(Vec::new())); $crate::rsx_inner! { $r, $($rest)* }; }; @@ -160,13 +162,17 @@ macro_rules! rsx_inner { // static ($r:expr, $(%$dep:ident)* $(@$comp:expr;)* static $name:path { $($inner:tt)* } ($($e:expr),*) $($rest:tt)*) => { - $r.create_element_static(std::sync::Arc::new($crate::widget::StaticWidget::new(Box::new(<$name>::new($($e),*)))) $(.component($comp))* .clone(), $crate::frontend::Rsx(Vec::new())); + let w = $crate::widget::StaticWidget::new(Box::new(<$name>::new($($e),*))); + $(w.component($comp);)* + $r.create_element_static(w, $crate::frontend::Rsx(Vec::new())); $crate::rsx_inner! { $r, $($rest)* }; }; // static ($r:expr, $(@$comp:expr;)* static $name:path { $($inner:tt)* } $($rest:tt)*) => { - $r.create_element_static(std::sync::Arc::new($crate::widget::StaticWidget::new(Box::new(<$name>::new()))) $(.component($comp))* .clone(), $crate::frontend::Rsx(Vec::new())); + let w = $crate::widget::StaticWidget::new(Box::new(<$name>::new())); + $(w.component($comp);)* + $r.create_element_static(w, $crate::frontend::Rsx(Vec::new())); $crate::rsx_inner! { $r, $($rest)* }; }; diff --git a/src/widget.rs b/src/widget.rs index 33dd49e..63f7ad9 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -50,12 +50,38 @@ impl WidgetLoad { } } +pub struct StaticWidget(Mutex, Mutex>); + +pub struct DynWidget( + Mutex, + Mutex>, + Mutex WidgetLoad + Send + Sync>>, + Mutex>>, + Mutex WidgetLoad + Send + Sync>>>, +); + pub enum Widget { - Static(Arc), - Dynamic(Arc), + Static(StaticWidget), + Dynamic(DynWidget), +} + +impl Widget { + pub fn new_static(e: BoxedElement) -> Self { + Self::Static(StaticWidget(Mutex::new(e), Mutex::new(HashMap::new()))) + } + + pub fn new_dyn WidgetLoad + 'static + Send + Sync>(mut e: F) -> Self { + let wl = e(); + Self::Dynamic(DynWidget( + Mutex::new(wl.0), + Mutex::new(wl.1), + Mutex::new(Box::new(e)), + Mutex::new(Vec::new()), + Mutex::new(None), + )) + } } -// === Trait Implementation === impl Widget { pub fn get_elem(&self) -> MutexGuard { match self { @@ -153,9 +179,6 @@ impl Widget { } } -// === Static Widget === -pub struct StaticWidget(Mutex, Mutex>); - impl StaticWidget { fn after_render(&self) {} fn get_elem(&self) -> MutexGuard { @@ -168,18 +191,16 @@ impl StaticWidget { Self(Mutex::new(e), Mutex::new(HashMap::new())) } - pub fn component(self: &Arc, c: C) -> &Arc { + pub fn component(&self, c: C) { self.1 .lock() .unwrap() .entry(c.type_id()) .or_insert_with(|| Box::new(c)); - self } - pub fn set_component(self: &Arc, c: C) -> &Arc { + pub fn set_component(&self, c: C) { self.1.lock().unwrap().insert(c.type_id(), Box::new(c)); - self } pub fn get(&self) -> Option { @@ -192,15 +213,6 @@ impl StaticWidget { } } -// === Dynamic Widget === -pub struct DynWidget( - Mutex, - Mutex>, - Mutex WidgetLoad + Send + Sync>>, - Mutex>>, - Mutex WidgetLoad + Send + Sync>>>, -); - impl DynWidget { fn after_render(&self) {} fn get_elem(&self) -> MutexGuard { @@ -220,15 +232,12 @@ impl DynWidget { ) } - pub fn inject WidgetLoad + 'static + Send + Sync>( - self: &Arc, - f: F, - ) { + pub fn inject WidgetLoad + 'static + Send + Sync>(&self, f: F) { *self.4.lock().unwrap() = Some(Box::new(f)); self.refresh(); } - pub fn refresh(self: &Arc) { + pub fn refresh(&self) { let mut w = (self.2.lock().unwrap())(); if let Some(we) = &mut *self.4.lock().unwrap() { @@ -239,7 +248,7 @@ impl DynWidget { *self.1.lock().unwrap() = w.1; } - pub fn auto_refresh(self: &Arc) { + pub fn auto_refresh(&self) { for d in self.3.lock().unwrap().iter() { if d.check() { self.refresh(); @@ -247,30 +256,26 @@ impl DynWidget { } } - pub fn dependency(self: &Arc, d: D) -> &Arc { + pub fn dependency(&self, d: D) { d.add(); self.3.lock().unwrap().push(Box::new(d)); - self } - pub fn dependency_box(self: &Arc, d: Box) -> &Arc { + pub fn dependency_box(&self, d: Box) { d.add(); self.3.lock().unwrap().push(d); - self } - pub fn component(self: &Arc, c: C) -> &Arc { + pub fn component(&self, c: C) { self.1 .lock() .unwrap() .entry(c.type_id()) .or_insert_with(|| Box::new(c)); - self } - pub fn set_component(self: &Arc, c: C) -> &Arc { + pub fn set_component(&self, c: C) { self.1.lock().unwrap().insert(c.type_id(), Box::new(c)); - self } pub fn get(&self) -> Option {