diff --git a/src/element/input.rs b/src/element/input.rs index b085104..f6ccfa9 100644 --- a/src/element/input.rs +++ b/src/element/input.rs @@ -41,7 +41,7 @@ impl Element for Input { } impl KeyPressEventHandler for Input { - fn on_keypress(&mut self, events: &Arc, event: Box) { + fn on_keypress(&mut self, events: &Arc, event: &KeyEvent) { match event.code { crossterm::event::KeyCode::Char(c) => { self.0.insert(self.1, c); diff --git a/src/events.rs b/src/events.rs index 1138089..436c489 100644 --- a/src/events.rs +++ b/src/events.rs @@ -9,13 +9,13 @@ use crate::{event, state::StateManager}; event!(Close); pub trait Event { - fn as_any(self: Box) -> Box; + fn as_any(&self) -> &dyn Any; } pub struct EventManager { - handlers: - Mutex, Box)>>>>>, + handlers: Mutex, &dyn Event)>>>>>, states: Mutex>>, + event_stack: Mutex)>>, } impl EventManager { @@ -23,10 +23,11 @@ impl EventManager { Arc::new(EventManager { handlers: Mutex::new(HashMap::new()), states: Mutex::new(None), + event_stack: Mutex::new(Vec::new()), }) } - pub fn on, Box) + 'static>( + pub fn on, &E) + 'static>( self: &Arc, mut f: F, ) { @@ -37,8 +38,8 @@ impl EventManager { .entry(TypeId::of::()) .or_insert_with(Vec::new) .push(Arc::new(Mutex::new( - move |e: &Arc, evt: Box| { - if let Ok(concrete) = evt.as_any().downcast::() { + move |e: &Arc, evt: &dyn Event| { + if let Some(concrete) = evt.as_any().downcast_ref::() { f(&e, concrete); if let Some(states) = &states { states.clone().flush(); @@ -48,24 +49,33 @@ impl EventManager { ))); } - pub fn dispatch(self: &Arc, evt: E) { - let tid = evt.type_id(); - + fn dispatch_single(self: &Arc, tid: TypeId, evt: &dyn Event) { if let Some(handlers) = self.handlers.lock().unwrap().get_mut(&tid) { - // Clone handlers to avoid borrowing self during call let handler_clones: Vec<_> = handlers.iter().cloned().collect(); for h in handler_clones { let mut ha = h.lock().unwrap(); - (ha)(self, Box::new(evt.clone())); + (ha)(self, evt); } } + } - if tid == TypeId::of::() { - std::process::exit(0); + pub fn dispatch(self: &Arc, evt: E) { + self.event_stack + .lock() + .unwrap() + .push((evt.type_id(), Box::new(evt))); + + while self.event_stack.lock().unwrap().len() > 0 { + dis } } + pub fn close(self: &Arc) { + self.dispatch(Close); + std::process::exit(0); + } + pub fn set_state_manager(self: &Arc, states: Arc) { *self.states.lock().unwrap() = Some(states); } diff --git a/src/extensions/keypress.rs b/src/extensions/keypress.rs index 0eb7d17..1613f54 100644 --- a/src/extensions/keypress.rs +++ b/src/extensions/keypress.rs @@ -9,13 +9,13 @@ use crate::{ }; impl Event for KeyEvent { - fn as_any(self: Box) -> Box { + fn as_any(&self) -> &dyn std::any::Any { self } } pub trait KeyPressEventHandler { - fn on_keypress(&mut self, events: &Arc, event: Box); + fn on_keypress(&mut self, events: &Arc, event: &KeyEvent); } pub struct KeyPressExtension; @@ -26,7 +26,7 @@ impl Extension for KeyPressExtension { crate::utils::clear().unwrap(); crate::utils::hide_cursor().unwrap(); - events.on(|_, _: Box| { + events.on(|_, _: &Close| { crossterm::terminal::disable_raw_mode().unwrap(); crate::utils::show_cursor().unwrap(); crate::utils::clear().unwrap(); diff --git a/src/macros.rs b/src/macros.rs index 083462a..a8d7d19 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,7 +5,7 @@ macro_rules! event { pub struct $name; impl $crate::events::Event for $name { - fn as_any(self: Box) -> Box { + fn as_any(&self) -> &dyn std::any::Any { self } } @@ -18,7 +18,7 @@ macro_rules! event { } impl $crate::events::Event for $name { - fn as_any(self: Box) -> Box { + fn as_any(&self) -> &dyn std::any::Any { self } } @@ -29,7 +29,7 @@ macro_rules! event { pub struct $name ($($inner)*); impl $crate::events::Event for $name { - fn as_any(self: Box) -> Box { + fn as_any(&self) -> &dyn std::any::Any { self } } diff --git a/src/main.rs b/src/main.rs index 169fb6d..66af92d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use crossterm::event::KeyEvent; use osui::{ element::rect::Rect, - events::Close, + events::EventManager, extensions::{keypress::KeyPressExtension, ExtensionManager}, state::StateManager, style::Transform, @@ -39,14 +39,14 @@ fn app(states: &Arc, screen: &mut Screen) { .draw(format!("Count: {}", count.get())) .component(Transform::center()); - screen - .events - .on(move |events, event: Box| match event.code { + screen.events.on( + move |events: &Arc, event: &KeyEvent| match event.code { crossterm::event::KeyCode::Enter => { count.set(count.get() + 1); } _ => { - events.dispatch(Close); + events.close(); } - }); + }, + ); }