Otclient  14/8/2020
luavaluecasts.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "luavaluecasts.h"
24 #include "luainterface.h"
26 
27 // bool
28 int push_luavalue(bool b)
29 {
30  g_lua.pushBoolean(b);
31  return 1;
32 }
33 
34 bool luavalue_cast(int index, bool& b)
35 {
36  b = g_lua.toBoolean(index);
37  return true;
38 }
39 
40 // int
41 int push_luavalue(int i)
42 {
43  g_lua.pushInteger(i);
44  return 1;
45 }
46 
47 bool luavalue_cast(int index, int& i)
48 {
49  i = g_lua.toInteger(index);
50  if(i == 0 && !g_lua.isNumber(index) && !g_lua.isNil())
51  return false;
52  return true;
53 }
54 
55 // double
56 int push_luavalue(double d)
57 {
58  g_lua.pushNumber(d);
59  return 1;
60 }
61 
62 bool luavalue_cast(int index, double& d)
63 {
64  d = g_lua.toNumber(index);
65  if(d == 0 && !g_lua.isNumber(index) && !g_lua.isNil())
66  return false;
67  return true;
68 }
69 
70 // string
71 int push_luavalue(const char* cstr)
72 {
73  g_lua.pushCString(cstr);
74  return 1;
75 }
76 
77 int push_luavalue(const std::string& str)
78 {
79  g_lua.pushString(str);
80  return 1;
81 }
82 
83 bool luavalue_cast(int index, std::string& str)
84 {
85  str = g_lua.toString(index);
86  return true;
87 }
88 
89 // lua cpp function
90 int push_luavalue(const LuaCppFunction& func)
91 {
92  g_lua.pushCppFunction(func);
93  return 1;
94 }
95 
96 // color
97 int push_luavalue(const Color& color)
98 {
99  g_lua.createTable(0, 4);
100  g_lua.pushInteger(color.r());
101  g_lua.setField("r");
102  g_lua.pushInteger(color.g());
103  g_lua.setField("g");
104  g_lua.pushInteger(color.b());
105  g_lua.setField("b");
106  g_lua.pushInteger(color.a());
107  g_lua.setField("a");
108  return 1;
109 }
110 
111 bool luavalue_cast(int index, Color& color)
112 {
113  if(g_lua.isTable(index)) {
114  g_lua.getField("r", index);
115  color.setRed((int)g_lua.popInteger());
116  g_lua.getField("g", index);
117  color.setGreen((int)g_lua.popInteger());
118  g_lua.getField("b", index);
119  color.setBlue((int)g_lua.popInteger());
120  g_lua.getField("a", index);
121  color.setAlpha((int)g_lua.popInteger());
122  return true;
123  } else if(g_lua.isString()) {
124  return stdext::cast(g_lua.toString(index), color);
125  } else if(g_lua.isNil()) {
126  color = Color::white;
127  return true;
128  }
129  return false;
130 }
131 
132 // rect
133 int push_luavalue(const Rect& rect)
134 {
135  g_lua.createTable(0, 4);
136  g_lua.pushInteger(rect.x());
137  g_lua.setField("x");
138  g_lua.pushInteger(rect.y());
139  g_lua.setField("y");
140  g_lua.pushInteger(rect.width());
141  g_lua.setField("width");
142  g_lua.pushInteger(rect.height());
143  g_lua.setField("height");
144  return 1;
145 }
146 
147 bool luavalue_cast(int index, Rect& rect)
148 {
149  if(g_lua.isTable(index)) {
150  g_lua.getField("x", index);
151  rect.setX(g_lua.popInteger());
152  g_lua.getField("y", index);
153  rect.setY(g_lua.popInteger());
154  g_lua.getField("width", index);
155  rect.setWidth(g_lua.popInteger());
156  g_lua.getField("height", index);
157  rect.setHeight(g_lua.popInteger());
158  return true;
159  } else if(g_lua.isString()) {
160  return stdext::cast(g_lua.toString(index), rect);
161  } else if(g_lua.isNil()) {
162  rect = Rect();
163  return true;
164  }
165  return false;
166 }
167 
168 // point
169 int push_luavalue(const Point& point)
170 {
171  g_lua.createTable(0, 2);
172  g_lua.pushInteger(point.x);
173  g_lua.setField("x");
174  g_lua.pushInteger(point.y);
175  g_lua.setField("y");
176  return 1;
177 }
178 
179 bool luavalue_cast(int index, Point& point)
180 {
181  if(g_lua.isTable(index)) {
182  g_lua.getField("x", index);
183  point.x = g_lua.popInteger();
184  g_lua.getField("y", index);
185  point.y = g_lua.popInteger();
186  return true;
187  } else if(g_lua.isString()) {
188  return stdext::cast(g_lua.toString(index), point);
189  } else if(g_lua.isNil()) {
190  point = Point();
191  return true;
192  }
193  return false;
194 }
195 
196 // size
197 int push_luavalue(const Size& size)
198 {
199  g_lua.createTable(0, 2);
200  g_lua.pushInteger(size.width());
201  g_lua.setField("width");
202  g_lua.pushInteger(size.height());
203  g_lua.setField("height");
204  return 1;
205 }
206 
207 bool luavalue_cast(int index, Size& size)
208 {
209  if(g_lua.isTable(index)) {
210  g_lua.getField("width", index);
211  size.setWidth(g_lua.popInteger());
212  g_lua.getField("height", index);
213  size.setHeight(g_lua.popInteger());
214  return true;
215  } else if(g_lua.isString()) {
216  return stdext::cast(g_lua.toString(index), size);
217  } else if(g_lua.isNil()) {
218  size = Size();
219  return true;
220  }
221  return false;
222 }
223 
224 // otml nodes
226 {
227  if(node->hasValue()) {
228  union {
229  bool b;
230  double d;
231  long l;
232  };
233  std::string value = node->rawValue();
234  if(stdext::cast(value, b))
235  g_lua.pushBoolean(b);
236  else if(stdext::cast(value, l))
237  g_lua.pushInteger(l);
238  else if(stdext::cast(value, d))
239  g_lua.pushNumber(d);
240  else
241  g_lua.pushString(value);
242  } else if(node->hasChildren()) {
243  g_lua.newTable();
244  bool pushedChild = false;
245  int currentIndex = 1;
246  for(const OTMLNodePtr& cnode : node->children()) {
248  if(!g_lua.isNil()) {
249  if(cnode->isUnique()) {
250  g_lua.pushString(cnode->tag());
251  g_lua.insert(-2);
252  g_lua.rawSet();
253  } else
254  g_lua.rawSeti(currentIndex++);
255  pushedChild = true;
256  } else
257  g_lua.pop();
258  }
259  if(!pushedChild) {
260  g_lua.pop();
261  g_lua.pushNil();
262  }
263  } else
264  g_lua.pushNil();
265 }
266 
267 int push_luavalue(const OTMLNodePtr& node)
268 {
269  if(node) {
270  g_lua.newTable();
271  int currentIndex = 1;
272  for(const OTMLNodePtr& cnode : node->children()) {
274  if(cnode->isUnique() && !cnode->tag().empty()) {
275  g_lua.setField(cnode->tag());
276  } else
277  g_lua.rawSeti(currentIndex++);
278  }
279  } else
280  g_lua.pushNil();
281  return 1;
282 }
283 
284 bool luavalue_cast(int index, OTMLNodePtr& node)
285 {
286  node = OTMLNode::create();
287  node->setUnique(true);
288  if(g_lua.isTable(index)) {
289  g_lua.pushNil();
290  while(g_lua.next(index < 0 ? index-1 : index)) {
291  std::string cnodeName;
292  if(g_lua.isString(-2)) {
293  g_lua.pushValue(-2);
294  cnodeName = g_lua.toString();
295  g_lua.pop();
296  } else
297  assert(g_lua.isNumber());
298  if(g_lua.isTable()) {
299  OTMLNodePtr cnode;
300  if(luavalue_cast(-1, cnode)) {
301  if(cnodeName.empty())
302  cnode->setUnique(false);
303  else
304  cnode->setTag(cnodeName);
305  node->addChild(cnode);
306  }
307  } else {
308  std::string value;
309  if(g_lua.isBoolean())
310  value = stdext::unsafe_cast<std::string>(g_lua.toBoolean());
311  else
312  value = g_lua.toString();
313  if(cnodeName.empty())
314  node->writeIn(value);
315  else
316  node->writeAt(cnodeName, value);
317  }
318  g_lua.pop();
319  }
320  return true;
321  }
322  return false;
323 }
324 
325 // object ptr
326 bool luavalue_cast(int index, LuaObjectPtr& obj) {
327  if(g_lua.isUserdata(index)) {
328  obj = g_lua.toObject(index);
329  return true;
330  } else if(g_lua.isNil(index)) {
331  obj = nullptr;
332  return true;
333  }
334  return false;
335 }
Color::g
uint8 g() const
Definition: color.h:46
push_luavalue
int push_luavalue(const Outfit &outfit)
Definition: luavaluecasts.cpp:26
OTMLNode::writeIn
void writeIn(const T &v)
Definition: otmlnode.h:170
OTMLNode::setTag
void setTag(const std::string &tag)
Definition: otmlnode.h:50
LuaInterface::insert
void insert(int index)
Definition: luainterface.cpp:819
LuaInterface::rawSeti
void rawSeti(int n, int index=-2)
Definition: luainterface.cpp:978
Color::setAlpha
void setAlpha(int a)
Definition: color.h:59
LuaCppFunction
std::function< int(LuaInterface *)> LuaCppFunction
Definition: declarations.h:31
Color
Definition: color.h:32
LuaInterface::isString
bool isString(int index=-1)
Definition: luainterface.cpp:1168
OTMLNode::hasValue
bool hasValue()
Definition: otmlnode.h:45
OTMLNode::writeAt
void writeAt(const std::string &childTag, const T &v)
Definition: otmlnode.h:162
TPoint::y
T y
Definition: point.h:83
LuaInterface::toString
std::string toString(int index=-1)
Definition: luainterface.cpp:1222
TSize::setWidth
void setWidth(T w)
Definition: size.h:47
TRect
Definition: rect.h:37
TRect::x
T x() const
Definition: rect.h:58
LuaInterface::isNumber
bool isNumber(int index=-1)
Definition: luainterface.cpp:1162
OTMLNode::hasChildren
bool hasChildren()
Definition: otmlnode.cpp:44
LuaInterface::toObject
LuaObjectPtr toObject(int index=-1)
Definition: luainterface.cpp:1239
luavaluecasts.h
luavalue_cast
bool luavalue_cast(int index, Outfit &outfit)
Definition: luavaluecasts.cpp:52
push_otml_subnode_luavalue
void push_otml_subnode_luavalue(const OTMLNodePtr &node)
Definition: luavaluecasts.cpp:225
luainterface.h
stdext::cast
bool cast(const T &in, R &out)
Definition: cast.h:37
OTMLNode::children
OTMLNodeList children()
Definition: otmlnode.cpp:170
TRect::setY
void setY(T y)
Definition: rect.h:80
Color::setRed
void setRed(int r)
Definition: color.h:56
Point
TPoint< int > Point
Definition: point.h:86
Color::setBlue
void setBlue(int b)
Definition: color.h:58
TSize::width
int width() const
Definition: size.h:43
Color::a
uint8 a() const
Definition: color.h:44
OTMLNode::addChild
void addChild(const OTMLNodePtr &newChild)
Definition: otmlnode.cpp:91
LuaInterface::getField
void getField(const char *key, int index=-1)
Definition: luainterface.cpp:880
LuaInterface::pushNumber
void pushNumber(double v)
Definition: luainterface.cpp:1072
Color::setGreen
void setGreen(int g)
Definition: color.h:57
LuaInterface::createTable
void createTable(int narr, int nrec)
Definition: luainterface.cpp:989
TRect::setX
void setX(T x)
Definition: rect.h:79
TSize::setHeight
void setHeight(T h)
Definition: size.h:48
LuaInterface::isNil
bool isNil(int index=-1)
Definition: luainterface.cpp:1150
LuaInterface::popInteger
long popInteger()
Definition: luainterface.cpp:1007
OTMLNode::setUnique
void setUnique(bool unique)
Definition: otmlnode.h:53
g_lua
LuaInterface g_lua
Definition: luainterface.cpp:31
Color::white
static const Color white
Definition: color.h:101
TRect::y
T y() const
Definition: rect.h:59
LuaInterface::pushCString
void pushCString(const char *v)
Definition: luainterface.cpp:1084
OTMLNode::rawValue
std::string rawValue()
Definition: otmlnode.h:39
Size
TSize< int > Size
Definition: size.h:107
TPoint::x
T x
Definition: point.h:83
LuaInterface::pushString
void pushString(const std::string &v)
Definition: luainterface.cpp:1091
LuaInterface::pushValue
void pushValue(int index=-1)
Definition: luainterface.cpp:1143
Rect
TRect< int > Rect
Definition: rect.h:319
LuaInterface::pushCppFunction
void pushCppFunction(const LuaCppFunction &func)
Definition: luainterface.cpp:1127
LuaInterface::isTable
bool isTable(int index=-1)
Definition: luainterface.cpp:1174
TSize::height
int height() const
Definition: size.h:44
TRect::setHeight
void setHeight(T height)
Definition: rect.h:86
otmlnode.h
LuaInterface::pop
void pop(int n=1)
Definition: luainterface.cpp:999
stdext::shared_object_ptr< OTMLNode >
LuaInterface::setField
void setField(const char *key, int index=-2)
Definition: luainterface.cpp:887
LuaInterface::isUserdata
bool isUserdata(int index=-1)
Definition: luainterface.cpp:1192
Color::r
uint8 r() const
Definition: color.h:47
TRect::height
T height() const
Definition: rect.h:70
TPoint< int >
LuaInterface::pushInteger
void pushInteger(long v)
Definition: luainterface.cpp:1066
TRect::setWidth
void setWidth(T width)
Definition: rect.h:85
LuaInterface::toBoolean
bool toBoolean(int index=-1)
Definition: luainterface.cpp:1198
LuaInterface::pushNil
void pushNil()
Definition: luainterface.cpp:1060
TRect::width
T width() const
Definition: rect.h:69
TSize
Definition: point.h:31
Color::b
uint8 b() const
Definition: color.h:45
LuaInterface::isBoolean
bool isBoolean(int index=-1)
Definition: luainterface.cpp:1156
LuaInterface::rawSet
void rawSet(int index=-3)
Definition: luainterface.cpp:972
LuaInterface::toInteger
int toInteger(int index=-1)
Definition: luainterface.cpp:1204
LuaInterface::next
bool next(int index=-2)
Definition: luainterface.cpp:831
LuaInterface::pushBoolean
void pushBoolean(bool v)
Definition: luainterface.cpp:1078
LuaInterface::toNumber
double toNumber(int index=-1)
Definition: luainterface.cpp:1210
LuaInterface::newTable
void newTable()
Definition: luainterface.cpp:984
OTMLNode::create
static OTMLNodePtr create(std::string tag="", bool unique=false)
Definition: otmlnode.cpp:27