123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 |
- #include "RUStateMachine.h"
- #include "RUState.h"
- #include "RUMetaState.h"
- #include "RUStateTransition.h"
- NS_RU_BEGIN
- StateMachine* StateMachine::create(const std::string& stateMachineName,
- const std::string& initStateName,
- const std::unordered_map<std::string, State*>& states,
- const std::vector<FsmTransition>& transitions,
- const std::map<std::string, FsmParameter>& params)
- {
- StateMachine * ret = new (std::nothrow) StateMachine();
- ret->autorelease();
- ret->retain();
-
- ret->_name = stateMachineName;
- ret->_initStateName = initStateName;
- ret->_states = states;
- ret->_transitions = transitions;
- ret->_parameters = params;
- return ret;
- }
- void StateMachine::runMachine(const std::function<void(void)>& runningCb)
- {
- if(_running){
- FSMLOG("%s : 已处于运行状态,直接返回", (_indent+_name).c_str());
- CCASSERT(false, "已处于运行状态");
- if(runningCb) {
- runningCb();
- }
- return;
- }
- FSMLOG("%s : 开始运行", (_indent+_name).c_str());
- _running = true;
- if(_runningStateName.empty() == true){ //状态机未提前设置好运行状态(有可能是切入到分层状态机)
- setRunningStateName(_initStateName);
- State* runningState = getState(_runningStateName);
- auto execHandleEventCb = [=](void){
- handleIfStateChanged(runningCb);
- };
- runningState->entry(execHandleEventCb);
- }else{ //已提前设置好运行状态(存档方式指定)
- State* runningState = getState(_runningStateName);
- runningState->idle(runningCb);
- }
- }
- void StateMachine::stopMachine(const std::function<void(void)>& stoppedCb)
- {
- auto exitCb = [=](void){
- _runningStateName = "";
- _running = false;
- if (stoppedCb) {
- stoppedCb();
- }
- };
- State* state = getState(_runningStateName);
- state->exit(exitCb);
- _cntAutoTrans2Hdl = 0;
- }
- void StateMachine::stopMachineImmediately() {
- State* state = getState(_runningStateName);
- if (state->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(state);
- metaState->stopMachineImmediately();
- }
- _runningStateName = "";
- _historyRunningStateName = "";
- _running = false;
- _cntAutoTrans2Hdl = 0;
- }
- void StateMachine::forceToStateNames(const std::vector<std::string>& stateNames, const std::function<void(void)>& forcedCb)
- {
- CCASSERT(_running == true, "如果当前不是运行运行态,不应该调用这个函数");
- stopMachineImmediately();
- setRunningStateNames(stateNames);
- runMachine(forcedCb);
- }
- std::vector<std::string> StateMachine::getInitStateNames()
- {
- std::vector<std::string> ret;
- ret.push_back(_initStateName);
- State* initState = getState(_initStateName);
- if (initState->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(initState);
- std::vector<std::string> metaInitStateNames = metaState->getInitStateNames();
- ret.insert(ret.end(), metaInitStateNames.begin(),metaInitStateNames.end());
- }
- return ret;
- }
- void StateMachine::setRunningStateName(const std::string& stateName)
- {
- CCASSERT(_states.find(stateName) != _states.end(), "没有这个状态");
- FSMLOG("%s : 设置状态->\"%s\"", (_indent+_name).c_str(), stateName.c_str());
- _runningStateName = stateName;
- _historyRunningStateName = _runningStateName;
- }
- void StateMachine::setRunningStateNames(std::vector<std::string> stateNames)
- {
- CCASSERT(stateNames.size() > 0 , "传个空的?");
- std::string stateName = stateNames.at(0);
- setRunningStateName(stateName);
- stateNames.erase(stateNames.begin());
- if (stateNames.size() > 0) {
- State* runningState = getState(stateName);
- CCASSERT(runningState->getStateType() == kStateType::META, "wft??");
- MetaState* metaState = dynamic_cast<MetaState*>(runningState);
- metaState->setRunningStateNames(stateNames);
- }
- }
- std::vector<std::string> StateMachine::getRunningStateNames()
- {
- std::vector<std::string> runningStateNames;
- if (_running) {
- runningStateNames.push_back(_runningStateName);
- State* runningState = getState(_runningStateName);
- if (runningState->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(runningState);
- std::vector<std::string> metaRunningStateNames = metaState->getRunningStateNames();
- runningStateNames.insert(runningStateNames.end(), metaRunningStateNames.begin(),metaRunningStateNames.end());
- }
- }
- return runningStateNames;
- }
- std::vector<std::string> StateMachine::getHistoryRunningStateNames()
- {
- if(_running){
- return getRunningStateNames();
- }else{
- std::vector<std::string> historyRunningStateNames;
- std::string historyRunningStateName;
- if (_historyRunningStateName.empty()) {
- historyRunningStateName = _initStateName;
- }else{
- historyRunningStateName = _historyRunningStateName;
- }
- historyRunningStateNames.push_back(historyRunningStateName);
- State* historyRunningState = getState(historyRunningStateName);
- if (historyRunningState->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(historyRunningState);
- std::vector<std::string> metaHistoryRunningStateNames = metaState->getHistoryRunningStateNames();
- historyRunningStateNames.insert(historyRunningStateNames.end(), metaHistoryRunningStateNames.begin(),metaHistoryRunningStateNames.end());
- }
- return historyRunningStateNames;
- }
- }
- bool StateMachine::canResponseEvent(const std::string& eventName)
- {
- bool canResponse = false;
-
- // 当前运行状态是否是MetaState(分层状态,状态本身就是个状态机),如果是,该分层状态能否响应该事件
- State* runningState = getState(_runningStateName);
- kStateType stateType = runningState->getStateType();
- if(stateType == kStateType::META){
- MetaState* metaState = dynamic_cast<MetaState*>(runningState) ;
- canResponse = metaState->canResponseEvent(eventName);
- }
- if (canResponse == false) {
- const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
- if (pTransition) {
- canResponse = true;
- }
- }
- return canResponse;
- }
- void StateMachine::handleEvent(const std::string& eventName, std::function<void(void)> handleEventCb)
- {
- handleEvent(eventName,{},handleEventCb);
- }
- void StateMachine::handleEvent(const std::string& eventName, const std::map<std::string, std::string>& eventParams, std::function<void(void)> handleEventCb)
- {
- // 不能响应事件的话直接返回
- if (_running == false || canResponseEvent(eventName) == false) {
- FSMLOG("%s : 不能响应事件:\"%s\",状态机是否运行:\"%s\",当前状态:\"%s\"]",
- (_indent+_name).c_str(), eventName.c_str(), cocos2d::Value(_running).asString().c_str(), _getRunningStateStr4Debug().c_str());
- if (handleEventCb) {
- handleEventCb();
- }
- return;
- }
- FSMLOG("%s : 响应事件:\"%s\",状态机是否运行:\"%s\",当前状态:\"%s\"]",
- (_indent+_name).c_str(), eventName.c_str(), cocos2d::Value(_running).asString().c_str(), _getRunningStateStr4Debug().c_str());
- // 当前运行状态如果为分层状态,优先分层状态处理该事件。
- State* runningState = getState(_runningStateName);
- kStateType stateType = runningState->getStateType();
- if(stateType == kStateType::META){
- MetaState* metaState = dynamic_cast<MetaState*>(runningState);
- if(metaState->canResponseEvent(eventName) == true){
- metaState->handleEvent(eventName, eventParams, handleEventCb);
- return;
- }
- }
-
- // 有新的事件,所以去掉自动转移
- _cntAutoTrans2Hdl = 0;
-
- if (_transitionDoing != nullptr) {
- _transitionDoing->interrupt();
- }
-
- const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
- if (pTransition) {
- _transitionDoing = StateTransition::create(this, pTransition, [=](StateTransition* trans, std::function<void(void)> cb, bool bInterrupted) {
- if (!bInterrupted) {
- handleIfStateChanged(cb);
- } else if (cb != nullptr) {
- cb();
- }
- trans->release();
- // 防止是被打断的情况
- if (trans == _transitionDoing) {
- _transitionDoing = nullptr;
- }
- });
- _transitionDoing->setEvent(eventName, eventParams, handleEventCb);
- _transitionDoing->execute();
- }
- }
- void StateMachine::handleIfStateChanged(std::function<void(void)> handleEventCb) {
- const FsmTransition* pTransition = _getFsmTransition(_runningStateName, AUTO_EVENT_NAME);
- if (pTransition) {
- /// 存在自动转换事件
- /// 自动事件和分发事件都不应该有事件参数,因为这个是状态机本身的行为,不是外部传递的
- if (_runningStateName == DISPATCH_STATE_NAME) {
- // 虚拟分发的时候先进行分发,后回调
- handleEvent(AUTO_EVENT_NAME, {}, handleEventCb);
- } else {
- _cntAutoTrans2Hdl += 1;
- if (handleEventCb) {
- handleEventCb();
- }
- if (_cntAutoTrans2Hdl > 0) {
- _cntAutoTrans2Hdl -= 1;
- handleEvent(AUTO_EVENT_NAME, {}, nullptr);
- }
- }
- }else{
- if (handleEventCb) {
- handleEventCb();
- }
- }
- }
- const std::vector<StateActInfo>& StateMachine::getIdleActInfosByStateFullPath(const std::vector<std::string>& stateNames)
- {
- CCASSERT(stateNames.size() > 0, "stateNames大小不能为零");
- State* state = getState(stateNames.at(0));
- if(stateNames.size() == 1){
- return state->getIdleActInfos();
- }else{
- CCASSERT(state->getStateType() == kStateType::META, "当前状态机一定是分层状态机,请检查");
- MetaState* metaState = dynamic_cast<MetaState*>(state) ;
- std::vector<std::string> states;
- states.insert(states.begin(), stateNames.begin() + 1, stateNames.end());
- return metaState->getIdleActInfosByStateFullPath(states);
- }
- }
- State* StateMachine::getState(const std::string& stateName)
- {
- State* ret = nullptr;
- auto iter = _states.find(stateName);
- if (iter != _states.end()) {
- ret = iter->second;
- }
- return ret;
- }
- bool StateMachine::chekcStateNamesValidity(std::vector<std::string> stateNames) {
- bool ret = true;
- if (stateNames.empty()) {
- ret = false;
- } else {
- State* state = getState(stateNames.at(0));
- if (state) {
- if (state->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(state);
- stateNames.erase(stateNames.begin());
- ret = metaState->chekcStateNamesValidity(stateNames);
- }
- } else {
- ret = false;
- }
- }
- return ret;
- }
- const FsmTransition* StateMachine::_getFsmTransition(const std::string& formState, const std::string& eventName)
- {
- const FsmTransition* pTransition = nullptr;
- for (const FsmTransition& transition : _transitions) {
- if (transition.fromState == formState && isEventNameMatched(eventName, transition.eventName)) {
- if (transition.conditions.size() > 0) {
- for (auto conds : transition.conditions) {
- if (checkConditonGroup(conds)) {
- pTransition = &transition;
- break;
- }
- }
- } else {
- pTransition = &transition;
- }
- }
- if (pTransition) {
- break;
- }
- }
- return pTransition;
- }
- bool StateMachine::isEventNameMatched(const std::string& name, const std::string& pattern) {
- /// eventName 支持字符串 "*" 匹配:全匹配、前半部分匹配、后半部分匹配;不支持中间部分匹配
- /// * 最多只有一个
- if (name == pattern) {
- return true;
- }
- if (name == AUTO_EVENT_NAME) {
- // 自动转移事件不参与匹配
- return false;
- }
- auto pos = pattern.find("*");
- if (pos == 0) {
- if (pattern.size() == 1) {
- // 全匹配
- return true;
- }
-
- // 前半部分匹配
- auto suffix = pattern.substr(1);
- auto pos1 = name.find(suffix);
- if ((pos1 + suffix.size()) == name.size()) {
- return true;
- }
- return false;
- } else if (pos == (pattern.size()-1)) {
- // 后半部分匹配
- auto suffix = pattern.substr(0, pattern.size()-1);
- if (name.find(suffix) == 0) {
- return true;
- }
- return false;
- }
- return false;
- }
- template<class T>
- bool checkParameter(T v1, std::string op, T v2) {
- if (op == "=") {
- return v1 == v2;
- } else if (op == "!=") {
- return v1 != v2;
- } else if (op == "<") {
- return v1 < v2;
- } else if (op == ">") {
- return v1 > v2;
- } else if (op == "<=") {
- return v1 < v2;
- } else if (op == ">=") {
- return v1 > v2;
- }
- return false;
- }
- bool StateMachine::checkConditonGroup(const std::list<FsmTansCondition>& conditions) {
- bool bRet = true;
- for (auto& cond : conditions) {
- auto it = _parameters.find(cond.name);
- if (it != _parameters.end()) {
- switch (it->second.type) {
- case PARAM_T_INT:
- bRet &= checkParameter<int>(it->second.iv, cond.op, cocos2d::Value(cond.v).asInt());
- break;
-
- case PARAM_T_FLOAT:
- bRet &= checkParameter<float>(it->second.fv, cond.op, cocos2d::Value(cond.v).asFloat());
- break;
-
- case PARAM_T_STRING:
- bRet &= checkParameter<std::string>(it->second.sv, cond.op, cocos2d::Value(cond.v).asString());
- break;
-
- case PARAM_T_TRIGGER:
- CCASSERT(false, "[fsm] trigger 还没有实现");
- break;
- }
- }
- }
- return bRet;
- }
- void StateMachine::setParam(const std::string& name, const std::string& v) {
- auto it = _parameters.find(name);
- if (it != _parameters.end()) {
- switch (it->second.type) {
- case PARAM_T_INT:
- it->second.iv = cocos2d::Value(v).asInt();
- break;
-
- case PARAM_T_FLOAT:
- it->second.fv = cocos2d::Value(v).asFloat();
- break;
-
- case PARAM_T_STRING:
- it->second.sv = cocos2d::Value(v).asString();
- break;
-
- case PARAM_T_TRIGGER:
- CCASSERT(false, "[fsm] trigger 还没有实现");
- break;
- }
- }
- // 遍历查找子子状态机
- for (auto st : _states) {
- auto stMeta = dynamic_cast<MetaState*>(st.second);
- if (stMeta) {
- stMeta->setParam(name, v);
- }
- }
- }
- void StateMachine::debugInfo()
- {
- CCLOG("状态机信息: %s", _name.c_str());
- CCLOG("{");
- CCLOG(" \"initStateName\":\"%s\",",_initStateName.c_str());
- CCLOG(" \"states\":{");
- for(auto state : _states) {
- state.second->debugInfo();
- }
- CCLOG(" },");
-
- auto getActionsInfo = [=](std::vector<StateActInfo> actinfos){
- std::string actions_str = "[";
- for(StateActInfo action : actinfos){
- actions_str = actions_str + "{\"type\":\""+ action.actType + "\",\"params\":{";
- for(auto paramIter : action.actParams){
- actions_str = actions_str + "\""+ paramIter.first + "\":\"" + paramIter.second + "\",";
- }
- actions_str = actions_str + "}";
- }
- actions_str = actions_str + "]";
- return actions_str;
- };
- auto getTransitionInfo = [=](FsmTransition transition){
- std::string transition_str;
- transition_str = transition_str + " {";
- transition_str = transition_str + "\n \"fromState\":\"" + transition.fromState + "\",";
- transition_str = transition_str + "\n \"toState\":\"" + transition.toState+ "\",";
- transition_str = transition_str + "\n \"eventName\":\"" + transition.eventName+ "\",";
- transition_str = transition_str + "\n \"before_switch_actions\":" + getActionsInfo(transition.beforeSwitchActInfos);
- transition_str = transition_str + ",\n \"after_switch_actions\":" + getActionsInfo(transition.afterSwitchActInfos);
- transition_str = transition_str + "\n },";
- return transition_str;
- };
-
- CCLOG(" \"transitions\":[");
- for(FsmTransition transition : _transitions){
- CCLOG("%s",getTransitionInfo(transition).c_str());
- }
- CCLOG(" ],");
- CCLOG("}");
-
- //打印子状态机信息
- for(auto state : _states){
- if (state.second->getStateType() == kStateType::META) {
- MetaState* metaState = dynamic_cast<MetaState*>(state.second);
- metaState->debugStateMachineInfo();
- }
- }
- }
- void StateMachine::setName(const std::string& name) {
- _name = name;
- }
- void StateMachine::setIndent4Dbg(const std::string& indent) {
- _indent = indent;
- std::vector<std::string> runnintStates = getRunningStateNames();
- std::string str = " " + indent;
- for (auto& st : _states) {
- st.second->setIndent4Dbg(" " + indent);
- }
- }
- void StateMachine::runMachine4Dbg()
- {
- _running = true;
- if(_runningStateName.empty() == true){ //状态机未提前设置好运行状态(有可能是切入到分层状态机)
- if(_initStateName.empty()){
- CCASSERT(false, "fff");
- }
- setRunningStateName(_initStateName);
- }
- }
- void StateMachine::handleEvent4Dbg(const std::string& eventName)
- {
- // 不能响应事件的话直接返回
- if (canResponseEvent(eventName) == false) {
- return;
- }
- State* runningState = getState(_runningStateName);
- kStateType stateType = runningState->getStateType();
- if(stateType == kStateType::META){
- MetaState* metaState = dynamic_cast<MetaState*>(runningState);
- if(metaState->canResponseEvent(eventName) == true){
- metaState->handleEvent4Dbg(eventName);
- return;
- }
- }
-
- const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
- setRunningStateName(pTransition->toState);
-
- State* toState = getState(pTransition->toState);
- if(toState->getStateType() == kStateType::META){
- MetaState* toMetaState = dynamic_cast<MetaState*>(toState);
- toMetaState->runMachine4Dbg();
- }
- }
- std::string StateMachine::_getRunningStateStr4Debug()
- {
- std::vector<std::string> runnintStates = getRunningStateNames();
- std::string str;
- for (int i = 0; i < runnintStates.size(); i++) {
- if (i == runnintStates.size() - 1) {
- str = str + runnintStates[i];
- }else{
- str = str + runnintStates[i] + "#";
- }
- }
- return str;
- }
- NS_RU_END
|