aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-11-06 16:12:56 +0800
committerchai <chaifix@163.com>2018-11-06 16:12:56 +0800
commit9c5dc853ec5ceba809e7f02cdde87c90544a45e1 (patch)
tree709bcc9409c8088a0d2be83ab14ddd230512b23f /src
parent1d1210d7932b287d66e27157701b92df764528cb (diff)
*状态机条件使用多重条件
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/buildvm/buildvm.exebin123392 -> 121856 bytes
-rw-r--r--src/3rdparty/minilua/minilua.exebin219136 -> 209920 bytes
-rw-r--r--src/libjin/Time/je_timer.cpp18
-rw-r--r--src/libjin/Time/je_timer.h5
-rw-r--r--src/libjin/ai/je_state_machine.cpp217
-rw-r--r--src/libjin/ai/je_state_machine.h199
6 files changed, 235 insertions, 204 deletions
diff --git a/src/3rdparty/buildvm/buildvm.exe b/src/3rdparty/buildvm/buildvm.exe
index c1e069e..8d16380 100644
--- a/src/3rdparty/buildvm/buildvm.exe
+++ b/src/3rdparty/buildvm/buildvm.exe
Binary files differ
diff --git a/src/3rdparty/minilua/minilua.exe b/src/3rdparty/minilua/minilua.exe
index 09b1820..e383b6f 100644
--- a/src/3rdparty/minilua/minilua.exe
+++ b/src/3rdparty/minilua/minilua.exe
Binary files differ
diff --git a/src/libjin/Time/je_timer.cpp b/src/libjin/Time/je_timer.cpp
index 94ab747..fcd805c 100644
--- a/src/libjin/Time/je_timer.cpp
+++ b/src/libjin/Time/je_timer.cpp
@@ -36,6 +36,17 @@ namespace JinEngine
}
}
+ void Timer::cancel(Handler* handler)
+ {
+ handler->canceled = true;
+ }
+
+ void Timer::cancelAll()
+ {
+ for (auto h : mHandlers)
+ cancel(h);
+ }
+
Timer::Handler* Timer::every(int ms, TimerCallback callback, void* p)
{
Handler* t = new Handler(Handler::EVERY, ms, 0, callback, p);
@@ -79,7 +90,7 @@ namespace JinEngine
if (tickdown <= 0)
{
tickdown = duration;
- if (callback != nullptr)
+ if (!canceled && callback != nullptr)
callback(paramters);
if (type == EVERY)
{
@@ -97,11 +108,6 @@ namespace JinEngine
}
}
- void Timer::cancel(Handler* handler)
- {
- handler->canceled = true;
- }
-
} // namespace Time
} // namespace JinEngine
diff --git a/src/libjin/Time/je_timer.h b/src/libjin/Time/je_timer.h
index d0e5513..1310890 100644
--- a/src/libjin/Time/je_timer.h
+++ b/src/libjin/Time/je_timer.h
@@ -82,6 +82,11 @@ namespace JinEngine
///
void cancel(Handler* handler = nullptr);
+ ///
+ ///
+ ///
+ void cancelAll();
+
private:
std::vector<Handler*> mHandlers;
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;
diff --git a/src/libjin/ai/je_state_machine.h b/src/libjin/ai/je_state_machine.h
index 1765e97..f53137e 100644
--- a/src/libjin/ai/je_state_machine.h
+++ b/src/libjin/ai/je_state_machine.h
@@ -7,6 +7,7 @@
#include <map>
#include <vector>
+#include "../common/je_temporary.h"
#include "../common/je_types.h"
#include "../common/je_object.h"
@@ -14,23 +15,14 @@ namespace JinEngine
{
namespace AI
{
+ // Grab from Unity.
///
/// A single layer statemachine.
///
class StateMachine : public Object
{
- public:
-
- ///
- ///
- ///
- enum Mode
- {
- Iterative, ///< Process until reach condition failed.(May cause endless loop)
- Stepwise ///< Process one state each update.
- };
-
+ public:
///
///
///
@@ -48,6 +40,113 @@ namespace JinEngine
BOOL_NOT = 0x100,
};
+ private:
+ ///
+ ///
+ ///
+ enum ParameterType
+ {
+ Int, ///< A integer value.
+ Float, ///< A float value.
+ Bool, ///< A bool value.
+ Trigger ///< A trigger will be reset to false after activated.
+ };
+
+ ///
+ ///
+ ///
+ union ParameterValue
+ {
+ int _int; ///< 0 by default.
+ float _float; ///< 0 by default.
+ bool _bool; ///< false by default.
+ bool _trigger; ///< false by default.
+ };
+
+ ///
+ /// Traslation's condition.
+ ///
+ struct Condition
+ {
+ std::string parameter;
+ ParameterExpression expression;
+ ParameterType type;
+ ParameterValue value;
+ };
+
+ public:
+ ///
+ ///
+ ///
+ enum Mode
+ {
+ Iterative, ///< Process until reach condition failed.(May cause endless loop)
+ Stepwise ///< Process one state each update.
+ };
+
+ struct Conditions : Temporary
+ {
+ Conditions()
+ {
+ }
+
+ Conditions(const Conditions& condition)
+ {
+ conditions = condition.conditions;
+ }
+
+ void operator = (const Conditions& condition)
+ {
+ conditions = condition.conditions;
+ }
+
+ inline Conditions& andi(const std::string& parameter, ParameterExpression expression, int value)
+ {
+ Condition condition;
+ condition.expression = expression;
+ condition.parameter = parameter;
+ condition.value._int = value;
+ condition.type = ParameterType::Int;
+ conditions.push_back(condition);
+ return *this;
+ }
+
+ inline Conditions& andf(const std::string& parameter, ParameterExpression expression , float value)
+ {
+ Condition condition;
+ condition.expression = expression;
+ condition.parameter = parameter;
+ condition.value._int = value;
+ condition.type = ParameterType::Float;
+ conditions.push_back(condition);
+ return *this;
+ }
+
+ inline Conditions& andb(const std::string& parameter, ParameterExpression expression, bool value)
+ {
+ Condition condition;
+ condition.expression = expression;
+ condition.parameter = parameter;
+ condition.value._int = value;
+ condition.type = ParameterType::Bool;
+ conditions.push_back(condition);
+ return *this;
+ }
+
+ inline Conditions& andt(const std::string& parameter)
+ {
+ Condition condition;
+ condition.parameter = parameter;
+ condition.type = ParameterType::Trigger;
+ conditions.push_back(condition);
+ return *this;
+ }
+
+ private:
+ friend class StateMachine;
+ std::vector<Condition> conditions;
+ };
+
///
///
///
@@ -56,6 +155,11 @@ namespace JinEngine
///
///
///
+ typedef void(StateUpdateCallback)(void* userdata);
+
+ ///
+ ///
+ ///
typedef void(StateTranslateCallback)(void* userdata);
///
@@ -117,26 +221,11 @@ namespace JinEngine
/// Add a state.
///
void addState(const std::string& name);
-
- ///
- ///
- ///
- void addTransitioni(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression condition, int value);
-
- ///
- ///
- ///
- void addTransitionf(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression condition, float value);
-
- ///
- ///
- ///
- void addTransitionb(const std::string& stateFrom, const std::string& stateTo, const std::string& name, ParameterExpression condition, bool value);
-
+
///
///
///
- void addTransitiont(const std::string& stateFrom, const std::string& stateTo, const std::string& name);
+ void addTransition(const std::string& from, const std::string& to, const Conditions& conditions);
///
/// Set parameter value.
@@ -169,6 +258,11 @@ namespace JinEngine
void addEnterListener(const std::string& state, StateChangeCallback* callback);
///
+ /// Call state update function.
+ ///
+ void addUpdateListener(const std::string& state, StateUpdateCallback* callback);
+
+ ///
///
///
void addExitListener(const std::string& state, StateChangeCallback* callback);
@@ -186,6 +280,11 @@ namespace JinEngine
///
///
///
+ void setUpdateListener(SingleStateCallback* callback);
+
+ ///
+ ///
+ ///
void setExitListener(SingleStateCallback* callback);
///
@@ -195,45 +294,19 @@ namespace JinEngine
private:
- enum ParameterType
- {
- Int, ///< A integer value.
- Float, ///< A float value.
- Bool, ///< A bool value.
- Trigger ///< A trigger will be reset to false after activated.
- };
-
- union ParameterValue
- {
- int _int; ///< 0 by default.
- float _float; ///< 0 by default.
- bool _bool; ///< false by default.
- bool _trigger; ///< false by default.
- };
-
struct Parameter
{
ParameterType type;
ParameterValue value;
};
- ///
- /// Traslation's condition.
- ///
- struct Condition
- {
- std::string parameter;
- ParameterExpression expression;
- ParameterValue value;
- };
-
///
/// Translate to another state.
///
struct Transition
{
- Condition condition; ///< Condition to active transition.
- std::string state; ///< State to translate to.
+ Conditions conditions; ///< Condition to active transition.
+ std::string state; ///< State to translate to.
};
///
@@ -284,6 +357,11 @@ namespace JinEngine
///
///
///
+ std::map<std::string, StateUpdateCallback*> mOnUpdateState;
+
+ ///
+ ///
+ ///
std::map<std::string, StateChangeCallback*> mOnExitState;
///
@@ -294,8 +372,13 @@ namespace JinEngine
///
///
///
- SingleStateCallback* mEnterCallback;
-
+ SingleStateCallback* mEnterCallback;
+
+ ///
+ ///
+ ///
+ SingleStateCallback* mUpdateCallback;
+
///
///
///