fluent_fsm/machine/
builder.rs1use crate::active::ActiveStateMachine;
24use crate::machine::passive::PassiveStateMachine;
25use std::hash::Hash;
26
27pub struct StateMachineBuilder<TState: Eq + Hash + Copy, TModel = (), TEvent: Eq + Hash + Copy = ()>
28{
29 working_on_state: TState,
30 working_on_event: Option<TEvent>,
31 current_state_machine: PassiveStateMachine<TState, TModel, TEvent>,
32}
33
34impl<TState, TModel, TEvent> StateMachineBuilder<TState, TModel, TEvent>
35where
36 TState: Eq + Hash + Copy + Sync + Send + 'static,
37 TModel: Sync + Send + 'static,
38 TEvent: Eq + Hash + Copy + Sync + Send + 'static,
39{
40 pub fn create(initial_state: TState, initial_model: TModel) -> Self {
42 Self {
43 working_on_state: initial_state,
44 working_on_event: None,
45 current_state_machine: PassiveStateMachine::new(initial_state, initial_model),
46 }
47 }
48
49 pub fn in_state(self, state: TState) -> Self {
51 Self {
52 working_on_state: state,
53 working_on_event: None,
54 ..self
55 }
56 }
57
58 pub fn on_enter(self, func: impl Fn() + 'static + Sync + Send) -> Self {
59 let mut builder = self;
60 let machine = &mut builder.current_state_machine;
61 machine.add_enter_handler(builder.working_on_state, move |_: &mut TModel| func());
62 builder
63 }
64
65 pub fn on_enter_mut(self, func: impl Fn(&mut TModel) + 'static + Sync + Send) -> Self {
67 let mut builder = self;
68
69 let machine = &mut builder.current_state_machine;
70
71 machine.add_enter_handler(builder.working_on_state, func);
72
73 builder
74 }
75
76 pub fn on_leave(self, func: impl Fn() + 'static + Sync + Send) -> Self {
77 let wrapper = move |_: &mut TModel| func();
78 self.on_leave_mut(wrapper)
79 }
80
81 pub fn on_leave_mut(self, func: impl Fn(&mut TModel) + 'static + Sync + Send) -> Self {
83 let mut builder = self;
84
85 let machine = &mut builder.current_state_machine;
86
87 machine.add_leave_handler(builder.working_on_state, func);
88 builder
89 }
90
91 pub fn on(self, event: TEvent, func: impl Fn() + 'static + Sync + Send) -> Self {
92 let wrapper = move |_: &mut TModel| func();
93 self.on_mut(event, wrapper)
94 }
95
96 pub fn on_mut(self, event: TEvent, func: impl Fn(&mut TModel) + 'static + Sync + Send) -> Self {
98 let mut builder = self;
99 builder.working_on_event = Some(event);
100
101 let machine = &mut builder.current_state_machine;
102
103 machine.add_event_handler(builder.working_on_state, event, func);
104
105 builder
106 }
107
108 pub fn goto(self, state: TState) -> Self {
111 let mut builder = self;
112
113 match builder.working_on_event {
114 Some(e) => {
115 builder
116 .current_state_machine
117 .add_transition(e, builder.working_on_state, state);
118 builder.working_on_event = None;
119 }
120 None => {
121 panic!("Can't add a transition before an event is in scope with on()")
122 }
123 }
124
125 builder
126 }
127
128 pub fn build_passive(self) -> PassiveStateMachine<TState, TModel, TEvent> {
130 self.current_state_machine
131 }
132
133 pub fn build_active(
135 self,
136 tick: impl Fn(&TState, &TModel) -> Option<TState> + Send + Sync + 'static,
137 ) -> ActiveStateMachine<TState, TModel, TEvent> {
138 ActiveStateMachine::create(tick, self.current_state_machine)
139 }
140}