1use std::{collections::VecDeque, marker::PhantomData};
2
3use crate::{AnyAction, Callback, EnablingCondition};
4
5pub struct Dispatcher<Action, State> {
6 queue: VecDeque<Action>,
7 _marker: PhantomData<State>,
8}
9
10impl<Action, State> Default for Dispatcher<Action, State>
11where
12 Action: crate::EnablingCondition<State>,
13{
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl<Action, State> Dispatcher<Action, State>
20where
21 Action: crate::EnablingCondition<State>,
22{
23 pub fn new() -> Self {
24 Self {
25 queue: VecDeque::new(),
26 _marker: Default::default(),
27 }
28 }
29
30 pub fn push<T>(&mut self, action: T)
31 where
32 T: Into<Action>,
33 {
34 self.queue.push_back(action.into());
35 }
36
37 pub fn push_if_enabled<T>(&mut self, action: T, state: &State, time: crate::Timestamp) -> bool
38 where
39 T: Into<Action> + EnablingCondition<State>,
40 {
41 if action.is_enabled(state, time) {
42 self.queue.push_back(action.into());
43 true
44 } else {
45 false
46 }
47 }
48
49 pub fn push_callback<T>(&mut self, callback: Callback<T>, args: T)
50 where
51 T: 'static,
52 Action: From<AnyAction>,
53 {
54 let action: Action = callback.call(args);
55 self.queue.push_back(action);
56 }
57
58 pub(crate) fn pop(&mut self) -> Option<Action> {
59 self.queue.pop_front()
60 }
61}