123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #include "RUStateMachineLoader.h"
- #include "RUState.h"
- #include "RUMetaState.h"
- NS_RU_BEGIN
- static StateMachineLoader *_instance = nullptr;
- StateMachineLoader* StateMachineLoader::getInstance()
- {
- if (_instance == nullptr)
- {
- _instance = new (std::nothrow) StateMachineLoader;
- }
- return _instance;
- }
- StateMachine* StateMachineLoader::createStateMachine(const std::string& stateMachineName, void* userObj4StateDelegate)
- {
- return _createStateMachine(stateMachineName, {} , userObj4StateDelegate);
- }
- StateMachine* StateMachineLoader::_createStateMachine(const std::string& stateMachineName,
- const std::vector<std::string>& fullStatePath,
- void* userObj4StateDelegate)
- {
- fsmproto::StateMachine* stateMachineData = getStateMachineData(stateMachineName);
-
- const std::string& initStateName = stateMachineData->init_state_name();
- std::unordered_map<std::string, State*> states;
- std::vector<FsmTransition> transitions;
- std::map<std::string, FsmParameter> params;
-
- //解析状态列表
- const google::protobuf::RepeatedPtrField<fsmproto::State>& states_pb = stateMachineData->states();
- states.reserve(states_pb.size());
- for(const fsmproto::State& state_pb : states_pb){
- std::vector<std::string> newFullStatePath = fullStatePath;
- const std::string& stateName = state_pb.name();
- std::vector<StateActInfo> entryActInfos = _createStateActInfos(state_pb.entry());
- std::vector<StateActInfo> idleActInfos = _createStateActInfos(state_pb.idle());
- std::vector<StateActInfo> exitActInfos = _createStateActInfos(state_pb.exit());
- const std::string& stateDelegateKey = state_pb.state_delegate_key();
- newFullStatePath.push_back(stateName);
- redutils::State* state = nullptr;
- //是不是分层状态机
- const std::string& fsm_name = state_pb.fsm_name();
- if (fsm_name.empty() == true) { //普通状态
- state = redutils::State::create(stateName,
- newFullStatePath,
- kStateType::NORMAL,
- entryActInfos,
- idleActInfos,
- exitActInfos,
- stateDelegateKey,
- userObj4StateDelegate);
- }else{
- StateMachine* metaStateMachine = _createStateMachine(fsm_name, newFullStatePath, userObj4StateDelegate);
- state = redutils::MetaState::create(stateName,
- newFullStatePath,
- kStateType::META,
- entryActInfos,
- idleActInfos,
- exitActInfos,
- stateDelegateKey,
- userObj4StateDelegate,
- metaStateMachine);
- }
- CCASSERT(states.find(stateName) == states.end(), "重复的状态?");
- states.emplace(stateName,state);
- }
- //解析状态转换
- const google::protobuf::RepeatedPtrField<fsmproto::Transition>& transitions_pb = stateMachineData->transitions();
- transitions.reserve(transitions_pb.size());
- for(const fsmproto::Transition& transition_pb : transitions_pb)
- {
- FsmTransition fsmTransition = _createFsmTransition(transition_pb);
- transitions.push_back(std::move(fsmTransition));
- }
-
- //解析状态机自定义提交参数
- const google::protobuf::Map<std::string, fsmproto::Param>& params_pb = stateMachineData->params();
- for (auto iter = params_pb.begin(); iter != params_pb.end(); iter++) {
- const std::string& param_name = iter->first;
- const fsmproto::Param& param_pb = iter->second;
-
- FsmParameter param;
- param.name = param_name;
- const std::string& type = param_pb.type();
- if (type == "int") {
- param.type = FsmParamType::PARAM_T_INT;
- param.iv = cocos2d::Value(param_pb.default_value()).asInt();
- }else if (type == "float"){
- param.type = FsmParamType::PARAM_T_FLOAT;
- param.fv = cocos2d::Value(param_pb.default_value()).asFloat();
- }else if (type == "string"){
- param.type = FsmParamType::PARAM_T_STRING;
- param.sv = param_pb.default_value();
- }else if (type == "trigger"){
- param.type = FsmParamType::PARAM_T_TRIGGER;
- param.iv = cocos2d::Value(param_pb.default_value()).asInt();
- }
- params.emplace(param_name,std::move(param));
- }
-
- StateMachine* stateMachine = StateMachine::create(stateMachineName, initStateName, states, transitions, params);
- return stateMachine;
- }
- std::vector<StateActInfo> StateMachineLoader::_createStateActInfos(const google::protobuf::RepeatedPtrField<fsmproto::Action>& actions_pb)
- {
- std::vector<StateActInfo> stateActInfos;
- stateActInfos.reserve(actions_pb.size()); // 预分配内存
- for(const fsmproto::Action& action_pb : actions_pb){
- StateActInfo stateActInfo;
- stateActInfo.actType = action_pb.type();;
- const google::protobuf::Map<std::string, std::string>& params_pb = action_pb.params();
- for (auto iter = params_pb.begin(); iter != params_pb.end(); ++iter) {
- stateActInfo.actParams.emplace(iter->first, iter->second);
- }
- stateActInfos.push_back(std::move(stateActInfo));
- }
- return stateActInfos;
- }
- FsmTransition StateMachineLoader::_createFsmTransition(const fsmproto::Transition& transition_pb)
- {
- FsmTransition fsmTransition;
- fsmTransition.eventName = transition_pb.event();
- fsmTransition.fromState = transition_pb.src();
- fsmTransition.toState = transition_pb.dst();
- //转移条件
- std::list<std::list<FsmTansCondition>> conditions;
- const google::protobuf::RepeatedPtrField<fsmproto::ConditionData>& conditions_group_pb = transition_pb.condition();
- for(const fsmproto::ConditionData& conditions_pb : conditions_group_pb){
- std::list<FsmTansCondition> fsmTansConditions;
- for(const fsmproto::ConditionValue& conditionValue_pb : conditions_pb.values()){
- FsmTansCondition fsmTansCondition;
- fsmTansCondition.name = conditionValue_pb.param_name();
- fsmTansCondition.op = conditionValue_pb.symbol();
- fsmTansCondition.v = conditionValue_pb.compare_value();
- fsmTansConditions.push_back(std::move(fsmTansCondition));
- }
- conditions.push_back(std::move(fsmTansConditions));
- }
- fsmTransition.conditions = std::move(conditions);
- fsmTransition.beforeSwitchActInfos = _createStateActInfos(transition_pb.before_switch_actions());
- fsmTransition.afterSwitchActInfos = _createStateActInfos(transition_pb.after_switch_actions());
- return fsmTransition;
- }
- fsmproto::StateMachine* StateMachineLoader::getStateMachineData(const std::string& stateMachineName)
- {
- fsmproto::StateMachine* stateMachineData = nullptr;
- auto p = _stateMachineDataCacheMap.find(stateMachineName);
- if( p != _stateMachineDataCacheMap.end()){
- stateMachineData = p->second;
- }else {
- std::string fileName = stateMachineName + ".fsm";
- cocos2d::Data datas = cocos2d::FileUtils::getInstance()->getDataFromFile(fileName);
- unsigned char *data = datas.getBytes();
- ssize_t len = datas.getSize();
- std::string fileStr(data, data + len);
-
- stateMachineData = new fsmproto::StateMachine();
- stateMachineData->ParseFromString(fileStr);
-
- _stateMachineDataCacheMap.emplace(stateMachineName, stateMachineData);
- }
- CCASSERT(stateMachineData != nullptr, "wtf");
- return stateMachineData;
- }
- void StateMachineLoader::releaseAllStateMachineDataCache()
- {
- for(auto iter : _stateMachineDataCacheMap ){
- delete iter.second;
- }
- _stateMachineDataCacheMap.clear();
- }
- NS_RU_END
|