Skip to main content

matchmaker/render/
dynamic.rs

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