2 * Copyright (c) 2007-2008 Mauro Iazzi
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
27 #include "lqt_common.hpp"
32 static void lqtL_getenumtable (lua_State
*L
) {
33 lua_getfield(L
, LUA_REGISTRYINDEX
, LQT_ENUMS
);
34 if (lua_isnil(L
, -1)) {
38 lua_setfield(L
, LUA_REGISTRYINDEX
, LQT_ENUMS
);
42 static void lqtL_getpointertable (lua_State
*L
) {
43 lua_getfield(L
, LUA_REGISTRYINDEX
, LQT_POINTERS
); // (1) get storage for pointers
44 if (lua_isnil(L
, -1)) { // (1) if there is not
45 lua_pop(L
, 1); // (0) pop the nil value
46 lua_newtable(L
); // (1) create a new one
47 lua_pushvalue(L
, -1); // (2) duplicate it
48 lua_setfield(L
, LUA_REGISTRYINDEX
, LQT_POINTERS
); // (1) put one copy as storage
52 static int lqtL_createenum (lua_State
*L
, lqt_Enum e
[], const char *n
) {
53 lqtL_getenumtable(L
); // (1)
54 lua_newtable(L
); // (2)
55 lua_pushvalue(L
, -1); // (3)
56 lua_setfield(L
, -3, n
); // (2)
57 while ( (e
->name
!=0) ) { // (2)
58 lua_pushstring(L
, e
->name
); // (3)
59 lua_pushinteger(L
, e
->value
); // (4)
60 lua_settable(L
, -3); // (2)
61 lua_pushinteger(L
, e
->value
); // (3)
62 lua_pushstring(L
, e
->name
); // (4)
63 lua_settable(L
, -3); // (2)
70 int lqtL_createenumlist (lua_State
*L
, lqt_Enumlist list
[]) {
71 while (list
->enums
!=0 && list
->name
!=0) {
72 lqtL_createenum(L
, list
->enums
, list
->name
); // (0)
78 static int lqtL_indexfunc (lua_State
*L
) {
80 lua_pushnil(L
); // (+1)
81 while (!lua_isnone(L
, lua_upvalueindex(i
))) { // (+1)
82 lua_pop(L
, 1); // (+0)
83 lua_pushvalue(L
, 2); // (+1)
85 lua_rawget(L
, lua_upvalueindex(i
)); // (+1)
87 lua_gettable(L
, lua_upvalueindex(i
)); // (+1)
89 if (!lua_isnil(L
, -1)) break;
95 static int lqtL_pushindexfunc (lua_State
*L
, const char *name
, lqt_Base
*bases
) {
97 luaL_newmetatable(L
, name
); // (1)
98 while (bases
->basename
!=NULL
) {
99 luaL_newmetatable(L
, bases
->basename
); // (upnum)
103 lua_pushcclosure(L
, lqtL_indexfunc
, upnum
); // (1)
107 int lqtL_createclasses (lua_State
*L
, lqt_Class
*list
) {
108 while (list
->name
!=0) { // (0)
109 luaL_newmetatable(L
, list
->name
); // (1)
110 luaL_register(L
, NULL
, list
->mt
); // (1)
111 lua_pushstring(L
, list
->name
); // (2)
112 lua_pushboolean(L
, 1); // (3)
113 lua_settable(L
, -3); // (1)
114 lqtL_pushindexfunc(L
, list
->name
, list
->bases
); // (2)
115 lua_setfield(L
, -2, "__index"); // (1)
116 lua_pushvalue(L
, -1); // (2)
117 lua_setmetatable(L
, -2); // (1)
118 lua_pop(L
, 1); // (0)
119 lua_pushlstring(L
, list
->name
, strlen(list
->name
)-1); // (1)
120 lua_newtable(L
); // (2)
121 luaL_register(L
, NULL
, list
->mt
); // (2)
122 lua_settable(L
, LUA_GLOBALSINDEX
); // (0)
128 bool lqtL_isinteger (lua_State
*L
, int i
) {
129 if (lua_type(L
, i
)==LUA_TNUMBER
)
130 return lua_tointeger(L
, i
)==lua_tonumber(L
, i
);
134 bool lqtL_isnumber (lua_State
*L
, int i
) {
135 return lua_type(L
, i
)==LUA_TNUMBER
;
137 bool lqtL_isstring (lua_State
*L
, int i
) {
138 return lua_type(L
, i
)==LUA_TSTRING
;
140 bool lqtL_isboolean (lua_State
*L
, int i
) {
141 return lua_type(L
, i
)==LUA_TBOOLEAN
;
143 bool lqtL_missarg (lua_State
*L
, int index
, int n
) {
146 for (i
=index
;i
<index
+n
;i
++) {
147 if (!lua_isnoneornil(L
, i
)) {
155 static void lqtL_ensurepointer (lua_State
*L
, const void *p
) { // (+1)
156 lqtL_getpointertable(L
); // (1)
157 lua_pushlightuserdata(L
, const_cast<void*>(p
)); // (2)
158 lua_gettable(L
, -2); // (2)
159 if (lua_isnil(L
, -1)) { // (2)
160 lua_pop(L
, 1); // (1)
161 const void **pp
= static_cast<const void**>(lua_newuserdata(L
, sizeof(void*))); // (2)
163 lua_pushlightuserdata(L
, const_cast<void*>(p
)); // (3)
164 lua_pushvalue(L
, -2); // (4)
165 lua_settable(L
, -4); // (2)
168 lua_remove(L
, -2); // (1)
171 void lqtL_register (lua_State
*L
, const void *p
) { // (+0)
172 lqtL_ensurepointer(L
, p
);
176 void lqtL_unregister (lua_State
*L
, const void *p
) {
177 lqtL_getpointertable(L
); // (1)
178 lua_pushlightuserdata(L
, const_cast<void*>(p
)); // (2)
179 lua_gettable(L
, -2); // (2)
180 if (lua_isuserdata(L
, -1)) {
181 const void **pp
= static_cast<const void**>(lua_touserdata(L
, -1)); // (2)
184 lua_pop(L
, 1); // (1)
185 lua_pushlightuserdata(L
, const_cast<void*>(p
)); // (2)
186 lua_pushnil(L
); // (3)
187 lua_settable(L
, -3); // (1)
188 lua_pop(L
, 1); // (0)
191 void lqtL_passudata (lua_State
*L
, const void *p
, const char *name
) {
192 lqtL_ensurepointer(L
, p
); // (1)
193 luaL_newmetatable(L
, name
); // (2)
194 lua_setmetatable(L
, -2); // (1)
198 void lqtL_pushudata (lua_State
*L
, const void *p
, const char *name
) {
199 lqtL_ensurepointer(L
, p
); // (1)
200 luaL_newmetatable(L
, name
); // (2)
201 lua_setmetatable(L
, -2); // (1)
205 void *lqtL_toudata (lua_State
*L
, int index
, const char *name
) {
207 if (!lqtL_testudata(L
, index
, name
)) return 0;
208 void **pp
= static_cast<void**>(lua_touserdata(L
, index
));
213 bool lqtL_testudata (lua_State
*L
, int index
, const char *name
) {
214 if (!lua_isuserdata(L
, index
) || lua_islightuserdata(L
, index
)) return false;
215 lua_getfield(L
, index
, name
);
216 if (!lua_isboolean(L
, -1) || !lua_toboolean(L
, -1)) {
224 void lqtL_pushenum (lua_State
*L
, int value
, const char *name
) {
225 lqtL_getenumtable(L
);
226 lua_getfield(L
, -1, name
);
228 if (!lua_istable(L
, -1)) {
233 lua_pushnumber(L
, value
);
237 bool lqtL_isenum (lua_State
*L
, int index
, const char *name
) {
239 if (!lua_isstring(L
, index
)) return false;
240 lqtL_getenumtable(L
);
241 lua_getfield(L
, -1, name
);
242 if (!lua_istable(L
, -1)) {
247 lua_pushvalue(L
, index
);
249 ret
= lua_isnumber(L
, -1);
253 int lqtL_toenum (lua_State
*L
, int index
, const char *name
) {
255 lqtL_getenumtable(L
);
256 lua_pushvalue(L
, index
);
258 ret
= lua_tointeger(L
, -1);