Go fsm
package fsm import ( "log" ) type EvtIf interface { GetEvtType() string } type Action interface { //doAction(evt EvtIf, srcState *State, dstState *State) doAction(evt EvtIf) } type Transition struct { dstState *State action Action } type State struct { name string isEnd bool transitionTbl map[string]Transition } type fsm struct { InstId uint64 version uint32 startPoint *State current *State transitionLog []Transition stateTbl map[string]*State } //func StartStateMachine(transtionLog []Transition) *fsm { //} //func ReplyStateMachine(transtionLog []Transition) *fsm { //} //func Save() *fsm { //} //func Load() *fms { //} func NewState(name string, end bool) *State { return &State{name, end, map[string]Transition{}} } func (this *State) GetName() string { return this.name } func (this *State) InterestInEvt(evt EvtIf) bool { if evt == nil { return false } _, exists := this.transitionTbl[evt.GetEvtType()] return exists } func (this *State) AddTransition(evt EvtIf, dst *State, action Action) { if evt == nil || dst == nil || action == nil { log.Fatal("AddTransition error, parameter invalid!") } _, exists := this.transitionTbl[evt.GetEvtType()] if exists { log.Fatal("AddTransition error,EvtIf exist") } this.transitionTbl[evt.GetEvtType()] = NewTransition(dst, action) } func (this *State) GetTransition(evt EvtIf) *Transition { if evt == nil { return nil } tran, exists := this.transitionTbl[evt.GetEvtType()] if exists == false { log.Fatal("GetTransition error,EvtIf doesn't exist") } return &tran } func NewTransition(dstState *State, action Action) Transition { return Transition{dstState, action} } func (this *fsm) RegisterState(state *State) { if state == nil { log.Fatal("RegisterState error, parameter invalid!") } _, exists := this.stateTbl[state.GetName()] if exists { return log.Fatal("RegisterState error,State exist") } this.stateTbl[state.GetName()] = state } func (this *fsm) AddTransition(srcState *State, evt EvtIf, dstState *State, action Action) { if srcState == nil || dstState == nil || evt == nil || action == nil { log.Fatal("AddTransition error, parameter invalid!") } this.RegisterState(srcState) this.RegisterState(dstState) srcState.AddTransition(evt, dstState, action) } func (this *fsm) AddInternalTransition(srcState *State, evt EvtIf, action Action) { this.AddTransition(srcState, evt, srcState, action) } func (this *fsm) HandleEvt(evt EvtIf) { if evt == nil { return } srcState := this.current if srcState.InterestInEvt(evt) { transition := srcState.GetTransition(evt) log.Printf("Handle Event, srcState:%s, dstState:%s, evt:%s", srcState.GetName(), transition.dstState.GetName(), evt.GetEvtType()) //transition.action.doAction(evt, srcState, transition.dstState) transition.action.doAction(evt) this.current = transition.dstState } else { log.Printf("parameter invalid, srcState:%s, evt:%s", srcState.GetName(), evt.GetEvtType()) } } func NewFsm(initialState *State) *fsm { if initialState == nil { log.Fatal("NewFsm error, parameter invalid!") } return &fsm{initialState, map[string]*State{}} }