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) }