matchmaker/render/
dynamic.rs

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