RUStateMachineLoader.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "RUStateMachineLoader.h"
  2. #include "RUState.h"
  3. #include "RUMetaState.h"
  4. NS_RU_BEGIN
  5. static StateMachineLoader *_instance = nullptr;
  6. StateMachineLoader* StateMachineLoader::getInstance()
  7. {
  8. if (_instance == nullptr)
  9. {
  10. _instance = new (std::nothrow) StateMachineLoader;
  11. }
  12. return _instance;
  13. }
  14. StateMachine* StateMachineLoader::createStateMachine(const std::string& stateMachineName, void* userObj4StateDelegate)
  15. {
  16. return _createStateMachine(stateMachineName, {} , userObj4StateDelegate);
  17. }
  18. StateMachine* StateMachineLoader::_createStateMachine(const std::string& stateMachineName,
  19. const std::vector<std::string>& fullStatePath,
  20. void* userObj4StateDelegate)
  21. {
  22. fsmproto::StateMachine* stateMachineData = getStateMachineData(stateMachineName);
  23. const std::string& initStateName = stateMachineData->init_state_name();
  24. std::unordered_map<std::string, State*> states;
  25. std::vector<FsmTransition> transitions;
  26. std::map<std::string, FsmParameter> params;
  27. //解析状态列表
  28. const google::protobuf::RepeatedPtrField<fsmproto::State>& states_pb = stateMachineData->states();
  29. states.reserve(states_pb.size());
  30. for(const fsmproto::State& state_pb : states_pb){
  31. std::vector<std::string> newFullStatePath = fullStatePath;
  32. const std::string& stateName = state_pb.name();
  33. std::vector<StateActInfo> entryActInfos = _createStateActInfos(state_pb.entry());
  34. std::vector<StateActInfo> idleActInfos = _createStateActInfos(state_pb.idle());
  35. std::vector<StateActInfo> exitActInfos = _createStateActInfos(state_pb.exit());
  36. const std::string& stateDelegateKey = state_pb.state_delegate_key();
  37. newFullStatePath.push_back(stateName);
  38. redutils::State* state = nullptr;
  39. //是不是分层状态机
  40. const std::string& fsm_name = state_pb.fsm_name();
  41. if (fsm_name.empty() == true) { //普通状态
  42. state = redutils::State::create(stateName,
  43. newFullStatePath,
  44. kStateType::NORMAL,
  45. entryActInfos,
  46. idleActInfos,
  47. exitActInfos,
  48. stateDelegateKey,
  49. userObj4StateDelegate);
  50. }else{
  51. StateMachine* metaStateMachine = _createStateMachine(fsm_name, newFullStatePath, userObj4StateDelegate);
  52. state = redutils::MetaState::create(stateName,
  53. newFullStatePath,
  54. kStateType::META,
  55. entryActInfos,
  56. idleActInfos,
  57. exitActInfos,
  58. stateDelegateKey,
  59. userObj4StateDelegate,
  60. metaStateMachine);
  61. }
  62. CCASSERT(states.find(stateName) == states.end(), "重复的状态?");
  63. states.emplace(stateName,state);
  64. }
  65. //解析状态转换
  66. const google::protobuf::RepeatedPtrField<fsmproto::Transition>& transitions_pb = stateMachineData->transitions();
  67. transitions.reserve(transitions_pb.size());
  68. for(const fsmproto::Transition& transition_pb : transitions_pb)
  69. {
  70. FsmTransition fsmTransition = _createFsmTransition(transition_pb);
  71. transitions.push_back(std::move(fsmTransition));
  72. }
  73. //解析状态机自定义提交参数
  74. const google::protobuf::Map<std::string, fsmproto::Param>& params_pb = stateMachineData->params();
  75. for (auto iter = params_pb.begin(); iter != params_pb.end(); iter++) {
  76. const std::string& param_name = iter->first;
  77. const fsmproto::Param& param_pb = iter->second;
  78. FsmParameter param;
  79. param.name = param_name;
  80. const std::string& type = param_pb.type();
  81. if (type == "int") {
  82. param.type = FsmParamType::PARAM_T_INT;
  83. param.iv = cocos2d::Value(param_pb.default_value()).asInt();
  84. }else if (type == "float"){
  85. param.type = FsmParamType::PARAM_T_FLOAT;
  86. param.fv = cocos2d::Value(param_pb.default_value()).asFloat();
  87. }else if (type == "string"){
  88. param.type = FsmParamType::PARAM_T_STRING;
  89. param.sv = param_pb.default_value();
  90. }else if (type == "trigger"){
  91. param.type = FsmParamType::PARAM_T_TRIGGER;
  92. param.iv = cocos2d::Value(param_pb.default_value()).asInt();
  93. }
  94. params.emplace(param_name,std::move(param));
  95. }
  96. StateMachine* stateMachine = StateMachine::create(stateMachineName, initStateName, states, transitions, params);
  97. return stateMachine;
  98. }
  99. std::vector<StateActInfo> StateMachineLoader::_createStateActInfos(const google::protobuf::RepeatedPtrField<fsmproto::Action>& actions_pb)
  100. {
  101. std::vector<StateActInfo> stateActInfos;
  102. stateActInfos.reserve(actions_pb.size()); // 预分配内存
  103. for(const fsmproto::Action& action_pb : actions_pb){
  104. StateActInfo stateActInfo;
  105. stateActInfo.actType = action_pb.type();;
  106. const google::protobuf::Map<std::string, std::string>& params_pb = action_pb.params();
  107. for (auto iter = params_pb.begin(); iter != params_pb.end(); ++iter) {
  108. stateActInfo.actParams.emplace(iter->first, iter->second);
  109. }
  110. stateActInfos.push_back(std::move(stateActInfo));
  111. }
  112. return stateActInfos;
  113. }
  114. FsmTransition StateMachineLoader::_createFsmTransition(const fsmproto::Transition& transition_pb)
  115. {
  116. FsmTransition fsmTransition;
  117. fsmTransition.eventName = transition_pb.event();
  118. fsmTransition.fromState = transition_pb.src();
  119. fsmTransition.toState = transition_pb.dst();
  120. //转移条件
  121. std::list<std::list<FsmTansCondition>> conditions;
  122. const google::protobuf::RepeatedPtrField<fsmproto::ConditionData>& conditions_group_pb = transition_pb.condition();
  123. for(const fsmproto::ConditionData& conditions_pb : conditions_group_pb){
  124. std::list<FsmTansCondition> fsmTansConditions;
  125. for(const fsmproto::ConditionValue& conditionValue_pb : conditions_pb.values()){
  126. FsmTansCondition fsmTansCondition;
  127. fsmTansCondition.name = conditionValue_pb.param_name();
  128. fsmTansCondition.op = conditionValue_pb.symbol();
  129. fsmTansCondition.v = conditionValue_pb.compare_value();
  130. fsmTansConditions.push_back(std::move(fsmTansCondition));
  131. }
  132. conditions.push_back(std::move(fsmTansConditions));
  133. }
  134. fsmTransition.conditions = std::move(conditions);
  135. fsmTransition.beforeSwitchActInfos = _createStateActInfos(transition_pb.before_switch_actions());
  136. fsmTransition.afterSwitchActInfos = _createStateActInfos(transition_pb.after_switch_actions());
  137. return fsmTransition;
  138. }
  139. fsmproto::StateMachine* StateMachineLoader::getStateMachineData(const std::string& stateMachineName)
  140. {
  141. fsmproto::StateMachine* stateMachineData = nullptr;
  142. auto p = _stateMachineDataCacheMap.find(stateMachineName);
  143. if( p != _stateMachineDataCacheMap.end()){
  144. stateMachineData = p->second;
  145. }else {
  146. std::string fileName = stateMachineName + ".fsm";
  147. cocos2d::Data datas = cocos2d::FileUtils::getInstance()->getDataFromFile(fileName);
  148. unsigned char *data = datas.getBytes();
  149. ssize_t len = datas.getSize();
  150. std::string fileStr(data, data + len);
  151. stateMachineData = new fsmproto::StateMachine();
  152. stateMachineData->ParseFromString(fileStr);
  153. _stateMachineDataCacheMap.emplace(stateMachineName, stateMachineData);
  154. }
  155. CCASSERT(stateMachineData != nullptr, "wtf");
  156. return stateMachineData;
  157. }
  158. void StateMachineLoader::releaseAllStateMachineDataCache()
  159. {
  160. for(auto iter : _stateMachineDataCacheMap ){
  161. delete iter.second;
  162. }
  163. _stateMachineDataCacheMap.clear();
  164. }
  165. NS_RU_END