SimpleAI
 All Classes Namespaces Files Functions Variables Typedefs Macros Groups Pages
LUASteering.h
Go to the documentation of this file.
1 
5 #pragma once
6 
7 #include "Steering.h"
8 #include "LUAFunctions.h"
9 
10 namespace ai {
11 namespace movement {
12 
16 class LUASteering : public ISteering {
17 protected:
18  mutable lua_State* _s;
19  std::string _type;
20 
21  MoveVector executeLUA(const AIPtr& entity, float speed) const {
22  // get userdata of the behaviour tree steering
23  const std::string name = "__meta_steering_" + _type;
24  lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
25 #if AI_LUA_SANTITY > 0
26  if (lua_isnil(_s, -1)) {
27  ai_log_error("LUA steering: could not find lua userdata for %s", name.c_str());
28  return MoveVector(VEC3_INFINITE, 0.0f);
29  }
30 #endif
31  // get metatable
32  lua_getmetatable(_s, -1);
33 #if AI_LUA_SANTITY > 0
34  if (!lua_istable(_s, -1)) {
35  ai_log_error("LUA steering: userdata for %s doesn't have a metatable assigned", name.c_str());
36  return MoveVector(VEC3_INFINITE, 0.0f);
37  }
38 #endif
39  // get execute() method
40  lua_getfield(_s, -1, "execute");
41  if (!lua_isfunction(_s, -1)) {
42  ai_log_error("LUA steering: metatable for %s doesn't have the execute() function assigned", name.c_str());
43  return MoveVector(VEC3_INFINITE, 0.0f);
44  }
45 
46  // push self onto the stack
47  lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
48 
49  // first parameter is ai
50  if (luaAI_pushai(_s, entity) == 0) {
51  return MoveVector(VEC3_INFINITE, 0.0f);
52  }
53 
54  // second parameter is speed
55  lua_pushnumber(_s, speed);
56 
57 #if AI_LUA_SANTITY > 0
58  if (!lua_isfunction(_s, -4)) {
59  ai_log_error("LUA steering: expected to find a function on stack -4");
60  return MoveVector(VEC3_INFINITE, 0.0f);
61  }
62  if (!lua_isuserdata(_s, -3)) {
63  ai_log_error("LUA steering: expected to find the userdata on -3");
64  return MoveVector(VEC3_INFINITE, 0.0f);
65  }
66  if (!lua_isuserdata(_s, -2)) {
67  ai_log_error("LUA steering: second parameter should be the ai");
68  return MoveVector(VEC3_INFINITE, 0.0f);
69  }
70  if (!lua_isnumber(_s, -1)) {
71  ai_log_error("LUA steering: first parameter should be the speed");
72  return MoveVector(VEC3_INFINITE, 0.0f);
73  }
74 #endif
75  const int error = lua_pcall(_s, 3, 4, 0);
76  if (error) {
77  ai_log_error("LUA steering script: %s", lua_isstring(_s, -1) ? lua_tostring(_s, -1) : "Unknown Error");
78  // reset stack
79  lua_pop(_s, lua_gettop(_s));
80  return MoveVector(VEC3_INFINITE, 0.0f);
81  }
82  // we get four values back, the direction vector and the
83  const lua_Number x = luaL_checknumber(_s, -1);
84  const lua_Number y = luaL_checknumber(_s, -2);
85  const lua_Number z = luaL_checknumber(_s, -3);
86  const lua_Number rotation = luaL_checknumber(_s, -4);
87 
88  // reset stack
89  lua_pop(_s, lua_gettop(_s));
90  return MoveVector(glm::vec3((float)x, (float)y, (float)z), (float)rotation);
91  }
92 
93 public:
95  private:
96  lua_State* _s;
97  std::string _type;
98  public:
99  LUASteeringFactory(lua_State* s, const std::string& typeStr) :
100  _s(s), _type(typeStr) {
101  }
102 
103  inline const std::string& type() const {
104  return _type;
105  }
106 
107  SteeringPtr create(const SteeringFactoryContext* ctx) const override {
108  return std::make_shared<LUASteering>(_s, _type);
109  }
110  };
111 
112  LUASteering(lua_State* s, const std::string& type) :
113  ISteering(), _s(s) {
114  _type = type;
115  }
116 
117  ~LUASteering() {
118  }
119 
120  MoveVector execute(const AIPtr& entity, float speed) const override {
121 #if AI_EXCEPTIONS
122  try {
123 #endif
124  return executeLUA(entity, speed);
125 #if AI_EXCEPTIONS
126  } catch (...) {
127  ai_log_error("Exception while running lua steering");
128  }
129  return MoveVector(VEC3_INFINITE, 0.0f);
130 #endif
131  }
132 };
133 
134 }
135 }
#define ai_log_error(...)
Logging macro to provide your own loggers.
Definition: Types.h:23
Definition: MoveVector.h:10
Defines some basic movement algorithms like Wandering, Seeking and Fleeing.
Definition: AIFactories.h:43
MoveVector execute(const AIPtr &entity, float speed) const override
Calculates the MoveVector.
Definition: LUASteering.h:120
Steering interface.
Definition: Steering.h:47
Definition: AIFactories.h:75
Definition: LUASteering.h:16