commit 9531a1a5d8171af78cb08cd4d0ae68f3429003ff Author: Greg Date: Wed Oct 17 18:21:25 2018 -0400 Initial commit. diff --git a/main.go b/main.go new file mode 100644 index 0000000..805e81b --- /dev/null +++ b/main.go @@ -0,0 +1,60 @@ +package state + +import ( + //"fmt" + "sync" +) + +type StateMachine struct { + arc map[[2]string]func() + State chan string + cur string + mux sync.Mutex +} + +func (s *StateMachine) Arc(a,b string,fs ...func()) { + var f func() + if len(fs) == 0 { + f = func() {} + } else { + f = fs[0] + } + s.mux.Lock() + s.arc[[2]string{a,b}] = f + s.mux.Unlock() +} + +func (s *StateMachine) Cur() string { + s.mux.Lock() + defer s.mux.Unlock() + return s.cur +} + +func (s *StateMachine) run() { + laststate := s.cur + for { + x := <-s.State + if f,ok := s.arc[[2]string{"",x}]; ok { + f() + } + if f,ok := s.arc[[2]string{laststate,""}]; ok { + f() + } + if f,ok := s.arc[[2]string{s.cur,x}]; ok { + f() + } + s.mux.Lock() + laststate = s.cur + s.cur = x + s.mux.Unlock() + } +} + +func NewStateMachine(s string) *StateMachine { + ret := &StateMachine{cur: s} + ret.arc = make(map[[2]string]func()) + ret.State = make(chan string) + go ret.run() + return(ret) +} + diff --git a/test/main.go b/test/main.go new file mode 100644 index 0000000..34c2ceb --- /dev/null +++ b/test/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "gitlab.wow.st/gmp/tile/state" +) + +type Thing struct { + *state.StateMachine + val int +} + +func main() { + fmt.Println("Creating state machine.") + s := state.NewStateMachine("Start") + + s.Arc("Start", "Thinking", func() {fmt.Println("Starting to Think")}) + s.Arc("Thinking", "Start") + s.Arc("Thinking", "Done", func() {fmt.Println("Going to Done")}) + + fmt.Println("Sending Done") + s.State <-"Thinking" + s.State <-"Start" + s.State <-"Thinking" + s.State <-"Done" + fmt.Println("Finished.") + + t := &Thing{} + t.StateMachine = state.NewStateMachine("Start") + t.Arc("Start","End",func() {fmt.Println("Hi!")}) + t.State <- "End" +} +