/// 状态机类 #ifndef RUStateMachine_h #define RUStateMachine_h #include "RUDefine.h" #include #include "RUStateDelegate.h" NS_RU_BEGIN class State; class StateTransition; #define DISPATCH_STATE_NAME "entry" //虚拟分发节点名称 #define AUTO_EVENT_NAME "自动" //状态自动触发的事件名 // 参数的类型 typedef enum { PARAM_T_INT = 1, PARAM_T_FLOAT, PARAM_T_STRING, PARAM_T_TRIGGER } FsmParamType; // 状态机的参数 typedef struct { std::string name; // 参数名称 FsmParamType type; // 参数类型 int iv; float fv; std::string sv; } FsmParameter; // 事件转移时的单个条件 typedef struct { std::string name; std::string op; std::string v; } FsmTansCondition; //状态机转换 typedef struct _FsmTransition { std::string fromState; //源状态 std::string toState; //目标状态 std::string eventName; //事件名 std::list> conditions; //转移条件,里层的list是与的关系,外层的list是或的关系 std::vector beforeSwitchActInfos; //切换状态前动作 std::vector afterSwitchActInfos; //切换状态后动作 } FsmTransition; class StateMachine : public cocos2d::Ref { public: static StateMachine* create(const std::string& stateMachineName, const std::string& initStateName, const std::unordered_map& states, const std::vector& transitions, const std::map& params); ///初始状态 virtual std::vector getInitStateNames(); /// 设置运行状态 virtual void setRunningStateName(const std::string& stateName); /// 设置运行状态(分层状态机需要往下传递) virtual void setRunningStateNames(std::vector stateNames); virtual std::vector getRunningStateNames(); virtual std::vector getHistoryRunningStateNames(); virtual void runMachine(const std::function& runningCb = nullptr); ///播放退出动画后再停止状态机 virtual void stopMachine(const std::function& stoppedCb = nullptr); ///立即停止状态机 virtual void stopMachineImmediately(); ///强制切换状态(如果当前不是运行运行态,不应该调用这个函数) virtual void forceToStateNames(const std::vector& stateNames, const std::function& forcedCb = nullptr); /// 是否能响应事件 virtual bool canResponseEvent(const std::string& eventName); /// 响应事件 virtual void handleEvent(const std::string& eventName, std::function handleEventCb = nullptr); virtual void handleEvent(const std::string& eventName, const std::map& eventParams, std::function handleEventCb = nullptr); ///获取Idle动作的配置信息 virtual const std::vector& getIdleActInfosByStateFullPath(const std::vector& stateNames); /// 设置某个参数 /// @param name 参数名 /// @param v 参数值 virtual void setParam(const std::string& name, const std::string& v); /// debug输出结构信息 virtual void debugInfo(); /// 设置状态机的名称 /// @param name 名称 void setName(const std::string& name); void setIndent4Dbg(const std::string& indent); ///调试用:运行状态机 void runMachine4Dbg(); ///调试用:根据事件直接设置物件状态,不做动画 void handleEvent4Dbg(const std::string& eventName); /// 获取State State* getState(const std::string& stateName); /** * 功能:检查指定的状态在状体机里是否存在 * 参数 stateNames:状态队列 * 返回值:状态队列的每一个状态是否能在对应的状态机响应 */ bool chekcStateNamesValidity(std::vector stateNames); private: StateMachine() = default; ~StateMachine() = default; /// 获取状态下事件的转换信息 const FsmTransition* _getFsmTransition(const std::string& formState, const std::string& eventName); /// debug日志专用 std::string _getRunningStateStr4Debug(); /// 检查该条件组是否成立 /// @param conditions 条件组 bool checkConditonGroup(const std::list& conditions); /// 判断名称是否能匹配上模式 /// @param name 名称 /// @param pattern 可能携带"*"的模式 bool isEventNameMatched(const std::string& name, const std::string& pattern); /// 在状态切换完成后的处理 /// @param handleEventCb 回调 void handleIfStateChanged(std::function handleEventCb); private: std::string _name; // 状态机本身的名字 std::string _initStateName; //初始默认状态 std::string _runningStateName; //当前运行状态 std::string _historyRunningStateName; //最后的运行状态 bool _running = false; //状态机是否在运行中 std::unordered_map _states; //所有状态 std::vector _transitions; //所有状态迁移信息 std::map _parameters; // 所有的参数 int _cntAutoTrans2Hdl = 0; // 需要处理的自动事件的数量 std::string _indent; // 调试输出时的偏移值 StateTransition* _transitionDoing = nullptr; }; NS_RU_END #endif /* RUStateMachine_h */