SimpleAI
 All Classes Namespaces Files Functions Variables Typedefs Macros Groups Pages
LUAFilter.h
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include "IFilter.h"
9 #include "LUAFunctions.h"
10 
11 namespace ai {
12 
16 class LUAFilter : public IFilter {
17 protected:
18  lua_State* _s;
19 
20  void filterLUA(const AIPtr& entity) {
21  // get userdata of the filter
22  const std::string name = "__meta_filter_" + _name;
23  lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
24 #if AI_LUA_SANTITY > 0
25  if (lua_isnil(_s, -1)) {
26  ai_log_error("LUA filter: could not find lua userdata for %s", _name.c_str());
27  return;
28  }
29 #endif
30  // get metatable
31  lua_getmetatable(_s, -1);
32 #if AI_LUA_SANTITY > 0
33  if (!lua_istable(_s, -1)) {
34  ai_log_error("LUA filter: userdata for %s doesn't have a metatable assigned", _name.c_str());
35  return;
36  }
37 #endif
38  // get filter() method
39  lua_getfield(_s, -1, "filter");
40  if (!lua_isfunction(_s, -1)) {
41  ai_log_error("LUA filter: metatable for %s doesn't have the filter() function assigned", _name.c_str());
42  return;
43  }
44 
45  // push self onto the stack
46  lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
47 
48  // first parameter is ai
49  if (luaAI_pushai(_s, entity) == 0) {
50  return;
51  }
52 #if AI_LUA_SANTITY > 0
53  if (!lua_isfunction(_s, -3)) {
54  ai_log_error("LUA filter: expected to find a function on stack -3");
55  return;
56  }
57  if (!lua_isuserdata(_s, -2)) {
58  ai_log_error("LUA filter: expected to find the userdata on -2");
59  return;
60  }
61  if (!lua_isuserdata(_s, -1)) {
62  ai_log_error("LUA filter: second parameter should be the ai");
63  return;
64  }
65 #endif
66  const int error = lua_pcall(_s, 2, 0, 0);
67  if (error) {
68  ai_log_error("LUA filter script: %s", lua_isstring(_s, -1) ? lua_tostring(_s, -1) : "Unknown Error");
69  }
70 
71  // reset stack
72  lua_pop(_s, lua_gettop(_s));
73  }
74 
75 public:
77  private:
78  lua_State* _s;
79  std::string _type;
80  public:
81  LUAFilterFactory(lua_State* s, const std::string& typeStr) :
82  _s(s), _type(typeStr) {
83  }
84 
85  inline const std::string& type() const {
86  return _type;
87  }
88 
89  FilterPtr create(const FilterFactoryContext* ctx) const override {
90  return std::make_shared<LUAFilter>(_type, ctx->parameters, _s);
91  }
92  };
93 
94  LUAFilter(const std::string& name, const std::string& parameters, lua_State* s) :
95  IFilter(name, parameters), _s(s) {
96  }
97 
98  ~LUAFilter() {
99  }
100 
101  void filter(const AIPtr& entity) override {
102 #if AI_EXCEPTIONS
103  try {
104 #endif
105  filterLUA(entity);
106 #if AI_EXCEPTIONS
107  } catch (...) {
108  ai_log_error("Exception while evaluating lua filter");
109  }
110 #endif
111  }
112 };
113 
114 }
#define ai_log_error(...)
Logging macro to provide your own loggers.
Definition: Types.h:23
Definition: AIFactories.h:89
Definition: LUAFilter.h:16
Definition: AIFactories.h:34
Definition: LUAFilter.h:76