aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/ai/state_machine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/ai/state_machine.cpp')
-rw-r--r--src/libjin/ai/state_machine.cpp872
1 files changed, 436 insertions, 436 deletions
diff --git a/src/libjin/ai/state_machine.cpp b/src/libjin/ai/state_machine.cpp
index cefd0b9..96450ae 100644
--- a/src/libjin/ai/state_machine.cpp
+++ b/src/libjin/ai/state_machine.cpp
@@ -6,440 +6,440 @@ using namespace std;
namespace JinEngine
{
- namespace AI
- {
-
- StateMachine::StateMachine(Mode mode, void* userdata)
- : mCurrentState(0)
- , mUserData(userdata)
- , mMode(mode)
- {
- addState(0);
- }
-
- StateMachine::~StateMachine()
- {
- }
-
- void StateMachine::invokeCallback(int from, int to)
- {
- if (mExitCallback != nullptr)
- mExitCallback(from, mUserData);
- if (mTraslateCallback != nullptr)
- mTraslateCallback(from, to, mUserData);
- if (mEnterCallback != nullptr)
- mEnterCallback(to, mUserData);
- map<int, StateChangeCallback>::iterator it = mOnExitState.find(from);
- if (it != mOnExitState.end())
- it->second(mUserData);
- map<pair<int, int>, StateTranslateCallback>::iterator transItr
- = mOnStateTranslate.find(pair<int, int>(from, to));
- if (transItr != mOnStateTranslate.end())
- transItr->second(mUserData);
- it = mOnEnterState.find(to);
- if (it != mOnEnterState.end())
- it->second(mUserData);
- }
-
- void StateMachine::stepwiseProcess()
- {
- map<int, State>::iterator it = mStates.find(mCurrentState);
- if (it == mStates.end())
- {
- jin_log_error("The state [%d] is not exist.", mCurrentState);
- return;
- }
- State& state = it->second;
- for (int i = 0; i < state.transitions.size(); ++i)
- {
- 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);
- break;
- }
- }
- // Call update
- if (mUpdateCallback != nullptr)
- mUpdateCallback(mCurrentState, mUserData);
- map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState);
- if (uit != mOnUpdateState.end())
- uit->second(mUserData);
- }
-
- void StateMachine::iterativeProcess()
- {
- map<int, State>::iterator it = mStates.find(mCurrentState);
- if (it == mStates.end())
- {
- jin_log_error("The state [%d] is not exist.", mCurrentState);
- return;
- }
- State& state = it->second;
- bool isActive = true;
- for (int i = 0; i < state.transitions.size(); ++i)
- {
- Conditions conditions = state.transitions[i].conditions;
- 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);
- break;
- }
- }
- // Call update
- if (mUpdateCallback != nullptr)
- mUpdateCallback(mCurrentState, mUserData);
- map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState);
- if (uit != mOnUpdateState.end())
- uit->second(mUserData);
- // Recursive.
- if(isActive)
- return iterativeProcess();
- }
-
- void StateMachine::setMode(Mode mode)
- {
- mMode = mode;
- }
-
- void StateMachine::update()
- {
- switch (mMode)
- {
- case Mode::Iterative: iterativeProcess(); break;
- case Mode::Stepwise: stepwiseProcess(); break;
- }
- }
-
- bool StateMachine::processCondition(const Condition& condition)
- {
- map<int, Parameter>::iterator it = mParameters.find(condition.parameter);
- if (it == mParameters.end())
- {
- jin_log_error("The parameter <%d> is not exist", condition.parameter);
- return false;
- }
- Parameter& p = it->second;
- switch (p.type)
- {
- case ParameterType::Int:
- {
- int value = p.value._int;
- int cvalue = condition.value._int;
- bool is = false;
- is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false);
- is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false);
- is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false);
- return is;
- }
- case ParameterType::Float:
- {
- float value = p.value._float;
- float cvalue = condition.value._float;
- bool is = false;
- is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false);
- is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false);
- is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false);
- return is;
- }
- case ParameterType::Bool:
- {
- bool value = p.value._bool;
- bool cvalue = condition.value._bool;
- bool is = false;
- is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false);
- is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false);
- return is;
- }
- case ParameterType::Trigger:
- {
- bool is = p.value._trigger;
- // Close trigger.
- p.value._trigger = false;
- return is;
- }
- }
- return false;
- }
-
- int StateMachine::getCurrentState()
- {
- return mCurrentState;
- }
-
- void StateMachine::addParameteri(int name)
- {
- if (mParameters.find(name) != mParameters.end())
- {
- jin_log_error("The parameter <%d> is already exist.", name);
- return;
- }
- Parameter p;
- p.type = ParameterType::Int;
- p.value._int = 0;
- mParameters.insert(pair<int, Parameter>(name, p));
- }
-
- void StateMachine::addParameterf(int name)
- {
- if (mParameters.find(name) != mParameters.end())
- {
- jin_log_error("The parameter <%d> is already exist.", name);
- return;
- }
- Parameter p;
- p.type = ParameterType::Float;
- p.value._float = 0.0f;
- mParameters.insert(pair<int, Parameter>(name, p));
- }
-
- void StateMachine::addParameterb(int name)
- {
- if (mParameters.find(name) != mParameters.end())
- {
- jin_log_error("The parameter <%d> is already exist.", name);
- return;
- }
- Parameter p;
- p.type = ParameterType::Bool;
- p.value._bool = false;
- mParameters.insert(pair<int, Parameter>(name, p));
- }
-
- void StateMachine::addParametert(int name)
- {
- if (mParameters.find(name) != mParameters.end())
- {
- jin_log_error("The parameter <%d> is already exist.", name);
- return;
- }
- Parameter p;
- p.type = ParameterType::Trigger;
- p.value._trigger = false;
- mParameters.insert(pair<int, Parameter>(name, p));
- }
-
- void StateMachine::addState(int name)
- {
- if (mStates.find(name) != mStates.end())
- {
- jin_log_error("The state [%d] is already exist.", name);
- return;
- }
- State state;
- state.name = name;
- mStates.insert(pair<int, State>(name, state));
- }
-
- const char* StateMachine::parameterTypeString(ParameterType type)
- {
- switch (type)
- {
- case ParameterType::Int: return "int";
- case ParameterType::Float: return "float";
- case ParameterType::Bool: return "bool";
- case ParameterType::Trigger: return "trigger";
- }
- }
-
- void StateMachine::addTransition(int from, int to, const Conditions& conditions)
- {
- map<int, State>::iterator it;
- it = mStates.find(from);
- if (it == mStates.end())
- {
- jin_log_error("The state [%d] is not exist.", from);
- return;
- }
- State& fromState = it->second;
- it = mStates.find(to);
- if (it == mStates.end())
- {
- jin_log_error("The state [%d] is not exist.", to);
- return;
- }
- // Check condtion correctness.
- for (int i = 0; i < conditions.conditions.size(); ++i)
- {
- const Condition& condition = conditions.conditions[i];
- map<int, Parameter>::iterator itp;
- itp = mParameters.find(condition.parameter);
- if (itp == mParameters.end())
- {
- jin_log_error("The parameter <%d> is not exist.", condition.parameter);
- return;
- }
- Parameter& p = itp->second;
- if (p.type != condition.type)
- {
- jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value."
- , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type));
- return;
- }
- }
- // Add transition.
- Transition transition;
- transition.conditions = conditions;
- transition.state = to;
- fromState.transitions.push_back(transition);
- }
-
- void StateMachine::setParameteri(int name, int value)
- {
- map<int, Parameter>::iterator it = mParameters.find(name);
- if (it == mParameters.end())
- {
- jin_log_error("The state [%d] is not exist.", name);
- return;
- }
- Parameter& p = it->second;
- if (p.type != ParameterType::Int)
- {
- jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type));
- return;
- }
- p.value._int = value;
- }
-
- void StateMachine::setParameterf(int name, float value)
- {
- map<int, Parameter>::iterator it = mParameters.find(name);
- if (it == mParameters.end())
- {
- jin_log_error("The state [%d] is not exist.", name);
- return;
- }
- Parameter& p = it->second;
- if (p.type != ParameterType::Float)
- {
- jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type));
- return;
- }
- p.value._float = value;
- }
-
- void StateMachine::setParameterb(int name, bool value)
- {
- map<int, Parameter>::iterator it = mParameters.find(name);
- if (it == mParameters.end())
- {
- jin_log_error("The state %s is not exist.", name);
- return;
- }
- Parameter& p = it->second;
- if (p.type != ParameterType::Bool)
- {
- jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type));
- return;
- }
- p.value._bool = value;
- }
-
- void StateMachine::setParametert(int name)
- {
- map<int, Parameter>::iterator it = mParameters.find(name);
- if (it == mParameters.end())
- {
- jin_log_error("The state %s is not exist.", name);
- return;
- }
- Parameter& p = it->second;
- if (p.type != ParameterType::Trigger)
- {
- jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type));
- return;
- }
- p.value._trigger = true;
- }
-
- void StateMachine::forceToState(int name)
- {
- if (mStates.find(name) == mStates.end())
- {
- jin_log_error("The state [%d] is not exist.", name);
- return;
- }
- mCurrentState = name;
- }
-
- void StateMachine::addEnterListener(int state, const StateChangeCallback& callback)
- {
- if (mOnEnterState.find(state) != mOnEnterState.end())
- {
- jin_log_error("The enter listener of [%d] is already exist.", state);
- return;
- }
- mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback));
- }
-
- void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback)
- {
- if (mOnUpdateState.find(state) != mOnUpdateState.end())
- {
- jin_log_error("The update listener of [%d] is already exist.", state);
- return;
- }
- mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback));
- }
-
- void StateMachine::addExitListener(int state, const StateChangeCallback& callback)
- {
- if (mOnExitState.find(state) != mOnExitState.end())
- {
- jin_log_error("The exit listener of [%d] is already exist.", state);
- return;
- }
- mOnExitState.insert(pair<int, StateChangeCallback>(state, callback));
- }
-
- void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback)
- {
- if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end())
- {
- jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to);
- return;
- }
- pair<int, int> key(from, to);
- mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback));
- }
-
- void StateMachine::setUpdateListener(const SingleStateCallback& callback)
- {
- mUpdateCallback = callback;
- }
-
- void StateMachine::setEnterListener(const SingleStateCallback& callback)
- {
- mEnterCallback = callback;
- }
-
- void StateMachine::setExitListener(const SingleStateCallback& callback)
- {
- mExitCallback = callback;
- }
-
- void StateMachine::setTranslateListener(const DoubleStateCallback& callback)
- {
- mTraslateCallback = callback;
- }
-
- } // namespace AI
+ namespace AI
+ {
+
+ StateMachine::StateMachine(Mode mode, void* userdata)
+ : mCurrentState(0)
+ , mUserData(userdata)
+ , mMode(mode)
+ {
+ addState(0);
+ }
+
+ StateMachine::~StateMachine()
+ {
+ }
+
+ void StateMachine::invokeCallback(int from, int to)
+ {
+ if (mExitCallback != nullptr)
+ mExitCallback(from, mUserData);
+ if (mTraslateCallback != nullptr)
+ mTraslateCallback(from, to, mUserData);
+ if (mEnterCallback != nullptr)
+ mEnterCallback(to, mUserData);
+ map<int, StateChangeCallback>::iterator it = mOnExitState.find(from);
+ if (it != mOnExitState.end())
+ it->second(mUserData);
+ map<pair<int, int>, StateTranslateCallback>::iterator transItr
+ = mOnStateTranslate.find(pair<int, int>(from, to));
+ if (transItr != mOnStateTranslate.end())
+ transItr->second(mUserData);
+ it = mOnEnterState.find(to);
+ if (it != mOnEnterState.end())
+ it->second(mUserData);
+ }
+
+ void StateMachine::stepwiseProcess()
+ {
+ map<int, State>::iterator it = mStates.find(mCurrentState);
+ if (it == mStates.end())
+ {
+ jin_log_error("The state [%d] is not exist.", mCurrentState);
+ return;
+ }
+ State& state = it->second;
+ for (int i = 0; i < state.transitions.size(); ++i)
+ {
+ 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);
+ break;
+ }
+ }
+ // Call update
+ if (mUpdateCallback != nullptr)
+ mUpdateCallback(mCurrentState, mUserData);
+ map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState);
+ if (uit != mOnUpdateState.end())
+ uit->second(mUserData);
+ }
+
+ void StateMachine::iterativeProcess()
+ {
+ map<int, State>::iterator it = mStates.find(mCurrentState);
+ if (it == mStates.end())
+ {
+ jin_log_error("The state [%d] is not exist.", mCurrentState);
+ return;
+ }
+ State& state = it->second;
+ bool isActive = true;
+ for (int i = 0; i < state.transitions.size(); ++i)
+ {
+ Conditions conditions = state.transitions[i].conditions;
+ 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);
+ break;
+ }
+ }
+ // Call update
+ if (mUpdateCallback != nullptr)
+ mUpdateCallback(mCurrentState, mUserData);
+ map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState);
+ if (uit != mOnUpdateState.end())
+ uit->second(mUserData);
+ // Recursive.
+ if(isActive)
+ return iterativeProcess();
+ }
+
+ void StateMachine::setMode(Mode mode)
+ {
+ mMode = mode;
+ }
+
+ void StateMachine::update()
+ {
+ switch (mMode)
+ {
+ case Mode::Iterative: iterativeProcess(); break;
+ case Mode::Stepwise: stepwiseProcess(); break;
+ }
+ }
+
+ bool StateMachine::processCondition(const Condition& condition)
+ {
+ map<int, Parameter>::iterator it = mParameters.find(condition.parameter);
+ if (it == mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is not exist", condition.parameter);
+ return false;
+ }
+ Parameter& p = it->second;
+ switch (p.type)
+ {
+ case ParameterType::Int:
+ {
+ int value = p.value._int;
+ int cvalue = condition.value._int;
+ bool is = false;
+ is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false);
+ is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false);
+ is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false);
+ return is;
+ }
+ case ParameterType::Float:
+ {
+ float value = p.value._float;
+ float cvalue = condition.value._float;
+ bool is = false;
+ is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false);
+ is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false);
+ is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false);
+ return is;
+ }
+ case ParameterType::Bool:
+ {
+ bool value = p.value._bool;
+ bool cvalue = condition.value._bool;
+ bool is = false;
+ is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false);
+ is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false);
+ return is;
+ }
+ case ParameterType::Trigger:
+ {
+ bool is = p.value._trigger;
+ // Close trigger.
+ p.value._trigger = false;
+ return is;
+ }
+ }
+ return false;
+ }
+
+ int StateMachine::getCurrentState()
+ {
+ return mCurrentState;
+ }
+
+ void StateMachine::addParameteri(int name)
+ {
+ if (mParameters.find(name) != mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is already exist.", name);
+ return;
+ }
+ Parameter p;
+ p.type = ParameterType::Int;
+ p.value._int = 0;
+ mParameters.insert(pair<int, Parameter>(name, p));
+ }
+
+ void StateMachine::addParameterf(int name)
+ {
+ if (mParameters.find(name) != mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is already exist.", name);
+ return;
+ }
+ Parameter p;
+ p.type = ParameterType::Float;
+ p.value._float = 0.0f;
+ mParameters.insert(pair<int, Parameter>(name, p));
+ }
+
+ void StateMachine::addParameterb(int name)
+ {
+ if (mParameters.find(name) != mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is already exist.", name);
+ return;
+ }
+ Parameter p;
+ p.type = ParameterType::Bool;
+ p.value._bool = false;
+ mParameters.insert(pair<int, Parameter>(name, p));
+ }
+
+ void StateMachine::addParametert(int name)
+ {
+ if (mParameters.find(name) != mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is already exist.", name);
+ return;
+ }
+ Parameter p;
+ p.type = ParameterType::Trigger;
+ p.value._trigger = false;
+ mParameters.insert(pair<int, Parameter>(name, p));
+ }
+
+ void StateMachine::addState(int name)
+ {
+ if (mStates.find(name) != mStates.end())
+ {
+ jin_log_error("The state [%d] is already exist.", name);
+ return;
+ }
+ State state;
+ state.name = name;
+ mStates.insert(pair<int, State>(name, state));
+ }
+
+ const char* StateMachine::parameterTypeString(ParameterType type)
+ {
+ switch (type)
+ {
+ case ParameterType::Int: return "int";
+ case ParameterType::Float: return "float";
+ case ParameterType::Bool: return "bool";
+ case ParameterType::Trigger: return "trigger";
+ }
+ }
+
+ void StateMachine::addTransition(int from, int to, const Conditions& conditions)
+ {
+ map<int, State>::iterator it;
+ it = mStates.find(from);
+ if (it == mStates.end())
+ {
+ jin_log_error("The state [%d] is not exist.", from);
+ return;
+ }
+ State& fromState = it->second;
+ it = mStates.find(to);
+ if (it == mStates.end())
+ {
+ jin_log_error("The state [%d] is not exist.", to);
+ return;
+ }
+ // Check condtion correctness.
+ for (int i = 0; i < conditions.conditions.size(); ++i)
+ {
+ const Condition& condition = conditions.conditions[i];
+ map<int, Parameter>::iterator itp;
+ itp = mParameters.find(condition.parameter);
+ if (itp == mParameters.end())
+ {
+ jin_log_error("The parameter <%d> is not exist.", condition.parameter);
+ return;
+ }
+ Parameter& p = itp->second;
+ if (p.type != condition.type)
+ {
+ jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value."
+ , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type));
+ return;
+ }
+ }
+ // Add transition.
+ Transition transition;
+ transition.conditions = conditions;
+ transition.state = to;
+ fromState.transitions.push_back(transition);
+ }
+
+ void StateMachine::setParameteri(int name, int value)
+ {
+ map<int, Parameter>::iterator it = mParameters.find(name);
+ if (it == mParameters.end())
+ {
+ jin_log_error("The state [%d] is not exist.", name);
+ return;
+ }
+ Parameter& p = it->second;
+ if (p.type != ParameterType::Int)
+ {
+ jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type));
+ return;
+ }
+ p.value._int = value;
+ }
+
+ void StateMachine::setParameterf(int name, float value)
+ {
+ map<int, Parameter>::iterator it = mParameters.find(name);
+ if (it == mParameters.end())
+ {
+ jin_log_error("The state [%d] is not exist.", name);
+ return;
+ }
+ Parameter& p = it->second;
+ if (p.type != ParameterType::Float)
+ {
+ jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type));
+ return;
+ }
+ p.value._float = value;
+ }
+
+ void StateMachine::setParameterb(int name, bool value)
+ {
+ map<int, Parameter>::iterator it = mParameters.find(name);
+ if (it == mParameters.end())
+ {
+ jin_log_error("The state %s is not exist.", name);
+ return;
+ }
+ Parameter& p = it->second;
+ if (p.type != ParameterType::Bool)
+ {
+ jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type));
+ return;
+ }
+ p.value._bool = value;
+ }
+
+ void StateMachine::setParametert(int name)
+ {
+ map<int, Parameter>::iterator it = mParameters.find(name);
+ if (it == mParameters.end())
+ {
+ jin_log_error("The state %s is not exist.", name);
+ return;
+ }
+ Parameter& p = it->second;
+ if (p.type != ParameterType::Trigger)
+ {
+ jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type));
+ return;
+ }
+ p.value._trigger = true;
+ }
+
+ void StateMachine::forceToState(int name)
+ {
+ if (mStates.find(name) == mStates.end())
+ {
+ jin_log_error("The state [%d] is not exist.", name);
+ return;
+ }
+ mCurrentState = name;
+ }
+
+ void StateMachine::addEnterListener(int state, const StateChangeCallback& callback)
+ {
+ if (mOnEnterState.find(state) != mOnEnterState.end())
+ {
+ jin_log_error("The enter listener of [%d] is already exist.", state);
+ return;
+ }
+ mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback));
+ }
+
+ void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback)
+ {
+ if (mOnUpdateState.find(state) != mOnUpdateState.end())
+ {
+ jin_log_error("The update listener of [%d] is already exist.", state);
+ return;
+ }
+ mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback));
+ }
+
+ void StateMachine::addExitListener(int state, const StateChangeCallback& callback)
+ {
+ if (mOnExitState.find(state) != mOnExitState.end())
+ {
+ jin_log_error("The exit listener of [%d] is already exist.", state);
+ return;
+ }
+ mOnExitState.insert(pair<int, StateChangeCallback>(state, callback));
+ }
+
+ void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback)
+ {
+ if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end())
+ {
+ jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to);
+ return;
+ }
+ pair<int, int> key(from, to);
+ mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback));
+ }
+
+ void StateMachine::setUpdateListener(const SingleStateCallback& callback)
+ {
+ mUpdateCallback = callback;
+ }
+
+ void StateMachine::setEnterListener(const SingleStateCallback& callback)
+ {
+ mEnterCallback = callback;
+ }
+
+ void StateMachine::setExitListener(const SingleStateCallback& callback)
+ {
+ mExitCallback = callback;
+ }
+
+ void StateMachine::setTranslateListener(const DoubleStateCallback& callback)
+ {
+ mTraslateCallback = callback;
+ }
+
+ } // namespace AI
} // namespace JinEngine \ No newline at end of file