better structure

This commit is contained in:
2025-06-28 15:02:45 +02:00
parent f401d4a995
commit f43be496c1
5 changed files with 36 additions and 26 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ impl Element for Input {
} }
impl KeyPressEventHandler for Input { impl KeyPressEventHandler for Input {
fn on_keypress(&mut self, events: &Arc<EventManager>, event: Box<KeyEvent>) { fn on_keypress(&mut self, events: &Arc<EventManager>, event: &KeyEvent) {
match event.code { match event.code {
crossterm::event::KeyCode::Char(c) => { crossterm::event::KeyCode::Char(c) => {
self.0.insert(self.1, c); self.0.insert(self.1, c);
+23 -13
View File
@@ -9,13 +9,13 @@ use crate::{event, state::StateManager};
event!(Close); event!(Close);
pub trait Event { pub trait Event {
fn as_any(self: Box<Self>) -> Box<dyn Any>; fn as_any(&self) -> &dyn Any;
} }
pub struct EventManager { pub struct EventManager {
handlers: handlers: Mutex<HashMap<TypeId, Vec<Arc<Mutex<dyn FnMut(&Arc<EventManager>, &dyn Event)>>>>>,
Mutex<HashMap<TypeId, Vec<Arc<Mutex<dyn FnMut(&Arc<EventManager>, Box<dyn Event>)>>>>>,
states: Mutex<Option<Arc<StateManager>>>, states: Mutex<Option<Arc<StateManager>>>,
event_stack: Mutex<Vec<(TypeId, Box<dyn Event>)>>,
} }
impl EventManager { impl EventManager {
@@ -23,10 +23,11 @@ impl EventManager {
Arc::new(EventManager { Arc::new(EventManager {
handlers: Mutex::new(HashMap::new()), handlers: Mutex::new(HashMap::new()),
states: Mutex::new(None), states: Mutex::new(None),
event_stack: Mutex::new(Vec::new()),
}) })
} }
pub fn on<E: Event + 'static, F: FnMut(&Arc<EventManager>, Box<E>) + 'static>( pub fn on<E: Event + 'static, F: FnMut(&Arc<EventManager>, &E) + 'static>(
self: &Arc<Self>, self: &Arc<Self>,
mut f: F, mut f: F,
) { ) {
@@ -37,8 +38,8 @@ impl EventManager {
.entry(TypeId::of::<E>()) .entry(TypeId::of::<E>())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(Arc::new(Mutex::new( .push(Arc::new(Mutex::new(
move |e: &Arc<EventManager>, evt: Box<dyn Event>| { move |e: &Arc<EventManager>, evt: &dyn Event| {
if let Ok(concrete) = evt.as_any().downcast::<E>() { if let Some(concrete) = evt.as_any().downcast_ref::<E>() {
f(&e, concrete); f(&e, concrete);
if let Some(states) = &states { if let Some(states) = &states {
states.clone().flush(); states.clone().flush();
@@ -48,24 +49,33 @@ impl EventManager {
))); )));
} }
pub fn dispatch<E: Event + 'static + Clone>(self: &Arc<Self>, evt: E) { fn dispatch_single(self: &Arc<Self>, tid: TypeId, evt: &dyn Event) {
let tid = evt.type_id();
if let Some(handlers) = self.handlers.lock().unwrap().get_mut(&tid) { 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(); let handler_clones: Vec<_> = handlers.iter().cloned().collect();
for h in handler_clones { for h in handler_clones {
let mut ha = h.lock().unwrap(); let mut ha = h.lock().unwrap();
(ha)(self, Box::new(evt.clone())); (ha)(self, evt);
}
} }
} }
if tid == TypeId::of::<Close>() { pub fn dispatch<E: Event + 'static + Clone>(self: &Arc<Self>, evt: E) {
std::process::exit(0); 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>) {
self.dispatch(Close);
std::process::exit(0);
}
pub fn set_state_manager(self: &Arc<Self>, states: Arc<StateManager>) { pub fn set_state_manager(self: &Arc<Self>, states: Arc<StateManager>) {
*self.states.lock().unwrap() = Some(states); *self.states.lock().unwrap() = Some(states);
} }
+3 -3
View File
@@ -9,13 +9,13 @@ use crate::{
}; };
impl Event for KeyEvent { impl Event for KeyEvent {
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
} }
pub trait KeyPressEventHandler { pub trait KeyPressEventHandler {
fn on_keypress(&mut self, events: &Arc<EventManager>, event: Box<KeyEvent>); fn on_keypress(&mut self, events: &Arc<EventManager>, event: &KeyEvent);
} }
pub struct KeyPressExtension; pub struct KeyPressExtension;
@@ -26,7 +26,7 @@ impl Extension for KeyPressExtension {
crate::utils::clear().unwrap(); crate::utils::clear().unwrap();
crate::utils::hide_cursor().unwrap(); crate::utils::hide_cursor().unwrap();
events.on(|_, _: Box<Close>| { events.on(|_, _: &Close| {
crossterm::terminal::disable_raw_mode().unwrap(); crossterm::terminal::disable_raw_mode().unwrap();
crate::utils::show_cursor().unwrap(); crate::utils::show_cursor().unwrap();
crate::utils::clear().unwrap(); crate::utils::clear().unwrap();
+3 -3
View File
@@ -5,7 +5,7 @@ macro_rules! event {
pub struct $name; pub struct $name;
impl $crate::events::Event for $name { impl $crate::events::Event for $name {
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
} }
@@ -18,7 +18,7 @@ macro_rules! event {
} }
impl $crate::events::Event for $name { impl $crate::events::Event for $name {
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
} }
@@ -29,7 +29,7 @@ macro_rules! event {
pub struct $name ($($inner)*); pub struct $name ($($inner)*);
impl $crate::events::Event for $name { impl $crate::events::Event for $name {
fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
} }
+6 -6
View File
@@ -3,7 +3,7 @@ use std::sync::Arc;
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;
use osui::{ use osui::{
element::rect::Rect, element::rect::Rect,
events::Close, events::EventManager,
extensions::{keypress::KeyPressExtension, ExtensionManager}, extensions::{keypress::KeyPressExtension, ExtensionManager},
state::StateManager, state::StateManager,
style::Transform, style::Transform,
@@ -39,14 +39,14 @@ fn app(states: &Arc<StateManager>, screen: &mut Screen) {
.draw(format!("Count: {}", count.get())) .draw(format!("Count: {}", count.get()))
.component(Transform::center()); .component(Transform::center());
screen screen.events.on(
.events move |events: &Arc<EventManager>, event: &KeyEvent| match event.code {
.on(move |events, event: Box<KeyEvent>| match event.code {
crossterm::event::KeyCode::Enter => { crossterm::event::KeyCode::Enter => {
count.set(count.get() + 1); count.set(count.get() + 1);
} }
_ => { _ => {
events.dispatch(Close); events.close();
} }
}); },
);
} }