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