首页
关于
使用TypeScript语言编写状态机
2020-01-10 13:35:01 | 分类:
TypeScript
 | 标签:
TypeScript 状态机 ts

状态机,在程序员方面,常用于多种状态和多种事件下,优化程序的美观可读性。

否则可能会频繁使用 if else 等判断语句,使得代码杂乱。

具体描述可访问:https://www.jianshu.com/p/403f750e1d3a

 

状态机类编写,可直接复制使用。

export default class FSM {

 

    /**上个状态 */

    private _curState: number;

    /**下个状态 */

    private _preState: number;

    //[state]=>callback

    private _stateMap: {[state: number]:(...args)=>any};

    //[event][fromState]=>toState

    private _eventMap: {[event: number]: {[fromState: number]: number}};

 

    constructor(defaultState: number){

        this._stateMap = {};

        this._eventMap = {};

        this._curState = this._preState = defaultState;

    }

 

    /**增加状态回调 */

    public addState(state: number, callback: (...args)=>any){

        if (this.isContainState(state)){

            console.log("error", "FSM 重复addState state" + state);

            return ;

        }

        this._stateMap[state] = callback;

    }

 

    public setState(state: number, callback: (...args)=>any){

        this._stateMap[state] = callback;

    }

 

    /**增加事件,事件发生后,从fromState状态变为toState状态 */

    public addEvent(event: number, fromState: number, toState: number){

        if (!this.isContainState(fromState)){

            console.log("error", "FSM addEvent 不存在state from" + fromState);

            return;

        }

        if (!this.isContainState(toState)){

            console.log("error", "FSM addEvent 不存在state to" + fromState);

            return;

        }

        if (this._eventMap[event] == null){

            this._eventMap[event] = {};

        }

        this._eventMap[event][fromState] = toState;

    }

 

    /**执行事件 */

    public doEvent(event: number, ...args){

        if (this.canDoEvent(event)){

            return this.changeToState(this._eventMap[event][this._curState], ...args);

        }

    }

 

    private canDoEvent(event: number){

        return this._eventMap[event] != null && this._eventMap[event][this._curState] != null;

    }

 

    public isContainState(state: number): boolean{

        return this._stateMap[state] != null;

    }

 

    private changeToState(state: number, ...args): any{

        if (!this.isContainState(state)){

            console.log("error", "FSM changeToState 不存在state: " + state);

            return ;

        }

        this._preState = this._curState;

        this._curState = state;

        return this._stateMap[state](...args);

    }

 

    /**获得当前状态 */

    public getCurState(): number{

        return this._curState;

    }

 

   /**获取上次状态 */

    public getPreState(): number{

        return this._preState;

    }

}

-----------------------------使用的例子-------------------------------

/**事件 */

export const enum FSMEvent{

    /**起床 */

    GET_UP,

    /**步行 */

    WALK,

    /**回房间 */

    BACK_ROOM,

}

 

/**状态 */

export const enum FSMState{

    NONE,

    /**准备上班 */

    PREPARING,

    /**工作中 */

    WORKING,

    /**回家 */

    COME_BACK_HOME,

    /**睡觉中 */

    SLEEPING,

}

 

//初始为睡觉状态

let fsm = new FSM(FSMState.SLEEPING);

//增加当前状态需要干的事情

fsm.addState(FSMState.PREPARING, () => {

    console.log("刷牙洗脸。");

    //步行去上班

    fsm.doEvent(FSMEvent.WALK);

});

fsm.addState(FSMState.WORKING, () => {

    console.log("8个小时过去了,也该下班了。");

    //步行回家

    fsm.doEvent(FSMEvent.WALK);

});

fsm.addState(FSMState.COME_BACK_HOME, () => {

    console.log("回到家了,在家里看电视。");

    //回房间

    fsm.doEvent(FSMEvent.BACK_ROOM);

});

fsm.addState(FSMState.SLEEPING, () => {

    console.log("在房间睡觉。");

    //起床

    fsm.doEvent(FSMEvent.GET_UP);

});

//增加事件,起床事件 睡觉中状态 => 准备上班

fsm.addEvent(FSMEvent.GET_UP, FSMState.SLEEPING, FSMState.PREPARING);

//增加事件,步行事件 准备上班 => 工作中

fsm.addEvent(FSMEvent.WALK, FSMState.PREPARING, FSMState.WORKING);

//增加事件,步行事件 工作中 => 回家

fsm.addEvent(FSMEvent.WALK, FSMState.WORKING, FSMState.COME_BACK_HOME);

//增加事件,回房间事件 回家 => 睡觉中

fsm.addEvent(FSMEvent.BACK_ROOM, FSMState.COME_BACK_HOME, FSMState.SLEEPING);

/**

* 整个事件流程:

 * 睡觉中 => 起床 => 准备上班 => 步行 => 工作中 => 步行 => 回家 => 回房间 => 睡觉中

 */

 

友情链接: 我写的技术解决方案

© 2020 wuyouteam.work 粤ICP备20033754号-1