The Battle for Wesnoth  1.15.2+dev
lua_object.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2018 by Dmitry Kovalenko <nephro.wes@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Lua object(value) wrapper implementation
18  */
19 
20 
21 #ifndef LUA_OBJECT_HPP_INCLUDED
22 #define LUA_OBJECT_HPP_INCLUDED
23 
24 #include "config.hpp"
25 #include "lua/lua.h"
26 #include "map/location.hpp"
27 #include "resources.hpp"
28 #include "scripting/lua_common.hpp"
29 #include "terrain/filter.hpp"
30 #include "variable.hpp"
31 #include "ai/default/contexts.hpp"
33 
34 #include <iterator>
35 #include <string>
36 #include <vector>
37 
38 
39 namespace ai {
40 
41 
43 
44 public:
46  virtual ~lua_object_base() {}
47 
48  virtual void store(lua_State* L, int n) = 0;
49 };
50 
51 template <typename T>
53 {
54 
55 public:
56 
58  : value_()
59  {
60  // empty
61  }
62 
63  lua_object(const T& init)
64  : value_(std::make_shared<T>(init))
65  {
66  // empty
67  }
68 
69  std::shared_ptr<T> get()
70  {
71  return value_;
72  }
73 
74  void store(lua_State* L, int n)
75  {
76  this->value_ = to_type(L, lua_absindex(L, n));
77  }
78 
79  void push(lua_State* L)
80  {
81  from_type(L, this->value_);
82  }
83 
84 protected:
85 
86  // A group of functions that deal with the translation of the results to C++
87  std::shared_ptr<T> to_type(lua_State *, int)
88  {
89  return std::shared_ptr<T>();
90  }
91 
92  // A group of functions that deal with the translations of values back to Lua
93  void from_type(lua_State* L, std::shared_ptr<T>)
94  {
95  lua_pushliteral(L, "Unsupported AI aspect type for Lua!");
96  lua_error(L);
97  }
98 
99  std::shared_ptr<T> value_;
100 };
101 
102 template <>
103 inline std::shared_ptr<double> lua_object<double>::to_type(lua_State *L, int n)
104 {
105  return std::make_shared<double>(lua_tonumber(L, n));
106 }
107 
108 template <>
109 inline void lua_object<double>::from_type(lua_State *L, std::shared_ptr<double> value)
110 {
111  if(value) lua_pushnumber(L, *value);
112  else lua_pushnil(L);
113 }
114 
115 template <>
116 inline std::shared_ptr<std::string> lua_object<std::string>::to_type(lua_State *L, int n)
117 {
118  return std::make_shared<std::string>(lua_tostring(L, n));
119 }
120 
121 template <>
122 inline void lua_object<std::string>::from_type(lua_State *L, std::shared_ptr<std::string> value)
123 {
124  if(value) lua_pushlstring(L, value->c_str(), value->size());
125  else lua_pushnil(L);
126 }
127 
128 template <>
129 inline std::shared_ptr<bool> lua_object<bool>::to_type(lua_State *L, int n)
130 {
131  return std::make_shared<bool>(luaW_toboolean(L, n));
132 }
133 
134 template <>
135 inline void lua_object<bool>::from_type(lua_State *L, std::shared_ptr<bool> value)
136 {
137  if(value) lua_pushboolean(L, *value);
138  else lua_pushnil(L);
139 }
140 
141 template <>
142 inline std::shared_ptr<int> lua_object<int>::to_type(lua_State *L, int n)
143 {
144  return std::make_shared<int>(static_cast<int>(lua_tointeger(L, n)));
145 }
146 
147 template <>
148 inline void lua_object<int>::from_type(lua_State *L, std::shared_ptr<int> value)
149 {
150  if(value) lua_pushnumber(L, *value);
151  else lua_pushnil(L);
152 }
153 
154 template <>
155 inline std::shared_ptr< std::vector<std::string> > lua_object< std::vector<std::string> >::to_type(lua_State *L, int n)
156 {
157  std::shared_ptr<std::vector<std::string>> v(new std::vector<std::string>());
158  int l = lua_rawlen(L, n);
159  for (int i = 1; i < l + 1; ++i)
160  {
161  lua_pushinteger(L, i);
162  lua_gettable(L, n);
163  std::string s = lua_tostring(L, -1);
164  lua_settop(L, n);
165  v->push_back(s);
166  }
167 
168  return v;
169 }
170 
171 template <>
172 inline void lua_object< std::vector<std::string> >::from_type(lua_State *L, std::shared_ptr< std::vector<std::string> > value)
173 {
174  if(value) {
175  lua_createtable(L, value->size(), 0);
176  for(const std::string& str : *value) {
177  lua_pushlstring(L, str.c_str(), str.size());
178  lua_rawseti(L, -1, lua_rawlen(L, -2) + 1);
179  }
180  } else lua_pushnil(L);
181 }
182 
183 template <>
184 inline std::shared_ptr<config> lua_object<config>::to_type(lua_State *L, int n)
185 {
186  std::shared_ptr<config> cfg(new config());
187  luaW_toconfig(L, n, *cfg);
188  return cfg;
189 }
190 
191 template <>
192 inline void lua_object<config>::from_type(lua_State *L, std::shared_ptr<config> value)
193 {
194  if(value) luaW_pushconfig(L, *value);
195  else lua_pushnil(L);
196 }
197 
198 template <>
199 inline std::shared_ptr<terrain_filter> lua_object<terrain_filter>::to_type(lua_State *L, int n)
200 {
201  std::shared_ptr<config> cfg(new config());
202  std::shared_ptr<vconfig> vcfg(new vconfig(*cfg));
203  if (!luaW_tovconfig(L, n, *vcfg)) {
204  cfg->add_child("not");
205  }
206  vcfg->make_safe();
207  std::shared_ptr<terrain_filter> tf(new terrain_filter(*vcfg, resources::filter_con));
208  return tf;
209 }
210 
211 template <>
212 inline void lua_object<terrain_filter>::from_type(lua_State *L, std::shared_ptr<terrain_filter> value)
213 {
214  if(value) {
215  std::set<map_location> locs;
216  value->get_locations(locs);
217  lua_createtable(L, locs.size(), 0);
218  for(const map_location& loc : locs) {
219  luaW_pushlocation(L, loc);
220  lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
221  }
222  } else lua_pushnil(L);
223 }
224 
225 template <>
226 inline std::shared_ptr<std::vector<target> > lua_object< std::vector<target> >::to_type(lua_State *L, int n)
227 {
228  std::shared_ptr<std::vector<target>> targets(new std::vector<target>());
229  std::back_insert_iterator< std::vector<target> > tg(*targets);
230  int l = lua_rawlen(L, n);
231 
232  for (int i = 1; i <= l; ++i)
233  {
234  lua_rawgeti(L, n, i); // st n + 1 TABLE @ N table @ n + 1
235 
236  lua_pushstring(L, "loc"); // st n + 2
237  lua_rawget(L, -2); // st n + 2
238 
239  lua_pushstring(L, "x"); // st n + 3
240  lua_rawget(L, -2); // st n + 3
241  int x = static_cast<int>(lua_tointeger(L, -1)); // st n + 3
242  lua_pop(L, 1); // st n + 2
243 
244  lua_pushstring(L, "y"); // st n + 3
245  lua_rawget(L, -2); // st n + 3
246  int y = static_cast<int>(lua_tointeger(L, -1)); // st n + 3
247 
248  lua_pop(L, 2); // st n + 1
249 
250  lua_pushstring(L, "type"); // st n + 2
251  lua_rawget(L, -2); // st n + 2
252  target::TYPE type = target::TYPE::EXPLICIT;
253  if(lua_isnumber(L, -1)) {
254  type = target::TYPE::from_int(static_cast<int>(lua_tointeger(L, -1))); // st n + 2
255  } else if(lua_isstring(L, -1)) {
256  type = target::TYPE::string_to_enum(lua_tostring(L, -1)); // st n + 2
257  }
258  lua_pop(L, 1); // st n + 1
259 
260 
261  lua_pushstring(L, "value");
262  lua_rawget(L, -2);
263  int value = static_cast<int>(lua_tointeger(L, -1));
264 
265  map_location ml(x, y, wml_loc());
266 
267  *tg = target(ml, value, type);
268  }
269 
270  lua_settop(L, n);
271  return targets;
272 }
273 
274 template <>
275 inline std::shared_ptr<unit_advancements_aspect> lua_object<unit_advancements_aspect>::to_type(lua_State *L, int n)
276 {
277  return std::make_shared<unit_advancements_aspect>(L, n);
278 }
279 
280 // This one is too complex to define in the header.
282 template <>
283 std::shared_ptr<aspect_attacks_lua_filter> lua_object<aspect_attacks_lua_filter>::to_type(lua_State *L, int n);
284 } // end of namespace ai
285 
286 
287 #endif
TYPE
UNSCALED : image will be drawn "as is" without changing size, even in case of redraw SCALED_TO_ZOOM :...
Definition: picture.hpp:185
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:684
lua_object(const T &init)
Definition: lua_object.hpp:63
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
Gets an optional vconfig from either a table or a userdata.
Definition: lua_common.cpp:836
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:730
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:172
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:557
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:658
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:817
std::shared_ptr< T > value_
Definition: lua_object.hpp:99
LUA_API int lua_gettable(lua_State *L, int idx)
Definition: lapi.cpp:612
#define lua_tointeger(L, i)
Definition: lua.h:342
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:647
STL namespace.
#define lua_tonumber(L, i)
Definition: lua.h:341
Definitions for the interface to Wesnoth Markup Language (WML).
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.cpp:160
virtual ~lua_object_base()
Definition: lua_object.hpp:46
#define lua_pop(L, n)
Definition: lua.h:344
std::shared_ptr< T > to_type(lua_State *, int)
Definition: lua_object.hpp:87
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:58
virtual void store(lua_State *L, int n)=0
struct utils::detail::formula_initer init
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:283
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:890
void store(lua_State *L, int n)
Definition: lua_object.hpp:74
filter_context * filter_con
Definition: resources.cpp:23
void push(lua_State *L)
Definition: lua_object.hpp:79
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.cpp:479
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:450
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
Definition: lapi.cpp:458
#define lua_pushliteral(L, s)
Definition: lua.h:361
Encapsulates the map of the game.
Definition: location.hpp:42
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:742
std::size_t i
Definition: function.cpp:933
static map_location::DIRECTION s
Default AI contexts.
void from_type(lua_State *L, std::shared_ptr< T >)
Definition: lua_object.hpp:93
#define lua_tostring(L, i)
Definition: lua.h:366
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:276
LUA_API size_t lua_rawlen(lua_State *L, int idx)
Definition: lapi.cpp:392
LUA_API int lua_error(lua_State *L)
Definition: lapi.cpp:1114
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:662
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:466
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:491