better handlers

This commit is contained in:
2025-07-05 06:48:21 +02:00
parent 661756eccd
commit cec25c02d5
4 changed files with 62 additions and 20 deletions
+40 -8
View File
@@ -3,27 +3,59 @@ pub mod tick;
pub mod velocity; pub mod velocity;
use std::{ use std::{
any::{Any, TypeId},
fmt::Debug, fmt::Debug,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use crate::{render_scope::RenderScope, widget::Widget}; use crate::{
render_scope::RenderScope,
widget::{Component, Widget},
};
pub trait Extension { pub trait Extension {
fn init(&mut self, _widgets: &Vec<Arc<Widget>>) {} fn init(&mut self, _widgets: &Vec<Arc<Widget>>) {}
fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc<Widget>) {} fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc<Widget>) {}
} }
#[derive(Clone)] pub trait Event: Send + Sync {
pub struct Handler(pub Arc<Mutex<dyn FnMut(&Arc<Widget>) + Send + Sync>>); fn as_any(&self) -> &dyn Any;
}
impl Handler { #[derive(Clone)]
pub fn new<F: FnMut(&Arc<Widget>) + Send + Sync + 'static>(f: F) -> Handler { pub struct Handler(
Handler(Arc::new(Mutex::new(f))) Arc<Mutex<dyn FnMut(&Arc<Widget>, &dyn Event) + Send + Sync>>,
TypeId,
);
impl Component for Handler {
fn as_any(&self) -> &dyn Any {
self
} }
pub fn call(&self, w: &Arc<Widget>) { fn as_any_mut(&mut self) -> &mut dyn Any {
(self.0.lock().unwrap())(w) self
}
}
impl Handler {
pub fn new<E: Event + 'static, F: FnMut(&Arc<Widget>, &E) + Send + Sync + 'static>(
mut f: F,
) -> Handler {
Handler(
Arc::new(Mutex::new(move |w: &Arc<Widget>, e: &dyn Event| {
if let Some(e) = e.as_any().downcast_ref::<E>() {
f(w, e)
}
})),
TypeId::of::<E>(),
)
}
pub fn call<E: Event>(&self, w: &Arc<Widget>, e: &E) {
if e.as_any().type_id() == self.1 {
(self.0.lock().unwrap())(w, e)
}
} }
} }
+10 -5
View File
@@ -1,7 +1,8 @@
use std::{fmt::Debug, sync::Arc}; use std::{fmt::Debug, sync::Arc};
use crate::event;
use crate::extensions::Handler; use crate::extensions::Handler;
use crate::{component, extensions::Extension, widget::Widget}; use crate::{extensions::Extension, widget::Widget};
pub struct TickExtension(pub u16); pub struct TickExtension(pub u16);
@@ -10,16 +11,20 @@ impl Extension for TickExtension {
let rate_dur = 1000 / self.0 as u64; let rate_dur = 1000 / self.0 as u64;
std::thread::spawn({ std::thread::spawn({
let widgets = widgets.clone(); let widgets = widgets.clone();
move || loop { move || {
let mut tick = 0;
loop {
for w in &widgets { for w in &widgets {
if let Some(on_tick) = w.get::<OnTick>() { if let Some(on_tick) = w.get::<Handler>() {
on_tick.0.call(&w) 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));
+3 -3
View File
@@ -4,7 +4,7 @@ macro_rules! event {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct $name; pub struct $name;
impl $crate::events::Event for $name { impl $crate::extensions::Event for $name {
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
@@ -17,7 +17,7 @@ macro_rules! event {
$($inner)* $($inner)*
} }
impl $crate::events::Event for $name { impl $crate::extensions::Event for $name {
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
@@ -28,7 +28,7 @@ macro_rules! event {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct $name ($($inner)*); pub struct $name ($($inner)*);
impl $crate::events::Event for $name { impl $crate::extensions::Event for $name {
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
} }
+7 -2
View File
@@ -1,9 +1,10 @@
use osui::{ use osui::{
extensions::{ extensions::{
id::{Id, IdExtension}, id::{Id, IdExtension},
tick::{OnTick, TickExtension}, tick::{TickEvent, TickExtension},
Handler, Handler,
}, },
style::Transform,
Screen, Screen,
}; };
@@ -15,7 +16,11 @@ fn main() {
screen screen
.draw(format!("Hello, World!")) .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)); .component(Id(69));
screen.run().unwrap(); screen.run().unwrap();