diff options
Diffstat (limited to 'src/state.go')
-rw-r--r-- | src/state.go | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/src/state.go b/src/state.go index 9a08738..5970ba8 100644 --- a/src/state.go +++ b/src/state.go @@ -7,6 +7,7 @@ import ( "time" ) +// This struct represents the statemachine. type Machine struct { name string initial string @@ -28,6 +29,16 @@ type MachineTransition struct { to string } +// This will run the statemachine (blocking). +func (m *Machine) Run() { + var event string + for { + event = <-m.api // read api (blocking) + m.processEvent(event) + } +} + +// A simple Getter to retrieve the current state. func (m Machine) GetState() string { if m.current == "" { return m.initial @@ -35,10 +46,14 @@ func (m Machine) GetState() string { return m.current } +// This function blocks until the current state differs +// from the 'known' state. It then returns the current +// state. func (m *Machine) GetStateOnChange(known string) string { listener := make(chan string) var current string - m.RegisterListener(&listener) + m.registerListener(&listener) + defer m.deregisterListener(&listener) for { if m.GetState() != known { current = m.GetState() @@ -49,15 +64,19 @@ func (m *Machine) GetStateOnChange(known string) string { break } } - m.DeregisterListener(&listener) return current } -func (m *Machine) RegisterListener(listener *(chan string)) { +// Use this function to send an event to the statemachine. +func (m *Machine) SendEvent(event string) { + m.api <- event // blocks until m.run() goroutine handles this event +} + +func (m *Machine) registerListener(listener *(chan string)) { m.state_listeners = append(m.state_listeners, listener) } -func (m *Machine) DeregisterListener(listener *(chan string)) { +func (m *Machine) deregisterListener(listener *(chan string)) { wasRemoved := false if len(m.state_listeners) == 0 { log.Println("Not able to unregister listener from empty state_listener slice") @@ -90,25 +109,13 @@ func (m *Machine) processEvent(event string) string { 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) - } -} - +// In this function one can implement callback functions +// which will be triggered on certain transitions. func (m *Machine) runHooks(last string, next string) { - log.Println("Send state to listeners ...") for _,listener := range(m.state_listeners) { *listener <- next } - log.Println("State sent to listeners") if last == "idle" && next == "single_picture" { // TODO implement launch of python subprocess here @@ -118,29 +125,3 @@ func (m *Machine) runHooks(last string, next string) { }() } } - -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), - state_listeners: make([]*(chan string), 0), - } -} - |