From cec25c02d578687530ef0ed9020bf5d22bace940 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sat, 5 Jul 2025 06:48:21 +0200 Subject: [PATCH] better handlers --- src/extensions/mod.rs | 48 +++++++++++++++++++++++++++++++++++------- src/extensions/tick.rs | 19 +++++++++++------ src/macros.rs | 6 +++--- src/main.rs | 9 ++++++-- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index 741f3a2..1b8db7c 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -3,27 +3,59 @@ pub mod tick; pub mod velocity; use std::{ + any::{Any, TypeId}, fmt::Debug, sync::{Arc, Mutex}, }; -use crate::{render_scope::RenderScope, widget::Widget}; +use crate::{ + render_scope::RenderScope, + widget::{Component, Widget}, +}; pub trait Extension { fn init(&mut self, _widgets: &Vec>) {} fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc) {} } -#[derive(Clone)] -pub struct Handler(pub Arc) + Send + Sync>>); +pub trait Event: Send + Sync { + fn as_any(&self) -> &dyn Any; +} -impl Handler { - pub fn new) + Send + Sync + 'static>(f: F) -> Handler { - Handler(Arc::new(Mutex::new(f))) +#[derive(Clone)] +pub struct Handler( + Arc, &dyn Event) + Send + Sync>>, + TypeId, +); + +impl Component for Handler { + fn as_any(&self) -> &dyn Any { + self } - pub fn call(&self, w: &Arc) { - (self.0.lock().unwrap())(w) + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } +} + +impl Handler { + pub fn new, &E) + Send + Sync + 'static>( + mut f: F, + ) -> Handler { + Handler( + Arc::new(Mutex::new(move |w: &Arc, e: &dyn Event| { + if let Some(e) = e.as_any().downcast_ref::() { + f(w, e) + } + })), + TypeId::of::(), + ) + } + + pub fn call(&self, w: &Arc, e: &E) { + if e.as_any().type_id() == self.1 { + (self.0.lock().unwrap())(w, e) + } } } diff --git a/src/extensions/tick.rs b/src/extensions/tick.rs index 0a58722..4df2bb7 100644 --- a/src/extensions/tick.rs +++ b/src/extensions/tick.rs @@ -1,7 +1,8 @@ use std::{fmt::Debug, sync::Arc}; +use crate::event; use crate::extensions::Handler; -use crate::{component, extensions::Extension, widget::Widget}; +use crate::{extensions::Extension, widget::Widget}; pub struct TickExtension(pub u16); @@ -10,16 +11,20 @@ impl Extension for TickExtension { let rate_dur = 1000 / self.0 as u64; std::thread::spawn({ let widgets = widgets.clone(); - move || loop { - for w in &widgets { - if let Some(on_tick) = w.get::() { - on_tick.0.call(&w) + move || { + let mut tick = 0; + loop { + for w in &widgets { + if let Some(on_tick) = w.get::() { + on_tick.call(&w, &TickEvent(tick)) + } } + tick += 1; + std::thread::sleep(std::time::Duration::from_millis(rate_dur)); } - std::thread::sleep(std::time::Duration::from_millis(rate_dur)); } }); } } -component!(OnTick(pub Handler)); +event!(TickEvent(pub u32)); diff --git a/src/macros.rs b/src/macros.rs index f415f18..9d29000 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -4,7 +4,7 @@ macro_rules! event { #[derive(Debug, Clone)] pub struct $name; - impl $crate::events::Event for $name { + impl $crate::extensions::Event for $name { fn as_any(&self) -> &dyn std::any::Any { self } @@ -17,7 +17,7 @@ macro_rules! event { $($inner)* } - impl $crate::events::Event for $name { + impl $crate::extensions::Event for $name { fn as_any(&self) -> &dyn std::any::Any { self } @@ -28,7 +28,7 @@ macro_rules! event { #[derive(Debug, Clone)] pub struct $name ($($inner)*); - impl $crate::events::Event for $name { + impl $crate::extensions::Event for $name { fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/src/main.rs b/src/main.rs index 66b91cf..079ea15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ use osui::{ extensions::{ id::{Id, IdExtension}, - tick::{OnTick, TickExtension}, + tick::{TickEvent, TickExtension}, Handler, }, + style::Transform, Screen, }; @@ -15,7 +16,11 @@ fn main() { screen .draw(format!("Hello, World!")) - .component(OnTick(Handler::new(move |_| {}))) + .component(Handler::new(move |w, e: &TickEvent| { + if e.0 == 30 { + w.set_component(Transform::center()); + } + })) .component(Id(69)); screen.run().unwrap();