comparison C++/Luae.cpp @ 182:15b264d9e833

Add Luae class
author David Demelier <markand@malikania.fr>
date Tue, 29 Oct 2013 21:32:20 +0100
parents
children 258087829c66
comparison
equal deleted inserted replaced
181:08af4f99c104 182:15b264d9e833
1 /*
2 * Luae.cpp -- Lua helpers and such
3 *
4 * Copyright (c) 2011, 2012, 2013 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include "Luae.h"
20
21 void LuaeClass::createClass(lua_State *L, const LuaObject &cls)
22 {
23 LUA_STACK_CHECKBEGIN(L);
24
25 // Already registered?
26 if (luaL_newmetatable(L, cls.name) == 0)
27 return;
28
29 // Add it's "name" field
30 lua_pushstring(L, cls.name);
31 lua_setfield(L, -2, LUAE_CLASS_FIELDNAME);
32
33 // Create a list of parent for a faster cast
34 lua_createtable(L, 0, 0);
35
36 int i = 0;
37 for (auto p = cls.parent; p != nullptr; p = p->parent) {
38 lua_pushstring(L, p->name);
39 lua_rawseti(L, -2, ++i);
40 }
41 lua_setfield(L, -2, LUAE_CLASS_FIELDPARENTS);
42
43 // Metamethods
44 if (cls.metamethods.size() > 0)
45 luaL_setfuncs(L, cls.metamethods.data(), 0);
46
47 // Methods
48 lua_createtable(L, 0, 0);
49
50 if (cls.methods.size() > 0) {
51 luaL_setfuncs(L, cls.methods.data(), 0);
52 }
53
54 /*
55 * Add a metatable to this __index table so that if
56 * a method is not found it use the parent table recursively
57 */
58 if (cls.parent) {
59 // 1. Get the parent
60 luaL_getmetatable(L, cls.parent->name);
61 assert(lua_type(L, -1) != LUA_TNIL);
62
63 // 2. Create an anonymous metatable
64 lua_createtable(L, 1, 1);
65
66 // 3. Get the __index field from this metatable
67 lua_getfield(L, -2, "__index");
68 assert(lua_type(L, -1) != LUA_TNIL);
69 lua_setfield(L, -2, "__index");
70 lua_setmetatable(L, -3);
71 lua_pop(L, 1);
72 }
73
74 lua_setfield(L, -2, "__index");
75
76 // Pop that metatable
77 lua_pop(L, 1);
78
79 LUA_STACK_CHECKEQUALS(L);
80 }
81
82 /* --------------------------------------------------------
83 * Luae public methods
84 * -------------------------------------------------------- */
85
86 void Luae::createEnum(lua_State *L, const LuaEnum *enumeration)
87 {
88 lua_createtable(L, 0, 0);
89
90 for (int i = 0; enumeration[i].name != nullptr; ++i) {
91 lua_pushinteger(L, enumeration[i].value);
92 lua_setfield(L, -2, enumeration[i].name);
93 }
94 }
95
96 void Luae::createLibrary(lua_State *L, const luaL_Reg *functions)
97 {
98 LUA_STACK_CHECKBEGIN(L);
99
100 lua_createtable(L, 0, 0);
101 luaL_setfuncs(L, functions, 0);
102
103 LUA_STACK_CHECKEND(L, - 1);
104 }
105
106 template <>
107 bool Luae::getField(lua_State *L, int idx, const std::string & name)
108 {
109 bool value = false;
110
111 lua_getfield(L, idx, name.c_str());
112 if (lua_type(L, idx) == LUA_TBOOLEAN)
113 value = lua_toboolean(L, -1) == 1;
114 lua_pop(L, 1);
115
116 return value;
117 }
118
119 template <>
120 double Luae::getField(lua_State *L, int idx, const std::string & name)
121 {
122 double value = 0;
123
124 lua_getfield(L, idx, name.c_str());
125 if (lua_type(L, idx) == LUA_TNUMBER)
126 value = lua_tonumber(L, -1);
127 lua_pop(L, 1);
128
129 return value;
130 }
131
132 template <>
133 int Luae::getField(lua_State *L, int idx, const std::string & name)
134 {
135 int value = 0;
136
137 lua_getfield(L, idx, name.c_str());
138 if (lua_type(L, idx) == LUA_TNUMBER)
139 value = lua_tointeger(L, -1);
140 lua_pop(L, 1);
141
142 return value;
143 }
144
145 template <>
146 std::string Luae::getField(lua_State *L, int idx, const std::string & name)
147 {
148 std::string value;
149
150 lua_getfield(L, idx, name.c_str());
151 if (lua_type(L, idx) == LUA_TSTRING)
152 value = lua_tostring(L, -1);
153 lua_pop(L, 1);
154
155 return value;
156 }
157
158 void Luae::preload(lua_State *L, const std::string & name, lua_CFunction func)
159 {
160 LUA_STACK_CHECKBEGIN(L);
161
162 lua_getglobal(L, "package");
163 lua_getfield(L, -1, "preload");
164 lua_pushcfunction(L, func);
165 lua_setfield(L, -2, name.c_str());
166 lua_pop(L, 2);
167
168 LUA_STACK_CHECKEQUALS(L);
169 }
170
171 void Luae::readTable(lua_State *L, int idx, ReadFunction func)
172 {
173 lua_pushnil(L);
174
175 if (idx < 0)
176 --idx;
177
178 while (lua_next(L, idx)) {
179 func(L, lua_type(L, -2), lua_type(L, -1));
180 lua_pop(L, 1);
181 }
182
183 lua_pop(L, 1);
184 }
185
186 int Luae::referenceField(lua_State *L, int idx, int type, const std::string & name)
187 {
188 int ref = LUA_REFNIL;
189
190 lua_getfield(L, idx, name.c_str());
191
192 if (lua_type(L, -1) == type) {
193 lua_pushvalue(L, -1);
194 ref = luaL_ref(L, LUA_REGISTRYINDEX);
195 }
196
197 lua_pop(L, 1);
198
199 return ref;
200 }
201
202 void Luae::require(lua_State *L, const std::string & name, lua_CFunction func, bool global)
203 {
204 LUA_STACK_CHECKBEGIN(L);
205
206 luaL_requiref(L, name.c_str(), func, global);
207 lua_pop(L, 1);
208
209 LUA_STACK_CHECKEQUALS(L);
210 }
211
212 void * operator new(size_t size, lua_State *L)
213 {
214 return lua_newuserdata(L, size);
215 }
216
217 void * operator new(size_t size, lua_State *L, const char *metaname)
218 {
219 void *object;
220
221 object = lua_newuserdata(L, size);
222 luaL_setmetatable(L, metaname);
223
224 return object;
225 }
226
227 void operator delete(void *, lua_State *)
228 {
229 }
230
231 void operator delete(void *, lua_State *L, const char *)
232 {
233 lua_pushnil(L);
234 lua_setmetatable(L, -2);
235 }