diff options
Diffstat (limited to 'src/libjin/ai/je_state_machine.cpp')
-rw-r--r-- | src/libjin/ai/je_state_machine.cpp | 217 |
1 files changed, 77 insertions, 140 deletions
diff --git a/src/libjin/ai/je_state_machine.cpp b/src/libjin/ai/je_state_machine.cpp index 9b766b5..d77e523 100644 --- a/src/libjin/ai/je_state_machine.cpp +++ b/src/libjin/ai/je_state_machine.cpp @@ -52,14 +52,28 @@ namespace JinEngine State& state = it->second; for (int i = 0; i < state.transitions.size(); ++i) { - if (processCondition(state.transitions[i].condition)) + Conditions conditions = state.transitions[i].conditions; + bool isActive = true; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) { // Traslate mCurrentState = state.transitions[i].state; invokeCallback(state.name, mCurrentState); - return; + break; } } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<string, StateUpdateCallback*>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); } void StateMachine::iterativeProcess() @@ -71,16 +85,33 @@ namespace JinEngine return; } State& state = it->second; + bool isActive = true; for (int i = 0; i < state.transitions.size(); ++i) { - if (processCondition(state.transitions[i].condition)) + Conditions conditions = state.transitions[i].conditions; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) { // Traslate mCurrentState = state.transitions[i].state; invokeCallback(state.name, mCurrentState); - return iterativeProcess(); + break; } } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<string, StateUpdateCallback*>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); + // Recursive. + if(isActive) + return iterativeProcess(); } void StateMachine::setMode(Mode mode) @@ -228,155 +259,46 @@ namespace JinEngine } } - void StateMachine::addTransitioni(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression expression, int value) - { - map<string, State>::iterator it; - it = mStates.find(stateFrom); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateFrom); - return; - } - State& from = it->second; - it = mStates.find(stateTo); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateTo); - return; - } - State& to = it->second; - map<string, Parameter>::iterator itp; - itp = mParameters.find(name); - if (itp == mParameters.end()) - { - jin_log_error("The parameter is not exist.", name); - return; - } - Parameter& parameter = itp->second; - if (parameter.type != ParameterType::Int) - { - jin_log_error("The type of parameter %s is %s, but the transition gives a int value.", name, parameterTypeString(parameter.type)); - return; - } - Transition transition; - transition.condition.parameter = name; - transition.condition.expression = expression; - transition.condition.value._int = value; - transition.state = stateTo; - from.transitions.push_back(transition); - } - - void StateMachine::addTransitionf(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression expression, float value) - { - map<string, State>::iterator it; - it = mStates.find(stateFrom); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateFrom); - return; - } - State& from = it->second; - it = mStates.find(stateTo); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateTo); - return; - } - State& to = it->second; - map<string, Parameter>::iterator itp; - itp = mParameters.find(name); - if (itp == mParameters.end()) - { - jin_log_error("The parameter is not exist.", name); - return; - } - Parameter& parameter = itp->second; - if (parameter.type != ParameterType::Float) - { - jin_log_error("The type of parameter %s is %s, but the transition gives a float value.", name, parameterTypeString(parameter.type)); - return; - } - Transition transition; - transition.condition.parameter = name; - transition.condition.expression = expression; - transition.condition.value._float = value; - transition.state = stateTo; - from.transitions.push_back(transition); - } - - void StateMachine::addTransitionb(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression expression, bool value) + void StateMachine::addTransition(const std::string& from, const std::string& to, const Conditions& conditions) { map<string, State>::iterator it; - it = mStates.find(stateFrom); + it = mStates.find(from); if (it == mStates.end()) { - jin_log_error("The state %s is not exist.", stateFrom); + jin_log_error("The state %s is not exist.", from); return; } - State& from = it->second; - it = mStates.find(stateTo); + State& fromState = it->second; + it = mStates.find(to); if (it == mStates.end()) { - jin_log_error("The state %s is not exist.", stateTo); - return; - } - State& to = it->second; - map<string, Parameter>::iterator itp; - itp = mParameters.find(name); - if (itp == mParameters.end()) - { - jin_log_error("The parameter is not exist.", name); + jin_log_error("The state %s is not exist.", to); return; } - Parameter& parameter = itp->second; - if (parameter.type != ParameterType::Bool) + // Check condtion correctness. + for (int i = 0; i < conditions.conditions.size(); ++i) { - jin_log_error("The type of parameter %s is %s, but the transition gives a bool value.", name, parameterTypeString(parameter.type)); - return; + const Condition& condition = conditions.conditions[i]; + map<string, Parameter>::iterator itp; + itp = mParameters.find(condition.parameter); + if (itp == mParameters.end()) + { + jin_log_error("The parameter %s is not exist.", condition.parameter); + return; + } + Parameter& p = itp->second; + if (p.type != condition.type) + { + jin_log_error("The type of parameter %s is a %s, but the transition gives a %s value." + , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type)); + return; + } } + // Add transition. Transition transition; - transition.condition.parameter = name; - transition.condition.expression = expression; - transition.condition.value._bool = value; - transition.state = stateTo; - from.transitions.push_back(transition); - } - - void StateMachine::addTransitiont(const std::string& stateFrom, const std::string& stateTo, const std::string& name) - { - map<string, State>::iterator it; - it = mStates.find(stateFrom); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateFrom); - return; - } - State& from = it->second; - it = mStates.find(stateTo); - if (it == mStates.end()) - { - jin_log_error("The state %s is not exist.", stateTo); - return; - } - State& to = it->second; - map<string, Parameter>::iterator itp; - itp = mParameters.find(name); - if (itp == mParameters.end()) - { - jin_log_error("The parameter is not exist.", name); - return; - } - Parameter& parameter = itp->second; - if (parameter.type != ParameterType::Trigger) - { - jin_log_error("The type of parameter %s is %s, but the transition gives a trigger value.", name, parameterTypeString(parameter.type)); - return; - } - Transition trasition; - trasition.condition.parameter = name; - trasition.condition.value._trigger = true; - trasition.state = stateTo; - from.transitions.push_back(trasition); + transition.conditions = conditions; + transition.state = to; + fromState.transitions.push_back(transition); } void StateMachine::setParameteri(const std::string& name, int value) @@ -467,6 +389,16 @@ namespace JinEngine mOnEnterState.insert(pair<string, StateChangeCallback*>(state, callback)); } + void StateMachine::addUpdateListener(const std::string& state, StateUpdateCallback* callback) + { + if (mOnUpdateState.find(state) != mOnUpdateState.end()) + { + jin_log_error("The update listener of %s is already exist.", state); + return; + } + mOnUpdateState.insert(pair<string, StateUpdateCallback*>(state, callback)); + } + void StateMachine::addExitListener(const std::string& state, StateChangeCallback* callback) { if (mOnExitState.find(state) != mOnExitState.end()) @@ -488,6 +420,11 @@ namespace JinEngine mOnStateTranslate.insert(pair<pair<string, string>, StateTranslateCallback*>(key, callback)); } + void StateMachine::setUpdateListener(SingleStateCallback* callback) + { + mUpdateCallback = callback; + } + void StateMachine::setEnterListener(SingleStateCallback* callback) { mEnterCallback = callback; |