diff options
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), + } +} + |