diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 72dc920..1d45b1a 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -23,21 +23,25 @@ fn main() { } fn app(cx: &Arc) -> View { - cx.child( - my_component, - Some(Arc::new(|ctx, view| { - let area = ctx.allocate(0, 0, 0, 0); - ctx.draw_view(area, view) - })), - ); + { + let scope = cx.scope(); - cx.child( - my_component, - Some(Arc::new(|ctx, view| { - let area = ctx.allocate(0, 1, 0, 0); - ctx.draw_view(area, view) - })), - ); + scope.child( + my_component, + Some(Arc::new(|ctx, view| { + let area = ctx.allocate(0, 0, 0, 0); + ctx.draw_view(area, view) + })), + ); + + scope.child( + my_component, + Some(Arc::new(|ctx, view| { + let area = ctx.allocate(0, 1, 0, 0); + ctx.draw_view(area, view) + })), + ); + } Arc::new({ let cx = cx.clone(); diff --git a/src/component.rs b/src/component.rs index 1081e73..4c6a585 100644 --- a/src/component.rs +++ b/src/component.rs @@ -19,24 +19,29 @@ impl<'a> dyn Event + 'a { pub type Component = Arc) -> View + Send + Sync>; pub type EventHandler = Arc, &dyn Event) + Send + Sync>>; +pub struct Scope { + pub children: Mutex, Option)>>, + pub scope: Mutex, +} + pub struct Context { component: Mutex, event_handlers: Mutex>>, view: Mutex, - children: Mutex, Option)>>, + scopes: Mutex>>, } impl Context { - pub fn new) -> View + Send + Sync + 'static>(component: F) -> Arc { + pub fn new) -> View + Send + Sync + 'static>(component: F) -> Arc { Arc::new(Self { component: Mutex::new(Arc::new(component)), event_handlers: Mutex::new(HashMap::new()), view: Mutex::new(Arc::new(|_| {})), - children: Mutex::new(Vec::new()), + scopes: Mutex::new(Vec::new()), }) } - pub fn refresh(self: &Arc) { + pub fn refresh(self: &Arc) { let s = self.clone(); std::thread::spawn({ @@ -48,7 +53,7 @@ impl Context { }); } - pub fn refresh_atomic(self: &Arc) -> Arc> { + pub fn refresh_atomic(self: &Arc) -> Arc> { let s = self.clone(); let done = Arc::new(Mutex::new(false)); @@ -65,12 +70,12 @@ impl Context { done } - pub fn get_view(self: &Arc) -> View { + pub fn get_view(self: &Arc) -> View { self.view.lock().unwrap().clone() } - pub fn on_event, &T) + Send + Sync + 'static>( - self: &Arc, + pub fn on_event, &T) + Send + Sync + 'static>( + self: &Arc, handler: F, ) { self.event_handlers @@ -79,7 +84,7 @@ impl Context { .entry(TypeId::of::()) .or_insert_with(|| Vec::new()) .push(Arc::new(Mutex::new( - move |ctx: &Arc, event: &dyn Event| { + move |ctx: &Arc, event: &dyn Event| { if let Some(e) = event.get::() { (handler)(ctx, e); } @@ -87,20 +92,22 @@ impl Context { ))); } - pub fn emit_event(self: &Arc, event: &E) { + pub fn emit_event(self: &Arc, event: &E) { if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::()) { for i in v { (i.lock().unwrap())(self, event); } } - for (child, _) in self.children.lock().unwrap().iter() { - child.emit_event(event); + for scope in self.scopes.lock().unwrap().iter() { + for (child, _) in scope.children.lock().unwrap().iter() { + child.emit_event(event); + } } } pub fn emit_event_threaded( - self: &Arc, + self: &Arc, event: &E, ) { if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::()) { @@ -114,13 +121,41 @@ impl Context { } } - for (child, _) in self.children.lock().unwrap().iter() { - child.emit_event_threaded(event); + for scope in self.scopes.lock().unwrap().iter() { + for (child, _) in scope.children.lock().unwrap().iter() { + child.emit_event_threaded(event); + } } } + pub fn scope(self: &Arc) -> Arc { + let scope = Arc::new(Scope { + children: Mutex::new(Vec::new()), + scope: Mutex::new(0), + }); + self.scopes.lock().unwrap().push(scope.clone()); + + scope + } + + pub fn draw_children(self: &Arc, ctx: &mut DrawContext) { + for scope in self.scopes.lock().unwrap().iter() { + for (child, view_wrapper) in scope.children.lock().unwrap().iter() { + let view = child.get_view(); + + if let Some(view_wrapper) = view_wrapper { + view_wrapper(ctx, view) + } else { + ctx.draw_view(ctx.area.clone(), view); + } + } + } + } +} + +impl Scope { pub fn child) -> View + Send + Sync + 'static>( - self: &Arc, + self: &Arc, child: F, view_wrapper: Option, ) { @@ -130,16 +165,4 @@ impl Context { self.children.lock().unwrap().push((ctx, view_wrapper)); } - - pub fn draw_children(self: &Arc, ctx: &mut DrawContext) { - for (child, view_wrapper) in self.children.lock().unwrap().iter() { - let view = child.get_view(); - - if let Some(view_wrapper) = view_wrapper { - view_wrapper(ctx, view) - } else { - ctx.draw_view(ctx.area.clone(), view); - } - } - } }