RUStateMachine.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #include "RUStateMachine.h"
  2. #include "RUState.h"
  3. #include "RUMetaState.h"
  4. #include "RUStateTransition.h"
  5. NS_RU_BEGIN
  6. StateMachine* StateMachine::create(const std::string& stateMachineName,
  7. const std::string& initStateName,
  8. const std::unordered_map<std::string, State*>& states,
  9. const std::vector<FsmTransition>& transitions,
  10. const std::map<std::string, FsmParameter>& params)
  11. {
  12. StateMachine * ret = new (std::nothrow) StateMachine();
  13. ret->autorelease();
  14. ret->retain();
  15. ret->_name = stateMachineName;
  16. ret->_initStateName = initStateName;
  17. ret->_states = states;
  18. ret->_transitions = transitions;
  19. ret->_parameters = params;
  20. return ret;
  21. }
  22. void StateMachine::runMachine(const std::function<void(void)>& runningCb)
  23. {
  24. if(_running){
  25. FSMLOG("%s : 已处于运行状态,直接返回", (_indent+_name).c_str());
  26. CCASSERT(false, "已处于运行状态");
  27. if(runningCb) {
  28. runningCb();
  29. }
  30. return;
  31. }
  32. FSMLOG("%s : 开始运行", (_indent+_name).c_str());
  33. _running = true;
  34. if(_runningStateName.empty() == true){ //状态机未提前设置好运行状态(有可能是切入到分层状态机)
  35. setRunningStateName(_initStateName);
  36. State* runningState = getState(_runningStateName);
  37. auto execHandleEventCb = [=](void){
  38. handleIfStateChanged(runningCb);
  39. };
  40. runningState->entry(execHandleEventCb);
  41. }else{ //已提前设置好运行状态(存档方式指定)
  42. State* runningState = getState(_runningStateName);
  43. runningState->idle(runningCb);
  44. }
  45. }
  46. void StateMachine::stopMachine(const std::function<void(void)>& stoppedCb)
  47. {
  48. auto exitCb = [=](void){
  49. _runningStateName = "";
  50. _running = false;
  51. if (stoppedCb) {
  52. stoppedCb();
  53. }
  54. };
  55. State* state = getState(_runningStateName);
  56. state->exit(exitCb);
  57. _cntAutoTrans2Hdl = 0;
  58. }
  59. void StateMachine::stopMachineImmediately() {
  60. State* state = getState(_runningStateName);
  61. if (state->getStateType() == kStateType::META) {
  62. MetaState* metaState = dynamic_cast<MetaState*>(state);
  63. metaState->stopMachineImmediately();
  64. }
  65. _runningStateName = "";
  66. _historyRunningStateName = "";
  67. _running = false;
  68. _cntAutoTrans2Hdl = 0;
  69. }
  70. void StateMachine::forceToStateNames(const std::vector<std::string>& stateNames, const std::function<void(void)>& forcedCb)
  71. {
  72. CCASSERT(_running == true, "如果当前不是运行运行态,不应该调用这个函数");
  73. stopMachineImmediately();
  74. setRunningStateNames(stateNames);
  75. runMachine(forcedCb);
  76. }
  77. std::vector<std::string> StateMachine::getInitStateNames()
  78. {
  79. std::vector<std::string> ret;
  80. ret.push_back(_initStateName);
  81. State* initState = getState(_initStateName);
  82. if (initState->getStateType() == kStateType::META) {
  83. MetaState* metaState = dynamic_cast<MetaState*>(initState);
  84. std::vector<std::string> metaInitStateNames = metaState->getInitStateNames();
  85. ret.insert(ret.end(), metaInitStateNames.begin(),metaInitStateNames.end());
  86. }
  87. return ret;
  88. }
  89. void StateMachine::setRunningStateName(const std::string& stateName)
  90. {
  91. CCASSERT(_states.find(stateName) != _states.end(), "没有这个状态");
  92. FSMLOG("%s : 设置状态->\"%s\"", (_indent+_name).c_str(), stateName.c_str());
  93. _runningStateName = stateName;
  94. _historyRunningStateName = _runningStateName;
  95. }
  96. void StateMachine::setRunningStateNames(std::vector<std::string> stateNames)
  97. {
  98. CCASSERT(stateNames.size() > 0 , "传个空的?");
  99. std::string stateName = stateNames.at(0);
  100. setRunningStateName(stateName);
  101. stateNames.erase(stateNames.begin());
  102. if (stateNames.size() > 0) {
  103. State* runningState = getState(stateName);
  104. CCASSERT(runningState->getStateType() == kStateType::META, "wft??");
  105. MetaState* metaState = dynamic_cast<MetaState*>(runningState);
  106. metaState->setRunningStateNames(stateNames);
  107. }
  108. }
  109. std::vector<std::string> StateMachine::getRunningStateNames()
  110. {
  111. std::vector<std::string> runningStateNames;
  112. if (_running) {
  113. runningStateNames.push_back(_runningStateName);
  114. State* runningState = getState(_runningStateName);
  115. if (runningState->getStateType() == kStateType::META) {
  116. MetaState* metaState = dynamic_cast<MetaState*>(runningState);
  117. std::vector<std::string> metaRunningStateNames = metaState->getRunningStateNames();
  118. runningStateNames.insert(runningStateNames.end(), metaRunningStateNames.begin(),metaRunningStateNames.end());
  119. }
  120. }
  121. return runningStateNames;
  122. }
  123. std::vector<std::string> StateMachine::getHistoryRunningStateNames()
  124. {
  125. if(_running){
  126. return getRunningStateNames();
  127. }else{
  128. std::vector<std::string> historyRunningStateNames;
  129. std::string historyRunningStateName;
  130. if (_historyRunningStateName.empty()) {
  131. historyRunningStateName = _initStateName;
  132. }else{
  133. historyRunningStateName = _historyRunningStateName;
  134. }
  135. historyRunningStateNames.push_back(historyRunningStateName);
  136. State* historyRunningState = getState(historyRunningStateName);
  137. if (historyRunningState->getStateType() == kStateType::META) {
  138. MetaState* metaState = dynamic_cast<MetaState*>(historyRunningState);
  139. std::vector<std::string> metaHistoryRunningStateNames = metaState->getHistoryRunningStateNames();
  140. historyRunningStateNames.insert(historyRunningStateNames.end(), metaHistoryRunningStateNames.begin(),metaHistoryRunningStateNames.end());
  141. }
  142. return historyRunningStateNames;
  143. }
  144. }
  145. bool StateMachine::canResponseEvent(const std::string& eventName)
  146. {
  147. bool canResponse = false;
  148. // 当前运行状态是否是MetaState(分层状态,状态本身就是个状态机),如果是,该分层状态能否响应该事件
  149. State* runningState = getState(_runningStateName);
  150. kStateType stateType = runningState->getStateType();
  151. if(stateType == kStateType::META){
  152. MetaState* metaState = dynamic_cast<MetaState*>(runningState) ;
  153. canResponse = metaState->canResponseEvent(eventName);
  154. }
  155. if (canResponse == false) {
  156. const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
  157. if (pTransition) {
  158. canResponse = true;
  159. }
  160. }
  161. return canResponse;
  162. }
  163. void StateMachine::handleEvent(const std::string& eventName, std::function<void(void)> handleEventCb)
  164. {
  165. handleEvent(eventName,{},handleEventCb);
  166. }
  167. void StateMachine::handleEvent(const std::string& eventName, const std::map<std::string, std::string>& eventParams, std::function<void(void)> handleEventCb)
  168. {
  169. // 不能响应事件的话直接返回
  170. if (_running == false || canResponseEvent(eventName) == false) {
  171. FSMLOG("%s : 不能响应事件:\"%s\",状态机是否运行:\"%s\",当前状态:\"%s\"]",
  172. (_indent+_name).c_str(), eventName.c_str(), cocos2d::Value(_running).asString().c_str(), _getRunningStateStr4Debug().c_str());
  173. if (handleEventCb) {
  174. handleEventCb();
  175. }
  176. return;
  177. }
  178. FSMLOG("%s : 响应事件:\"%s\",状态机是否运行:\"%s\",当前状态:\"%s\"]",
  179. (_indent+_name).c_str(), eventName.c_str(), cocos2d::Value(_running).asString().c_str(), _getRunningStateStr4Debug().c_str());
  180. // 当前运行状态如果为分层状态,优先分层状态处理该事件。
  181. State* runningState = getState(_runningStateName);
  182. kStateType stateType = runningState->getStateType();
  183. if(stateType == kStateType::META){
  184. MetaState* metaState = dynamic_cast<MetaState*>(runningState);
  185. if(metaState->canResponseEvent(eventName) == true){
  186. metaState->handleEvent(eventName, eventParams, handleEventCb);
  187. return;
  188. }
  189. }
  190. // 有新的事件,所以去掉自动转移
  191. _cntAutoTrans2Hdl = 0;
  192. if (_transitionDoing != nullptr) {
  193. _transitionDoing->interrupt();
  194. }
  195. const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
  196. if (pTransition) {
  197. _transitionDoing = StateTransition::create(this, pTransition, [=](StateTransition* trans, std::function<void(void)> cb, bool bInterrupted) {
  198. if (!bInterrupted) {
  199. handleIfStateChanged(cb);
  200. } else if (cb != nullptr) {
  201. cb();
  202. }
  203. trans->release();
  204. // 防止是被打断的情况
  205. if (trans == _transitionDoing) {
  206. _transitionDoing = nullptr;
  207. }
  208. });
  209. _transitionDoing->setEvent(eventName, eventParams, handleEventCb);
  210. _transitionDoing->execute();
  211. }
  212. }
  213. void StateMachine::handleIfStateChanged(std::function<void(void)> handleEventCb) {
  214. const FsmTransition* pTransition = _getFsmTransition(_runningStateName, AUTO_EVENT_NAME);
  215. if (pTransition) {
  216. /// 存在自动转换事件
  217. /// 自动事件和分发事件都不应该有事件参数,因为这个是状态机本身的行为,不是外部传递的
  218. if (_runningStateName == DISPATCH_STATE_NAME) {
  219. // 虚拟分发的时候先进行分发,后回调
  220. handleEvent(AUTO_EVENT_NAME, {}, handleEventCb);
  221. } else {
  222. _cntAutoTrans2Hdl += 1;
  223. if (handleEventCb) {
  224. handleEventCb();
  225. }
  226. if (_cntAutoTrans2Hdl > 0) {
  227. _cntAutoTrans2Hdl -= 1;
  228. handleEvent(AUTO_EVENT_NAME, {}, nullptr);
  229. }
  230. }
  231. }else{
  232. if (handleEventCb) {
  233. handleEventCb();
  234. }
  235. }
  236. }
  237. const std::vector<StateActInfo>& StateMachine::getIdleActInfosByStateFullPath(const std::vector<std::string>& stateNames)
  238. {
  239. CCASSERT(stateNames.size() > 0, "stateNames大小不能为零");
  240. State* state = getState(stateNames.at(0));
  241. if(stateNames.size() == 1){
  242. return state->getIdleActInfos();
  243. }else{
  244. CCASSERT(state->getStateType() == kStateType::META, "当前状态机一定是分层状态机,请检查");
  245. MetaState* metaState = dynamic_cast<MetaState*>(state) ;
  246. std::vector<std::string> states;
  247. states.insert(states.begin(), stateNames.begin() + 1, stateNames.end());
  248. return metaState->getIdleActInfosByStateFullPath(states);
  249. }
  250. }
  251. State* StateMachine::getState(const std::string& stateName)
  252. {
  253. State* ret = nullptr;
  254. auto iter = _states.find(stateName);
  255. if (iter != _states.end()) {
  256. ret = iter->second;
  257. }
  258. return ret;
  259. }
  260. bool StateMachine::chekcStateNamesValidity(std::vector<std::string> stateNames) {
  261. bool ret = true;
  262. if (stateNames.empty()) {
  263. ret = false;
  264. } else {
  265. State* state = getState(stateNames.at(0));
  266. if (state) {
  267. if (state->getStateType() == kStateType::META) {
  268. MetaState* metaState = dynamic_cast<MetaState*>(state);
  269. stateNames.erase(stateNames.begin());
  270. ret = metaState->chekcStateNamesValidity(stateNames);
  271. }
  272. } else {
  273. ret = false;
  274. }
  275. }
  276. return ret;
  277. }
  278. const FsmTransition* StateMachine::_getFsmTransition(const std::string& formState, const std::string& eventName)
  279. {
  280. const FsmTransition* pTransition = nullptr;
  281. for (const FsmTransition& transition : _transitions) {
  282. if (transition.fromState == formState && isEventNameMatched(eventName, transition.eventName)) {
  283. if (transition.conditions.size() > 0) {
  284. for (auto conds : transition.conditions) {
  285. if (checkConditonGroup(conds)) {
  286. pTransition = &transition;
  287. break;
  288. }
  289. }
  290. } else {
  291. pTransition = &transition;
  292. }
  293. }
  294. if (pTransition) {
  295. break;
  296. }
  297. }
  298. return pTransition;
  299. }
  300. bool StateMachine::isEventNameMatched(const std::string& name, const std::string& pattern) {
  301. /// eventName 支持字符串 "*" 匹配:全匹配、前半部分匹配、后半部分匹配;不支持中间部分匹配
  302. /// * 最多只有一个
  303. if (name == pattern) {
  304. return true;
  305. }
  306. if (name == AUTO_EVENT_NAME) {
  307. // 自动转移事件不参与匹配
  308. return false;
  309. }
  310. auto pos = pattern.find("*");
  311. if (pos == 0) {
  312. if (pattern.size() == 1) {
  313. // 全匹配
  314. return true;
  315. }
  316. // 前半部分匹配
  317. auto suffix = pattern.substr(1);
  318. auto pos1 = name.find(suffix);
  319. if ((pos1 + suffix.size()) == name.size()) {
  320. return true;
  321. }
  322. return false;
  323. } else if (pos == (pattern.size()-1)) {
  324. // 后半部分匹配
  325. auto suffix = pattern.substr(0, pattern.size()-1);
  326. if (name.find(suffix) == 0) {
  327. return true;
  328. }
  329. return false;
  330. }
  331. return false;
  332. }
  333. template<class T>
  334. bool checkParameter(T v1, std::string op, T v2) {
  335. if (op == "=") {
  336. return v1 == v2;
  337. } else if (op == "!=") {
  338. return v1 != v2;
  339. } else if (op == "<") {
  340. return v1 < v2;
  341. } else if (op == ">") {
  342. return v1 > v2;
  343. } else if (op == "<=") {
  344. return v1 < v2;
  345. } else if (op == ">=") {
  346. return v1 > v2;
  347. }
  348. return false;
  349. }
  350. bool StateMachine::checkConditonGroup(const std::list<FsmTansCondition>& conditions) {
  351. bool bRet = true;
  352. for (auto& cond : conditions) {
  353. auto it = _parameters.find(cond.name);
  354. if (it != _parameters.end()) {
  355. switch (it->second.type) {
  356. case PARAM_T_INT:
  357. bRet &= checkParameter<int>(it->second.iv, cond.op, cocos2d::Value(cond.v).asInt());
  358. break;
  359. case PARAM_T_FLOAT:
  360. bRet &= checkParameter<float>(it->second.fv, cond.op, cocos2d::Value(cond.v).asFloat());
  361. break;
  362. case PARAM_T_STRING:
  363. bRet &= checkParameter<std::string>(it->second.sv, cond.op, cocos2d::Value(cond.v).asString());
  364. break;
  365. case PARAM_T_TRIGGER:
  366. CCASSERT(false, "[fsm] trigger 还没有实现");
  367. break;
  368. }
  369. }
  370. }
  371. return bRet;
  372. }
  373. void StateMachine::setParam(const std::string& name, const std::string& v) {
  374. auto it = _parameters.find(name);
  375. if (it != _parameters.end()) {
  376. switch (it->second.type) {
  377. case PARAM_T_INT:
  378. it->second.iv = cocos2d::Value(v).asInt();
  379. break;
  380. case PARAM_T_FLOAT:
  381. it->second.fv = cocos2d::Value(v).asFloat();
  382. break;
  383. case PARAM_T_STRING:
  384. it->second.sv = cocos2d::Value(v).asString();
  385. break;
  386. case PARAM_T_TRIGGER:
  387. CCASSERT(false, "[fsm] trigger 还没有实现");
  388. break;
  389. }
  390. }
  391. // 遍历查找子子状态机
  392. for (auto st : _states) {
  393. auto stMeta = dynamic_cast<MetaState*>(st.second);
  394. if (stMeta) {
  395. stMeta->setParam(name, v);
  396. }
  397. }
  398. }
  399. void StateMachine::debugInfo()
  400. {
  401. CCLOG("状态机信息: %s", _name.c_str());
  402. CCLOG("{");
  403. CCLOG(" \"initStateName\":\"%s\",",_initStateName.c_str());
  404. CCLOG(" \"states\":{");
  405. for(auto state : _states) {
  406. state.second->debugInfo();
  407. }
  408. CCLOG(" },");
  409. auto getActionsInfo = [=](std::vector<StateActInfo> actinfos){
  410. std::string actions_str = "[";
  411. for(StateActInfo action : actinfos){
  412. actions_str = actions_str + "{\"type\":\""+ action.actType + "\",\"params\":{";
  413. for(auto paramIter : action.actParams){
  414. actions_str = actions_str + "\""+ paramIter.first + "\":\"" + paramIter.second + "\",";
  415. }
  416. actions_str = actions_str + "}";
  417. }
  418. actions_str = actions_str + "]";
  419. return actions_str;
  420. };
  421. auto getTransitionInfo = [=](FsmTransition transition){
  422. std::string transition_str;
  423. transition_str = transition_str + " {";
  424. transition_str = transition_str + "\n \"fromState\":\"" + transition.fromState + "\",";
  425. transition_str = transition_str + "\n \"toState\":\"" + transition.toState+ "\",";
  426. transition_str = transition_str + "\n \"eventName\":\"" + transition.eventName+ "\",";
  427. transition_str = transition_str + "\n \"before_switch_actions\":" + getActionsInfo(transition.beforeSwitchActInfos);
  428. transition_str = transition_str + ",\n \"after_switch_actions\":" + getActionsInfo(transition.afterSwitchActInfos);
  429. transition_str = transition_str + "\n },";
  430. return transition_str;
  431. };
  432. CCLOG(" \"transitions\":[");
  433. for(FsmTransition transition : _transitions){
  434. CCLOG("%s",getTransitionInfo(transition).c_str());
  435. }
  436. CCLOG(" ],");
  437. CCLOG("}");
  438. //打印子状态机信息
  439. for(auto state : _states){
  440. if (state.second->getStateType() == kStateType::META) {
  441. MetaState* metaState = dynamic_cast<MetaState*>(state.second);
  442. metaState->debugStateMachineInfo();
  443. }
  444. }
  445. }
  446. void StateMachine::setName(const std::string& name) {
  447. _name = name;
  448. }
  449. void StateMachine::setIndent4Dbg(const std::string& indent) {
  450. _indent = indent;
  451. std::vector<std::string> runnintStates = getRunningStateNames();
  452. std::string str = " " + indent;
  453. for (auto& st : _states) {
  454. st.second->setIndent4Dbg(" " + indent);
  455. }
  456. }
  457. void StateMachine::runMachine4Dbg()
  458. {
  459. _running = true;
  460. if(_runningStateName.empty() == true){ //状态机未提前设置好运行状态(有可能是切入到分层状态机)
  461. if(_initStateName.empty()){
  462. CCASSERT(false, "fff");
  463. }
  464. setRunningStateName(_initStateName);
  465. }
  466. }
  467. void StateMachine::handleEvent4Dbg(const std::string& eventName)
  468. {
  469. // 不能响应事件的话直接返回
  470. if (canResponseEvent(eventName) == false) {
  471. return;
  472. }
  473. State* runningState = getState(_runningStateName);
  474. kStateType stateType = runningState->getStateType();
  475. if(stateType == kStateType::META){
  476. MetaState* metaState = dynamic_cast<MetaState*>(runningState);
  477. if(metaState->canResponseEvent(eventName) == true){
  478. metaState->handleEvent4Dbg(eventName);
  479. return;
  480. }
  481. }
  482. const FsmTransition* pTransition = _getFsmTransition(_runningStateName, eventName);
  483. setRunningStateName(pTransition->toState);
  484. State* toState = getState(pTransition->toState);
  485. if(toState->getStateType() == kStateType::META){
  486. MetaState* toMetaState = dynamic_cast<MetaState*>(toState);
  487. toMetaState->runMachine4Dbg();
  488. }
  489. }
  490. std::string StateMachine::_getRunningStateStr4Debug()
  491. {
  492. std::vector<std::string> runnintStates = getRunningStateNames();
  493. std::string str;
  494. for (int i = 0; i < runnintStates.size(); i++) {
  495. if (i == runnintStates.size() - 1) {
  496. str = str + runnintStates[i];
  497. }else{
  498. str = str + runnintStates[i] + "#";
  499. }
  500. }
  501. return str;
  502. }
  503. NS_RU_END