summaryrefslogtreecommitdiff
path: root/src/state.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.go')
-rw-r--r--src/state.go69
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),
- }
-}
-