aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/ai/je_state_machine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/ai/je_state_machine.cpp')
-rw-r--r--src/libjin/ai/je_state_machine.cpp217
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;