zoukankan      html  css  js  c++  java
  • 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{}}
    }
  • 相关阅读:
    Fix Installing .NET Framework 3.5 failed Error Code 0x800F0954 on Windows 10
    RHEL8安装五笔输入法
    Enable EPEL and Local Repository on RHEL8
    Why is Yum Replaced by DNF?
    检查Linux服务器是否被攻击的常用命令及方法
    IDEA 主题
    IDEA 如何显示一个类中所有的方法
    Appium 安装以及安装过程中遇到的问题
    Maven 如何发布 jar 包到 Nexus 私库
    java泛型的基本使用
  • 原文地址:https://www.cnblogs.com/diegodu/p/5113737.html
Copyright © 2011-2022 走看看