From 9d5a2f9870e52bfc0fe6db8c27981f29d91dcb55 Mon Sep 17 00:00:00 2001 From: xengineering Date: Sun, 13 Jun 2021 12:54:28 +0200 Subject: Implement working State Machine --- src/state.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/state.go (limited to 'src/state.go') 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), + } +} + -- cgit v1.2.3-70-g09d2