event system!!!

This commit is contained in:
2025-09-25 12:37:06 -04:00
parent 4deeabe611
commit 21f15fb9c5
7 changed files with 255 additions and 50 deletions

View File

@@ -1,6 +1,9 @@
use crate::prelude::*;
use std::ops::{BitOr, Deref, DerefMut};
use std::{
ops::{BitOr, Deref, DerefMut},
rc::Rc,
};
use crate::{
layout::{UiModule, UiRegion, Vec2},
@@ -11,12 +14,14 @@ pub trait CursorCtx {
fn cursor_state(&self) -> &CursorState;
}
#[derive(PartialEq)]
pub enum Button {
Left,
Right,
Middle,
}
#[derive(PartialEq)]
pub enum Sense {
PressStart(Button),
Pressing(Button),
@@ -78,7 +83,7 @@ pub enum ActivationState {
pub struct Sensor<Ctx> {
pub senses: Senses,
pub f: Box<dyn SenseFn<Ctx>>,
pub f: Rc<dyn SenseFn<Ctx>>,
}
pub type SensorMap<Ctx> = HashMap<Id, SensorGroup<Ctx>>;
@@ -88,13 +93,14 @@ pub struct SensorGroup<Ctx> {
pub sensors: Vec<Sensor<Ctx>>,
}
#[derive(Clone)]
pub struct SenseData {
pub cursor: Vec2,
pub size: Vec2,
}
pub trait SenseFn<Ctx>: FnMut(&mut Ctx, SenseData) + 'static {}
impl<F: FnMut(&mut Ctx, SenseData) + 'static, Ctx> SenseFn<Ctx> for F {}
pub trait SenseFn<Ctx>: Fn(&mut Ctx, SenseData) + 'static {}
impl<F: Fn(&mut Ctx, SenseData) + 'static, Ctx> SenseFn<Ctx> for F {}
pub struct SensorModule<Ctx> {
map: SensorMap<Ctx>,
@@ -242,24 +248,48 @@ impl<Ctx: 'static> Event<Ctx> for Senses {
type Data = SenseData;
}
impl<Ctx: 'static> EventModule<Ctx, Senses> for SensorModule<Ctx> {
fn register(&mut self, id: Id, senses: Senses, f: impl EventFn<Ctx, SenseData>) {
// TODO: does not add to active if currently active
self.map.entry(id).or_default().sensors.push(Sensor {
senses,
f: Box::new(f),
});
}
}
impl<Ctx: 'static> Event<Ctx> for Sense {
type Module = SensorModule<Ctx>;
type Data = SenseData;
}
impl<Ctx: 'static> EventModule<Ctx, Sense> for SensorModule<Ctx> {
fn register(&mut self, id: Id, sense: Sense, f: impl EventFn<Ctx, SenseData>) {
self.register(id, Senses::from(sense), f);
impl<E: Event<Ctx, Data = <Senses as Event<Ctx>>::Data> + Into<Senses>, Ctx: 'static>
EventModule<E, Ctx> for SensorModule<Ctx>
{
fn register(&mut self, id: Id, senses: E, f: impl EventFn<Ctx, <E as Event<Ctx>>::Data>) {
// TODO: does not add to active if currently active
self.map.entry(id).or_default().sensors.push(Sensor {
senses: senses.into(),
f: Rc::new(f),
});
}
fn run<'a>(
&mut self,
id: &Id,
event: E,
) -> Option<impl Fn(&mut Ctx, E::Data) + use<'a, E, Ctx>> {
let senses = event.into();
if let Some(group) = self.map.get_mut(id) {
let fs: Vec<_> = group
.sensors
.iter()
.filter_map(|sensor| {
if sensor.senses.iter().any(|s| senses.contains(s)) {
Some(sensor.f.clone())
} else {
None
}
})
.collect();
Some(move |ctx: &mut Ctx, data: SenseData| {
for f in &fs {
f(ctx, data.clone());
}
})
} else {
None
}
}
}