67 lines
1.4 KiB
V
67 lines
1.4 KiB
V
module statemachine
|
|
|
|
pub type EventHandlerFn = fn (receiver voidptr)
|
|
|
|
pub type ConditionFn = fn (receiver voidptr) bool
|
|
|
|
struct State {
|
|
mut:
|
|
entry_handler EventHandlerFn
|
|
run_handler EventHandlerFn
|
|
exit_handler EventHandlerFn
|
|
}
|
|
|
|
struct Transition {
|
|
mut:
|
|
to string
|
|
condition ConditionFn
|
|
}
|
|
|
|
struct StateMachine {
|
|
mut:
|
|
states map[string]State
|
|
transitions map[string]Transition
|
|
current_state string
|
|
}
|
|
|
|
pub fn new() &StateMachine {
|
|
return &StateMachine{}
|
|
}
|
|
|
|
pub fn (mut s StateMachine) add_state(name string, entry EventHandlerFn, run EventHandlerFn, exit EventHandlerFn) {
|
|
s.states[name] = State{
|
|
entry_handler: entry
|
|
run_handler: run
|
|
exit_handler: exit
|
|
}
|
|
if s.states.len == 1 {
|
|
s.current_state = name
|
|
}
|
|
}
|
|
|
|
pub fn (mut s StateMachine) add_transition(from string, to string, condition ConditionFn) {
|
|
s.transitions[from] = Transition{
|
|
to: to
|
|
condition: condition
|
|
}
|
|
}
|
|
|
|
pub fn (mut s StateMachine) run(receiver voidptr) {
|
|
for from_state, transition in s.transitions {
|
|
if from_state == s.current_state {
|
|
if transition.condition(receiver) {
|
|
s.change_state(receiver, s.transitions[from_state].to)
|
|
}
|
|
s.states[s.current_state].run_handler(receiver)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn (mut s StateMachine) change_state(receiver voidptr, newstate string) {
|
|
mut current_state := s.current_state
|
|
s.states[current_state].exit_handler(receiver)
|
|
current_state = newstate
|
|
s.states[current_state].entry_handler(receiver)
|
|
s.current_state = current_state
|
|
}
|