diff --git a/mangades/src/component_demo_syntax.rs b/mangades/src/component_demo_syntax.rs index d8e9700..b8743f5 100644 --- a/mangades/src/component_demo_syntax.rs +++ b/mangades/src/component_demo_syntax.rs @@ -72,10 +72,11 @@ make_component!( $|event| { match event.event { mangui::events::InnerEvent::MouseDown(_) => { - $test_ = true; + let test_ = &mut $test_; + *test_ = !*test_; }, mangui::events::InnerEvent::MouseUp(_) => { - $test_ = false; + // $test_ = false; }, _ => {} } diff --git a/mangades/src/slot_demo.rs b/mangades/src/slot_demo.rs index e80b948..639d56b 100644 --- a/mangades/src/slot_demo.rs +++ b/mangades/src/slot_demo.rs @@ -1,12 +1,14 @@ use std::sync::{Arc, Mutex, RwLock}; use mangui::nodes::layout::Layout; use mangui::nodes::primitives::Rectangle; +use mangui::WeakSharedNode; use rusalka::component::Slot; use rusalka::store::{DerefGuardExt, ReadableStore, Signal, StoreUnsubscribe, Writable, WritableStore}; pub struct SlotAcceptDemo { comp0: rusalka::SharedNodeComponent, - comp1: Mutex>, + comp1: Arc>>, + parent: Mutex>, selfref: rusalka::WeakSharedComponent, attrs: ReactiveSlotAcceptDemoAttributes, } @@ -52,14 +54,30 @@ impl rusalka::component::Component for SlotAcceptDemo { comp0: std::sync::Arc::new( std::sync::RwLock::new(Layout { ..Default::default() }), ), - comp1: Mutex::new(None), + comp1: Arc::new(Mutex::new(None)), attrs: attrs.into(), + parent: Mutex::new(None), selfref }; this } fn set(&mut self, attrs: Self::PartialComponentAttrs) { - + if let Some(__default_slot) = attrs.__default_slot { + if let Some(slot) = &self.attrs.__default_slot { + if self.parent.lock().unwrap().is_some() { + (*self.comp1.lock().unwrap().as_mut().unwrap().unmount)(); + } + *self.comp1.lock().unwrap() = None; + } + if let Some(slot) = __default_slot { + *self.comp1.lock().unwrap() = Some(slot.lock().unwrap()(())); + if let Some(parent) = &self.parent.lock().unwrap().as_ref() { + if let Some(parent) = parent.upgrade() { + (*self.comp1.lock().unwrap().as_mut().unwrap().mount)(&parent, None); + } + } + } + } } fn get(&self) -> &Self::ReactiveComponentAttrs { &self.attrs @@ -69,6 +87,7 @@ impl rusalka::component::Component for SlotAcceptDemo { parent: &mangui::SharedNode, before: Option<&mangui::SharedNode>, ) { + self.parent.lock().unwrap().replace(Arc::downgrade(parent)); rusalka::nodes::insert(parent, &{ self.comp0.clone() }, before); match &self.attrs.__default_slot { Some(slot) => { @@ -79,6 +98,7 @@ impl rusalka::component::Component for SlotAcceptDemo { } } fn unmount(&self) { + self.parent.lock().unwrap().take(); rusalka::nodes::detach(&{ self.comp0.clone() }); match &self.attrs.__default_slot { Some(slot) => { @@ -98,7 +118,7 @@ struct SlotDemoSlot1 { pub struct SlotDemo { comp0: rusalka::SharedNodeComponent, comp1: rusalka::SharedComponent, - test_: std::sync::Arc>>, + test_: std::sync::Arc>, sub0: Box, selfref: rusalka::WeakSharedComponent, attrs: ReactiveSlotDemoAttributes, @@ -109,7 +129,7 @@ pub struct SlotDemoAttributes { } pub struct ReactiveSlotDemoAttributes { - pub test: Arc>> + pub test: Arc> } #[derive(Default)] @@ -124,17 +144,17 @@ impl From for PartialSlotDemoAttributes { impl From for SlotDemoAttributes { fn from(attrs: ReactiveSlotDemoAttributes) -> Self { - Self { test: *attrs.test.lock().unwrap().get() } + Self { test: *attrs.test.get() } } } impl From<&ReactiveSlotDemoAttributes> for SlotDemoAttributes { fn from(attrs: &ReactiveSlotDemoAttributes) -> Self { - Self { test: *attrs.test.lock().unwrap().get() } + Self { test: *attrs.test.get() } } } impl From for ReactiveSlotDemoAttributes { fn from(attrs: SlotDemoAttributes) -> Self { - Self { test: Arc::new(Mutex::new(Writable::new(attrs.test))) } + Self { test: Arc::new(Writable::new(attrs.test)) } } } @@ -149,9 +169,9 @@ impl rusalka::component::Component for SlotDemo { ) -> Self { let attrs: Self::ReactiveComponentAttrs = attrs.into(); let test_: std::sync::Arc< - std::sync::Mutex>, + rusalka::store::Writable, > = std::sync::Arc::new( - std::sync::Mutex::new(rusalka::store::Writable::new(false)), + rusalka::store::Writable::new(false), ); let test = attrs.test.clone(); let this = Self { @@ -172,17 +192,17 @@ impl rusalka::component::Component for SlotDemo { let slot = Some( SlotDemoSlot1 { comp0: std::sync::Arc::new( - std::sync::RwLock::new(Rectangle { radius: *test.clone().lock().unwrap().get(), ..Default::default() }), + std::sync::RwLock::new(Rectangle { radius: *test.clone().get(), ..Default::default() }), ), sub0: { let comp0 = comp0.clone(); let test = test.clone(); - [test.clone().lock().unwrap()].subscribe(Box::new(move || { + [test.clone()].subscribe(Box::new(move || { let comp1 = comp0.clone(); let test1 = test.clone(); let mut comp1l = comp1.lock().unwrap(); if let Some(comp1) = comp1l.as_mut() { - comp1.comp0.write().unwrap().radius = *test1.lock().unwrap().get(); + comp1.comp0.write().unwrap().radius = *test1.get(); } })) }, @@ -211,9 +231,9 @@ impl rusalka::component::Component for SlotDemo { )), sub0: { let test = test_.clone(); - [test.clone().lock().unwrap()].subscribe(Box::new(move || { + [test.clone()].subscribe(Box::new(move || { let test = test.clone(); - dbg!(test.lock().unwrap().get()); + dbg!(test.get()); })) }, attrs, @@ -233,10 +253,10 @@ impl rusalka::component::Component for SlotDemo { let test_ = &this.test_; match event.event { mangui::events::InnerEvent::MouseDown(_) => { - **test_.lock().unwrap().guard() = true; + **test_.guard() = true; } mangui::events::InnerEvent::MouseUp(_) => { - **test_.lock().unwrap().guard() = false; + **test_.guard() = false; } _ => {} } @@ -246,8 +266,7 @@ impl rusalka::component::Component for SlotDemo { } fn set(&mut self, attrs: Self::PartialComponentAttrs) { if let Some(test) = attrs.test { - **self.attrs.test.lock().unwrap().guard() = test; - // self.attrs.test.lock().unwrap().set(test); + **self.attrs.test.guard() = test; } } fn get(&self) -> &Self::ReactiveComponentAttrs { diff --git a/rusalka-macro/src/lib.rs b/rusalka-macro/src/lib.rs index d438364..a0eb3ea 100644 --- a/rusalka-macro/src/lib.rs +++ b/rusalka-macro/src/lib.rs @@ -28,6 +28,7 @@ struct EventListener { #[derive(Debug)] enum ComponentType { + SlotDefinition, RealComponent, Node } @@ -293,15 +294,24 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream }, ComponentType::Node => { midstream.extend(quote!(SharedNodeComponent<)); + }, + ComponentType::SlotDefinition => { + midstream.extend(quote!(SharedSlot)); } } + + match component.component_type { + ComponentType::RealComponent | ComponentType::Node => { + let component_name = component.name.clone(); + + component_struct_stream.extend(Some(TokenTree::Ident(ident))); + component_struct_stream.extend(midstream); + component_struct_stream.extend(Some(TokenTree::Ident(component_name))); + component_struct_stream.extend(quote!(>,)); + }, + ComponentType::SlotDefinition => {} + } - let component_name = component.name.clone(); - - component_struct_stream.extend(Some(TokenTree::Ident(ident))); - component_struct_stream.extend(midstream); - component_struct_stream.extend(Some(TokenTree::Ident(component_name))); - component_struct_stream.extend(quote!(>,)); } component_struct_stream.extend(quote!( @@ -515,10 +525,10 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream let mut component_stream = TokenStream::new(); - component_stream.extend(Some(TokenTree::Ident(component_name.clone()))); - match component.component_type { ComponentType::RealComponent => { + component_stream.extend(Some(TokenTree::Ident(component_name.clone()))); + component_stream.extend(quote!(::new)); let mut component_new_stream = TokenStream::new(); @@ -544,10 +554,15 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream new_returnvalue_stream.extend(wrap_in_arcmutex_cyclic(component_stream)); }, ComponentType::Node => { + component_stream.extend(Some(TokenTree::Ident(component_name.clone()))); + let (_reactive_variables, subcomponent_stream) = replace_variables(component.contents.clone()); let node_group = Group::new(Delimiter::Brace, subcomponent_stream); component_stream.extend(Some(TokenTree::Group(node_group))); new_returnvalue_stream.extend(wrap_in_arcrwlock(component_stream)); + }, + ComponentType::SlotDefinition => { + component_stream.extend(quote!(Arc::new(Mutex::new(None)))); } } new_returnvalue_stream.extend(quote!(,)); @@ -594,6 +609,8 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream for component in &components_used { match component.component_type { ComponentType::RealComponent => continue, + // currently just ignore those, in the future it should probably be an error. + ComponentType::SlotDefinition => continue, ComponentType::Node => {} }; for event_listener in &component.event_listeners { @@ -706,6 +723,7 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream let ident = Ident::new(&format!("comp{}", i), component.name.span()); match component.component_type { + ComponentType::SlotDefinition => continue, ComponentType::RealComponent => { // mount mount_stream.extend(quote!(self.)); @@ -805,6 +823,7 @@ pub fn make_component(item: proc_macro::TokenStream) -> proc_macro::TokenStream let ident = Ident::new(&format!("comp{}", i), component.name.span()); match component.component_type { + ComponentType::SlotDefinition => continue, ComponentType::RealComponent => { let mut component_stream = TokenStream::new(); diff --git a/rusalka/src/lib.rs b/rusalka/src/lib.rs index 97af669..7567461 100644 --- a/rusalka/src/lib.rs +++ b/rusalka/src/lib.rs @@ -2,6 +2,7 @@ use std::sync::{Arc, Mutex, RwLock}; use component::Component; use mangui::nodes::Node; +use crate::component::Slot; pub mod component; pub mod nodes; @@ -9,4 +10,5 @@ pub mod store; pub type SharedComponent = Arc>; pub type WeakSharedComponent = std::sync::Weak>; -pub type SharedNodeComponent = Arc>; \ No newline at end of file +pub type SharedNodeComponent = Arc>; +pub type SharedSlot = Arc>>; \ No newline at end of file