From 591097e5a3741432e2acd9c41fadd4eb10678674 Mon Sep 17 00:00:00 2001
From: xengineering <mail2xengineering@protonmail.com>
Date: Tue, 15 Jun 2021 16:44:15 +0200
Subject: Refactoring: Make Statemachine reusable

---
 src/camera.go | 16 ++++++++++++++++
 src/state.go  | 33 ++++++++++++---------------------
 2 files changed, 28 insertions(+), 21 deletions(-)

(limited to 'src')

diff --git a/src/camera.go b/src/camera.go
index 12a9d54..197aa21 100644
--- a/src/camera.go
+++ b/src/camera.go
@@ -2,6 +2,10 @@
 
 package main
 
+import (
+	"time"
+)
+
 type Camera struct {
 	statemachine Machine
 }
@@ -29,10 +33,22 @@ func NewCamera() Camera {
 			},
 			api: make(chan string),
 			state_listeners: make([]*(chan string), 0),
+			hook: runCameraHooks,
 		},
 	}
 }
 
+func runCameraHooks(last string, next string) {
+
+	if last == "idle" && next == "single_picture" {
+		// TODO implement launch of python subprocess here
+		go func() {
+			time.Sleep(1 * time.Second)
+			camera.statemachine.SendEvent("single_picture_taken")
+		}()
+	}
+}
+
 func (cam *Camera) run() {
 	cam.statemachine.Run()
 }
diff --git a/src/state.go b/src/state.go
index 5970ba8..10c35ef 100644
--- a/src/state.go
+++ b/src/state.go
@@ -4,7 +4,6 @@ package main
 
 import (
 	"log"
-	"time"
 )
 
 // This struct represents the statemachine.
@@ -15,6 +14,7 @@ type Machine struct {
 	states StateMap
 	api chan string
 	state_listeners []*(chan string)
+	hook HookFunction
 }
 
 type StateMap map[string]MachineState
@@ -29,6 +29,8 @@ type MachineTransition struct {
 	to string
 }
 
+type HookFunction func(string, string)
+
 // This will run the statemachine (blocking).
 func (m *Machine) Run() {
 	var event string
@@ -100,28 +102,17 @@ func (m *Machine) deregisterListener(listener *(chan string)) {
 func (m *Machine) processEvent(event string) string {
 	current := m.GetState()
 	next := m.states[current].on[event].to
-	if next != "" {
+	if next != "" {  // check if transition is possible
 		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
-}
 
-// In this function one can implement callback functions
-// which will be triggered on certain transitions.
-func (m *Machine) runHooks(last string, next string) {
-
-	for _,listener := range(m.state_listeners) {
-		*listener <- next
-	}
+		// inform all state listeners
+		for _,listener := range(m.state_listeners) {
+			*listener <- next
+		}
 
-	if last == "idle" && next == "single_picture" {
-		// TODO implement launch of python subprocess here
-		go func() {
-			time.Sleep(1 * time.Second)
-			m.SendEvent("single_picture_taken")
-		}()
+		m.hook(current, next)  // execute registered callback function
+		m.current = next  // set new state
+		return next
 	}
+	return current
 }
-- 
cgit v1.2.3-70-g09d2