use std::rc::Rc;
use inset_foundation::{App, Handle};
use crate::events::PointerEvent;
pub type PointerSignalResolvedCallback = Rc<dyn Fn(&mut App, &PointerEvent)>;
#[derive(Default)]
pub struct PointerSignalResolver {
first_registered_callback: Option<PointerSignalResolvedCallback>,
current_event: Option<PointerEvent>,
}
impl PointerSignalResolver {
pub fn new(app: &mut App) -> Handle<PointerSignalResolver> {
app.create(PointerSignalResolver::default())
}
pub fn register(
self: Handle<Self>,
app: &mut App,
event: &PointerEvent,
callback: PointerSignalResolvedCallback,
) {
let resolver = app.get_mut(self);
if resolver.first_registered_callback.is_some() {
return;
}
resolver.current_event = Some(event.clone());
resolver.first_registered_callback = Some(callback);
}
pub fn resolve(self: Handle<Self>, app: &mut App) {
let resolver = app.get_mut(self);
let Some(callback) = resolver.first_registered_callback.take() else {
debug_assert!(resolver.current_event.is_none());
return;
};
let event = resolver
.current_event
.take()
.expect("a registered callback carries its event");
callback(app, &event);
}
}
#[cfg(test)]
mod tests {
use inset_foundation::AppCell;
use std::cell::RefCell;
use crate::events::PointerScrollEvent;
use super::*;
#[test]
fn only_the_first_registered_callback_runs() {
let cell = AppCell::new();
let mut app = cell.borrow_mut();
let resolver = PointerSignalResolver::new(&mut app);
let event = PointerEvent::Scroll(PointerScrollEvent::default());
let called = Rc::new(RefCell::new(Vec::<&'static str>::new()));
let first = called.clone();
resolver.register(
&mut app,
&event,
Rc::new(move |_app, _event| first.borrow_mut().push("first")),
);
let second = called.clone();
resolver.register(
&mut app,
&event,
Rc::new(move |_app, _event| second.borrow_mut().push("second")),
);
resolver.resolve(&mut app);
assert_eq!(*called.borrow(), vec!["first"]);
let third = called.clone();
resolver.register(
&mut app,
&event,
Rc::new(move |_app, _event| third.borrow_mut().push("third")),
);
resolver.resolve(&mut app);
assert_eq!(*called.borrow(), vec!["first", "third"]);
}
#[test]
fn resolving_without_a_registration_does_nothing() {
let cell = AppCell::new();
let mut app = cell.borrow_mut();
let resolver = PointerSignalResolver::new(&mut app);
resolver.resolve(&mut app);
}
}