diff options
author | xengineering <mail2xengineering@protonmail.com> | 2021-06-13 12:54:28 +0200 |
---|---|---|
committer | xengineering <mail2xengineering@protonmail.com> | 2021-06-13 13:01:26 +0200 |
commit | 9d5a2f9870e52bfc0fe6db8c27981f29d91dcb55 (patch) | |
tree | e3856fbbd1bc7c429472d950e7f1d46e5cf2fae3 /src/state.go | |
parent | c015034ba2e0bfd8464ae444792552a4b354eb0d (diff) | |
download | birdscan-9d5a2f9870e52bfc0fe6db8c27981f29d91dcb55.tar birdscan-9d5a2f9870e52bfc0fe6db8c27981f29d91dcb55.tar.zst birdscan-9d5a2f9870e52bfc0fe6db8c27981f29d91dcb55.zip |
Implement working State Machine
Diffstat (limited to 'src/state.go')
-rw-r--r-- | src/state.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/state.go b/src/state.go new file mode 100644 index 0000000..9c6ab66 --- /dev/null +++ b/src/state.go @@ -0,0 +1,94 @@ +// vim: shiftwidth=4 tabstop=4 noexpandtab + +package main + +import ( + "log" + "time" +) + +type Machine struct { + name string + initial string + current string + states StateMap + api chan string +} + +type StateMap map[string]MachineState + +type MachineState struct { + on TransitionMap +} + +type TransitionMap map[string]MachineTransition + +type MachineTransition struct { + to string +} + +func (m Machine) GetState() string { + if m.current == "" { + return m.initial + } + return m.current +} + +func (m *Machine) processEvent(event string) string { + current := m.GetState() + next := m.states[current].on[event].to + if next != "" { + log.Printf("State machine '%s' changes from '%s' to '%s'\n", m.name, current, next) + m.current = next + m.runHooks(current, next) + return next + } + return current +} + +func (m *Machine) SendEvent(event string) { + m.api <- event // blocks until m.run() goroutine handles this event +} + +func (m *Machine) run() { + var event string + for { + event = <-m.api // read api (blocking) + m.processEvent(event) + } +} + +func (m *Machine) runHooks(last string, next string) { + if next == "single_picture" { + // TODO implement launch of python subprocess here + go func() { + time.Sleep(1 * time.Second) + m.SendEvent("single_picture_taken") + }() + } +} + +func newCamStateMachine() Machine { + return Machine{ + name: "camera", + initial: "idle", + states: StateMap{ + "idle": MachineState{ + on: TransitionMap{ + "take_single_picture": MachineTransition{ + to: "single_picture", + }, + }, + }, + "single_picture": MachineState{ + on: TransitionMap{ + "single_picture_taken": MachineTransition{ + to: "idle", + }, + }, + }, + }, + api: make(chan string), + } +} + |