SimpleAI
 All Classes Namespaces Files Functions Variables Typedefs Macros Groups Pages
ICondition.h
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include <string>
12 #include <vector>
13 #include <sstream>
14 #include <memory>
15 
16 #include "common/MemoryAllocator.h"
17 #include "common/Thread.h"
18 
19 #include "AIFactories.h"
20 
21 namespace ai {
22 
23 class AI;
24 typedef std::shared_ptr<AI> AIPtr;
25 
29 #define CONDITION_CLASS(ConditionName) \
30  explicit ConditionName(const std::string& parameters = "") : \
31  ::ai::ICondition(#ConditionName, parameters) { \
32  } \
33 public: \
34  virtual ~ConditionName() { \
35  }
36 
41 #define CONDITION_FACTORY_NO_IMPL(ConditionName) \
42 public: \
43  class Factory: public ::ai::IConditionFactory { \
44  public: \
45  ::ai::ConditionPtr create (const ::ai::ConditionFactoryContext *ctx) const override; \
46  }; \
47  static const Factory& getFactory() { \
48  static Factory FACTORY; \
49  return FACTORY; \
50  }
51 
55 #define CONDITION_FACTORY(ConditionName) \
56 public: \
57  class Factory: public ::ai::IConditionFactory { \
58  public: \
59  ::ai::ConditionPtr create (const ::ai::ConditionFactoryContext *ctx) const override { \
60  return std::make_shared<ConditionName>(ctx->parameters); \
61  } \
62  }; \
63  static const Factory& getFactory() { \
64  static Factory FACTORY; \
65  return FACTORY; \
66  }
67 
73 #define CONDITION_FACTORY_SINGLETON \
74 public: \
75  class Factory: public ::ai::IConditionFactory { \
76  ::ai::ConditionPtr create (const ::ai::ConditionFactoryContext */*ctx*/) const { \
77  return get(); \
78  } \
79  }; \
80  static const Factory& getFactory() { \
81  static Factory FACTORY; \
82  return FACTORY; \
83  }
84 
88 #define CONDITION_CLASS_SINGLETON(ConditionName) \
89 private: \
90  CONDITION_CLASS(ConditionName) \
91 public: \
92  static ConditionPtr& get() { \
93  AI_THREAD_LOCAL ConditionName* c = nullptr; \
94  if (c == nullptr) { c = new ConditionName; } \
95  AI_THREAD_LOCAL ConditionPtr _instance(c); \
96  return _instance; \
97  } \
98  CONDITION_FACTORY_SINGLETON
99 
100 #define CONDITION_PRINT_SUBCONDITIONS_GETCONDITIONNAMEWITHVALUE \
101  void getConditionNameWithValue(std::stringstream& s, const ::ai::AIPtr& entity) override { \
102  bool first = true; \
103  s << "("; \
104  for (::ai::ConditionsConstIter i = _conditions.begin(); i != _conditions.end(); ++i) { \
105  if (!first) { \
106  s << ","; \
107  } \
108  s << (*i)->getNameWithConditions(entity); \
109  first = false; \
110  } \
111  s << ")"; \
112  }
113 
114 class ICondition;
115 typedef std::shared_ptr<ICondition> ConditionPtr;
116 typedef std::vector<ConditionPtr> Conditions;
117 typedef Conditions::iterator ConditionsIter;
118 typedef Conditions::const_iterator ConditionsConstIter;
119 
124 class ICondition : public MemObject {
125 protected:
126  static int getNextId() {
127  static int _nextId = 0;
128  const int id = _nextId++;
129  return id;
130  }
131 
135  int _id;
136  const std::string _name;
137  const std::string _parameters;
138 
146  virtual void getConditionNameWithValue(std::stringstream& s, const AIPtr& entity) {
147  (void)entity;
148  s << "{" << _parameters << "}";
149  }
150 public:
151  ICondition(const std::string& name, const std::string& parameters) :
152  _id(getNextId()), _name(name), _parameters(parameters) {
153  }
154 
155  virtual ~ICondition() {
156  }
157 
163  virtual bool evaluate(const AIPtr& entity) = 0;
164 
168  const std::string& getName() const;
169 
173  const std::string& getParameters() const;
174 
180  inline std::string getNameWithConditions(const AIPtr& entity) {
181  std::stringstream s;
182  s << getName();
183  getConditionNameWithValue(s, entity);
184  s << "[";
185  s << (evaluate(entity) ? "1" : "0");
186  s << "]";
187  return s.str();
188  }
189 };
190 
191 inline const std::string& ICondition::getName() const {
192  return _name;
193 }
194 
195 inline const std::string& ICondition::getParameters() const {
196  return _parameters;
197 }
198 
199 }
200 
A condition can be placed on a TreeNode to decide which node is going to get executed. In general they are stateless. If they are not, it should explicitly get noted.
Definition: ICondition.h:124
virtual bool evaluate(const AIPtr &entity)=0
Checks whether the condition evaluates to true for the given entity.
Definition: MemoryAllocator.h:26
virtual void getConditionNameWithValue(std::stringstream &s, const AIPtr &entity)
Override this method to get a more detailed result in getNameWithConditions()
Definition: ICondition.h:146
int _id
Every node has an id to identify it. It's unique per type.
Definition: ICondition.h:135
std::string getNameWithConditions(const AIPtr &entity)
Returns the full condition string with all related conditions and results of the evaluation method...
Definition: ICondition.h:180
const std::string & getParameters() const
Returns the raw parameters of the condition.
Definition: ICondition.h:195
const std::string & getName() const
Returns the short name of the condition - without any related conditions or results.
Definition: ICondition.h:191