matchmaker/render/
dynamic.rs

1use std::fmt;
2
3use super::MMState;
4use crate::{
5    SSS, Selection,
6    message::{Event, Interrupt},
7    render::Effects,
8};
9
10// note: beware that same handler could be called multiple times for the same event in one iteration
11// We choose not to return a Option<Result<S, E>> to simplify defining handlers, but will rather expose some mechanisms on state later on if a use case arises
12pub type DynamicMethod<T, S, E> = Box<dyn Fn(&mut MMState<'_, T, S>, &E) -> Effects + Send + Sync>;
13pub type DynamicHandlers<T, S> = (EventHandlers<T, S>, InterruptHandlers<T, S>);
14
15#[allow(clippy::type_complexity)]
16pub struct EventHandlers<T: SSS, S: Selection> {
17    handlers: Vec<(Vec<Event>, DynamicMethod<T, S, Event>)>,
18}
19
20#[allow(clippy::type_complexity)]
21pub struct InterruptHandlers<T: SSS, S: Selection> {
22    handlers: Vec<(Interrupt, Vec<DynamicMethod<T, S, Interrupt>>)>,
23}
24
25impl<T: SSS, S: Selection> Default for EventHandlers<T, S> {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31impl<T: SSS, S: Selection> EventHandlers<T, S> {
32    pub fn new() -> Self {
33        Self { handlers: vec![] }
34    }
35
36    pub fn set(&mut self, events: Vec<Event>, handler: DynamicMethod<T, S, Event>) {
37        self.handlers.push((events, handler));
38    }
39
40    pub fn get(&self, event: &Event) -> impl Iterator<Item = &DynamicMethod<T, S, Event>> {
41        self.handlers
42            .iter()
43            .filter(move |(events, _)| events.contains(event))
44            .map(|(_, handler)| handler)
45    }
46}
47
48impl<T: SSS, S: Selection> Default for InterruptHandlers<T, S> {
49    fn default() -> Self {
50        Self::new()
51    }
52}
53
54impl<T: SSS, S: Selection> InterruptHandlers<T, S> {
55    pub fn new() -> Self {
56        Self { handlers: vec![] }
57    }
58
59    pub fn set(&mut self, variant: Interrupt, handler: DynamicMethod<T, S, Interrupt>) {
60        if let Some((_, handlers)) = self.handlers.iter_mut().find(|(v, _)| *v == variant) {
61            handlers.push(handler);
62        } else {
63            self.handlers.push((variant, vec![handler]));
64        }
65    }
66
67    pub fn get(
68        &self,
69        variant: &Interrupt,
70    ) -> impl Iterator<Item = &DynamicMethod<T, S, Interrupt>> {
71        self.handlers
72            .iter()
73            .filter_map(move |(v, h)| (v == variant).then_some(h))
74            .flatten()
75    }
76}
77
78// -------------------------------BOILERPLATE----------------------------------
79
80impl<T: SSS, S: Selection> fmt::Debug for EventHandlers<T, S> {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        f.debug_struct("EventHandlers")
83            .field("handler_count", &self.handlers.len())
84            .finish()
85    }
86}
87
88impl<T: SSS, S: Selection> fmt::Debug for InterruptHandlers<T, S> {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        f.debug_struct("InterruptHandlers")
91            .field("variant_count", &self.handlers.len())
92            .finish()
93    }
94}