better structure
This commit is contained in:
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user