event system!!!
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user