Mercurial > love-experiments
annotate src/common/runtime.cpp @ 1333:730ed5f01ab0 minor
Merge in default, update changelog
| author | Bart van Strien <bart.bes+projects@gmail.com> |
|---|---|
| date | Sun, 03 Mar 2013 19:51:04 +0100 |
| parents | c5286ec34327 b7f097053d74 |
| children | 2a5ef265e040 |
| rev | line source |
|---|---|
| 1096 | 1 /** |
|
1282
b7f097053d74
Updated copyright text for the new year
Alex Szpakowski <slime73@gmail.com>
parents:
1168
diff
changeset
|
2 * Copyright (c) 2006-2013 LOVE Development Team |
| 1096 | 3 * |
| 4 * This software is provided 'as-is', without any express or implied | |
| 5 * warranty. In no event will the authors be held liable for any damages | |
| 6 * arising from the use of this software. | |
| 7 * | |
| 8 * Permission is granted to anyone to use this software for any purpose, | |
| 9 * including commercial applications, and to alter it and redistribute it | |
| 10 * freely, subject to the following restrictions: | |
| 11 * | |
| 12 * 1. The origin of this software must not be misrepresented; you must not | |
| 13 * claim that you wrote the original software. If you use this software | |
| 14 * in a product, an acknowledgment in the product documentation would be | |
| 15 * appreciated but is not required. | |
| 16 * 2. Altered source versions must be plainly marked as such, and must not be | |
| 17 * misrepresented as being the original software. | |
| 18 * 3. This notice may not be removed or altered from any source distribution. | |
| 19 **/ | |
| 20 | |
| 21 #include "runtime.h" | |
| 22 | |
| 23 // LOVE | |
| 24 #include "Module.h" | |
| 25 #include "Object.h" | |
| 26 #include "Reference.h" | |
| 27 #include "StringMap.h" | |
|
1098
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
28 #include <thread/threads.h> |
| 1096 | 29 |
| 30 // STD | |
| 31 #include <iostream> | |
| 32 | |
| 33 namespace love | |
| 34 { | |
| 35 | |
| 36 static thread::Mutex *gcmutex = 0; | |
| 37 void *_gcmutex = 0; | |
| 38 /** | |
| 39 * Called when an object is collected. The object is released | |
| 40 * once in this function, possibly deleting it. | |
| 41 **/ | |
| 42 static int w__gc(lua_State *L) | |
| 43 { | |
| 44 if (!gcmutex) | |
| 45 { | |
|
1098
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
46 gcmutex = thread::newMutex(); |
| 1096 | 47 _gcmutex = (void *) gcmutex; |
| 48 } | |
| 49 Proxy *p = (Proxy *)lua_touserdata(L, 1); | |
| 50 Object *t = (Object *)p->data; | |
| 51 if (p->own) | |
| 52 { | |
| 53 thread::Lock lock(gcmutex); | |
| 54 t->release(); | |
| 55 } | |
| 56 return 0; | |
| 57 } | |
| 58 | |
| 59 static int w__tostring(lua_State *L) | |
| 60 { | |
| 61 lua_pushvalue(L, lua_upvalueindex(1)); | |
| 62 return 1; | |
| 63 } | |
| 64 | |
| 65 static int w__typeOf(lua_State *L) | |
| 66 { | |
| 67 Proxy *p = (Proxy *)lua_touserdata(L, 1); | |
| 68 Type t = luax_type(L, 2); | |
| 69 luax_pushboolean(L, p->flags[t]); | |
| 70 return 1; | |
| 71 } | |
| 72 | |
| 73 static int w__eq(lua_State *L) | |
| 74 { | |
| 75 Proxy *p1 = (Proxy *)lua_touserdata(L, 1); | |
| 76 Proxy *p2 = (Proxy *)lua_touserdata(L, 2); | |
| 77 luax_pushboolean(L, p1->data == p2->data); | |
| 78 return 1; | |
| 79 } | |
| 80 | |
| 81 Reference *luax_refif (lua_State *L, int type) | |
| 82 { | |
| 83 Reference *r = 0; | |
| 84 | |
| 85 // Create a reference only if the test succeeds. | |
| 86 if (lua_type(L, -1) == type) | |
| 87 r = new Reference(L); | |
| 88 else // Pop the value even if it fails (but also if it succeeds). | |
| 89 lua_pop(L, 1); | |
| 90 | |
| 91 return r; | |
| 92 } | |
| 93 | |
| 94 void luax_printstack(lua_State *L) | |
| 95 { | |
| 96 for (int i = 1; i<=lua_gettop(L); i++) | |
| 97 { | |
| 98 std::cout << i << " - " << luaL_typename(L, i) << std::endl; | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 bool luax_toboolean(lua_State *L, int idx) | |
| 103 { | |
| 104 return (lua_toboolean(L, idx) != 0); | |
| 105 } | |
| 106 | |
| 107 void luax_pushboolean(lua_State *L, bool b) | |
| 108 { | |
| 109 lua_pushboolean(L, b ? 1 : 0); | |
| 110 } | |
| 111 | |
| 112 bool luax_optboolean(lua_State *L, int idx, bool b) | |
| 113 { | |
| 114 if (lua_isboolean(L, idx) == 1) | |
| 115 return (lua_toboolean(L, idx) == 1 ? true : false); | |
| 116 return b; | |
| 117 } | |
| 118 | |
|
1098
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
119 std::string luax_tostring(lua_State *L, int idx) |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
120 { |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
121 size_t len; |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
122 const char *str = lua_tolstring(L, idx, &len); |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
123 return std::string(str, len); |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
124 } |
|
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
125 |
| 1096 | 126 std::string luax_checkstring(lua_State *L, int idx) |
| 127 { | |
| 128 size_t len; | |
| 129 const char *str = luaL_checklstring(L, idx, &len); | |
| 130 return std::string(str, len); | |
| 131 } | |
| 132 | |
| 133 void luax_pushstring(lua_State *L, std::string str) | |
| 134 { | |
| 135 lua_pushlstring(L, str.data(), str.size()); | |
| 136 } | |
| 137 | |
| 138 int luax_assert_argc(lua_State *L, int min) | |
| 139 { | |
| 140 int argc = lua_gettop(L); | |
| 141 if (argc < min) | |
| 142 return luaL_error(L, "Incorrect number of arguments. Got [%d], expected at least [%d]", argc, min); | |
| 143 return 0; | |
| 144 } | |
| 145 | |
| 146 int luax_assert_argc(lua_State *L, int min, int max) | |
| 147 { | |
| 148 int argc = lua_gettop(L); | |
| 149 if (argc < min || argc > max) | |
| 150 return luaL_error(L, "Incorrect number of arguments. Got [%d], expected [%d-%d]", argc, min, max); | |
| 151 return 0; | |
| 152 } | |
| 153 | |
| 154 int luax_assert_function(lua_State *L, int n) | |
| 155 { | |
| 156 if (!lua_isfunction(L, n)) | |
| 157 return luaL_error(L, "Argument must be of type \"function\"."); | |
| 158 return 0; | |
| 159 } | |
| 160 | |
| 161 int luax_register_module(lua_State *L, const WrappedModule &m) | |
| 162 { | |
| 163 // Put a reference to the C++ module in Lua. | |
| 164 luax_getregistry(L, REGISTRY_MODULES); | |
| 165 | |
| 166 Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); | |
| 167 p->own = true; | |
| 168 p->data = m.module; | |
| 169 p->flags = m.flags; | |
| 170 | |
| 171 luaL_newmetatable(L, m.module->getName()); | |
| 172 lua_pushvalue(L, -1); | |
| 173 lua_setfield(L, -2, "__index"); | |
| 174 lua_pushcfunction(L, w__gc); | |
| 175 lua_setfield(L, -2, "__gc"); | |
| 176 | |
| 177 lua_setmetatable(L, -2); | |
| 178 lua_setfield(L, -2, m.name); // _modules[name] = proxy | |
| 179 lua_pop(L, 1); | |
| 180 | |
| 181 // Gets the love table. | |
| 182 luax_insistglobal(L, "love"); | |
| 183 | |
| 184 // Create new table for module. | |
| 185 lua_newtable(L); | |
| 186 | |
| 187 // Register all the functions. | |
| 188 luaL_register(L, 0, m.functions); | |
| 189 | |
| 190 // Register types. | |
| 191 if (m.types != 0) | |
| 192 for (const lua_CFunction *t = m.types; *t != 0; t++) | |
| 193 (*t)(L); | |
| 194 | |
| 195 lua_pushvalue(L, -1); | |
| 196 lua_setfield(L, -3, m.name); // love.graphics = table | |
| 197 lua_remove(L, -2); // love | |
| 198 | |
|
1117
3c6206da8bcf
Add Module::registerInstance() and Module::getInstance().
vrld <vrld@vrld.org>
parents:
1096
diff
changeset
|
199 // Register module instance |
|
3c6206da8bcf
Add Module::registerInstance() and Module::getInstance().
vrld <vrld@vrld.org>
parents:
1096
diff
changeset
|
200 Module::registerInstance(m.module); |
|
3c6206da8bcf
Add Module::registerInstance() and Module::getInstance().
vrld <vrld@vrld.org>
parents:
1096
diff
changeset
|
201 |
| 1096 | 202 return 1; |
| 203 } | |
| 204 | |
| 205 int luax_preload(lua_State *L, lua_CFunction f, const char *name) | |
| 206 { | |
| 207 lua_getglobal(L, "package"); | |
| 208 lua_getfield(L, -1, "preload"); | |
| 209 lua_pushcfunction(L, f); | |
| 210 lua_setfield(L, -2, name); | |
| 211 lua_pop(L, 2); | |
| 212 return 0; | |
| 213 } | |
| 214 | |
| 215 int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f) | |
| 216 { | |
| 217 luaL_newmetatable(L, tname); | |
| 218 | |
| 219 // m.__index = m | |
| 220 lua_pushvalue(L, -1); | |
| 221 lua_setfield(L, -2, "__index"); | |
| 222 | |
| 223 // setup gc | |
| 224 lua_pushcfunction(L, w__gc); | |
| 225 lua_setfield(L, -2, "__gc"); | |
| 226 | |
| 227 // Add equality | |
| 228 lua_pushcfunction(L, w__eq); | |
| 229 lua_setfield(L, -2, "__eq"); | |
| 230 | |
| 231 // Add tostring function. | |
| 232 lua_pushstring(L, tname); | |
| 233 lua_pushcclosure(L, w__tostring, 1); | |
| 234 lua_setfield(L, -2, "__tostring"); | |
| 235 | |
| 236 // Add tostring to as type() as well. | |
| 237 lua_pushstring(L, tname); | |
| 238 lua_pushcclosure(L, w__tostring, 1); | |
| 239 lua_setfield(L, -2, "type"); | |
| 240 | |
| 241 // Add typeOf | |
| 242 lua_pushcfunction(L, w__typeOf); | |
| 243 lua_setfield(L, -2, "typeOf"); | |
| 244 | |
| 245 if (f != 0) | |
| 246 luaL_register(L, 0, f); | |
| 247 | |
| 248 lua_pop(L, 1); // Pops metatable. | |
| 249 return 0; | |
| 250 } | |
| 251 | |
| 252 int luax_table_insert(lua_State *L, int tindex, int vindex, int pos) | |
| 253 { | |
| 254 if (tindex < 0) | |
| 255 tindex = lua_gettop(L)+1+tindex; | |
| 256 if (vindex < 0) | |
| 257 vindex = lua_gettop(L)+1+vindex; | |
| 258 if (pos == -1) | |
| 259 { | |
| 260 lua_pushvalue(L, vindex); | |
| 261 lua_rawseti(L, tindex, lua_objlen(L, tindex)+1); | |
| 262 return 0; | |
| 263 } | |
| 264 else if (pos < 0) | |
| 265 pos = lua_objlen(L, tindex)+1+pos; | |
| 266 for (int i = lua_objlen(L, tindex)+1; i > pos; i--) | |
| 267 { | |
| 268 lua_rawgeti(L, tindex, i-1); | |
| 269 lua_rawseti(L, tindex, i); | |
| 270 } | |
| 271 lua_pushvalue(L, vindex); | |
| 272 lua_rawseti(L, tindex, pos); | |
| 273 return 0; | |
| 274 } | |
| 275 | |
| 276 int luax_register_searcher(lua_State *L, lua_CFunction f, int pos) | |
| 277 { | |
| 278 // Add the package loader to the package.loaders table. | |
| 279 lua_getglobal(L, "package"); | |
| 280 | |
| 281 if (lua_isnil(L, -1)) | |
| 282 return luaL_error(L, "Can't register searcher: package table does not exist."); | |
| 283 | |
| 284 lua_getfield(L, -1, "loaders"); | |
| 285 | |
| 286 if (lua_isnil(L, -1)) | |
| 287 return luaL_error(L, "Can't register searcher: package.loaders table does not exist."); | |
| 288 | |
| 289 lua_pushcfunction(L, f); | |
| 290 luax_table_insert(L, -2, -1, pos); | |
| 291 lua_pop(L, 3); | |
| 292 return 0; | |
| 293 } | |
| 294 | |
| 295 void luax_newtype(lua_State *L, const char *name, bits flags, void *data, bool own) | |
| 296 { | |
| 297 Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); | |
| 298 | |
| 299 u->data = data; | |
| 300 u->flags = flags; | |
| 301 u->own = own; | |
| 302 | |
| 303 luaL_newmetatable(L, name); | |
| 304 lua_setmetatable(L, -2); | |
| 305 } | |
| 306 | |
| 307 bool luax_istype(lua_State *L, int idx, love::bits type) | |
| 308 { | |
| 309 if (lua_isuserdata(L, idx) == 0) | |
| 310 return false; | |
| 311 | |
| 312 return ((((Proxy *)lua_touserdata(L, idx))->flags & type) == type); | |
| 313 } | |
| 314 | |
| 315 int luax_getfunction(lua_State *L, const char *mod, const char *fn) | |
| 316 { | |
| 317 lua_getglobal(L, "love"); | |
| 318 if (lua_isnil(L, -1)) return luaL_error(L, "Could not find global love!"); | |
| 319 lua_getfield(L, -1, mod); | |
| 320 if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s!", mod); | |
| 321 lua_getfield(L, -1, fn); | |
| 322 if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s.%s!", mod, fn); | |
| 323 | |
| 324 lua_remove(L, -2); // remove mod | |
| 325 lua_remove(L, -2); // remove fn | |
| 326 return 0; | |
| 327 } | |
| 328 | |
| 329 int luax_convobj(lua_State *L, int idx, const char *mod, const char *fn) | |
| 330 { | |
| 331 // Convert string to a file. | |
| 332 luax_getfunction(L, mod, fn); | |
| 333 lua_pushvalue(L, idx); // The initial argument. | |
| 334 lua_call(L, 1, 1); // Call the function, one arg, one return value. | |
| 335 lua_replace(L, idx); // Replace the initial argument with the new object. | |
| 336 return 0; | |
| 337 } | |
| 338 | |
| 339 int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn) | |
| 340 { | |
| 341 luax_getfunction(L, mod, fn); | |
| 342 for (int i = 0; i < n; i++) | |
| 343 { | |
| 344 lua_pushvalue(L, idxs[i]); // The arguments. | |
| 345 } | |
| 346 lua_call(L, n, 1); // Call the function, n args, one return value. | |
| 347 lua_replace(L, idxs[0]); // Replace the initial argument with the new object. | |
| 348 return 0; | |
| 349 } | |
| 350 | |
|
1168
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
351 int luax_pconvobj(lua_State *L, int idx, const char *mod, const char *fn) |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
352 { |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
353 // Convert string to a file. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
354 luax_getfunction(L, mod, fn); |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
355 lua_pushvalue(L, idx); // The initial argument. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
356 int ret = lua_pcall(L, 1, 1, 0); // Call the function, one arg, one return value. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
357 if (ret == 0) |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
358 lua_replace(L, idx); // Replace the initial argument with the new object. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
359 return ret; |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
360 } |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
361 |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
362 int luax_pconvobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn) |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
363 { |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
364 luax_getfunction(L, mod, fn); |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
365 for (int i = 0; i < n; i++) |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
366 { |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
367 lua_pushvalue(L, idxs[i]); // The arguments. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
368 } |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
369 int ret = lua_pcall(L, n, 1, 0); // Call the function, n args, one return value. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
370 if (ret == 0) |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
371 lua_replace(L, idxs[0]); // Replace the initial argument with the new object. |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
372 return ret; |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
373 } |
|
fb1bf6a0dede
Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1117
diff
changeset
|
374 |
| 1096 | 375 int luax_strtofile(lua_State *L, int idx) |
| 376 { | |
| 377 return luax_convobj(L, idx, "filesystem", "newFile"); | |
| 378 } | |
| 379 | |
| 380 int luax_filetodata(lua_State *L, int idx) | |
| 381 { | |
| 382 return luax_convobj(L, idx, "filesystem", "read"); | |
| 383 } | |
| 384 | |
| 385 int luax_insist(lua_State *L, int idx, const char *k) | |
| 386 { | |
| 387 // Convert to absolute index if necessary. | |
| 388 if (idx < 0 && idx > LUA_REGISTRYINDEX) | |
| 389 idx = lua_gettop(L) + ++idx; | |
| 390 | |
| 391 lua_getfield(L, idx, k); | |
| 392 | |
| 393 // Create if necessary. | |
| 394 if (!lua_istable(L, -1)) | |
| 395 { | |
| 396 lua_pop(L, 1); // Pop the non-table. | |
| 397 lua_newtable(L); | |
| 398 lua_pushvalue(L, -1); // Duplicate the table to leave on top. | |
| 399 lua_setfield(L, idx, k); // lua_stack[idx][k] = lua_stack[-1] (table) | |
| 400 } | |
| 401 | |
| 402 return 1; | |
| 403 } | |
| 404 | |
| 405 int luax_insistglobal(lua_State *L, const char *k) | |
| 406 { | |
| 407 lua_getglobal(L, k); | |
| 408 | |
| 409 if (!lua_istable(L, -1)) | |
| 410 { | |
| 411 lua_pop(L, 1); // Pop the non-table. | |
| 412 lua_newtable(L); | |
| 413 lua_pushvalue(L, -1); | |
| 414 lua_setglobal(L, k); | |
| 415 } | |
| 416 | |
| 417 return 1; | |
| 418 } | |
| 419 | |
| 420 int luax_insistlove(lua_State *L, const char *k) | |
| 421 { | |
| 422 luax_insistglobal(L, "love"); | |
| 423 luax_insist(L, -1, k); | |
| 424 | |
| 425 // The love table should be replaced with the top stack | |
| 426 // item. Only the reqested table should remain on the stack. | |
| 427 lua_replace(L, -2); | |
| 428 | |
| 429 return 1; | |
| 430 } | |
| 431 | |
| 432 int luax_getregistry(lua_State *L, Registry r) | |
| 433 { | |
| 434 switch (r) | |
| 435 { | |
| 436 case REGISTRY_GC: | |
| 437 return luax_insistlove(L, "_gc"); | |
| 438 case REGISTRY_MODULES: | |
| 439 return luax_insistlove(L, "_modules"); | |
| 440 default: | |
| 441 return luaL_error(L, "Attempted to use invalid registry."); | |
| 442 } | |
| 443 } | |
| 444 | |
| 445 StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] = | |
| 446 { | |
| 447 {"Invalid", INVALID_ID}, | |
| 448 | |
| 449 {"Object", OBJECT_ID}, | |
| 450 {"Data", DATA_ID}, | |
| 451 {"Module", MODULE_ID}, | |
| 452 | |
| 453 // Filesystem | |
| 454 {"File", FILESYSTEM_FILE_ID}, | |
| 455 {"FileData", FILESYSTEM_FILE_DATA_ID}, | |
| 456 | |
| 457 // Font | |
| 458 {"GlyphData", FONT_GLYPH_DATA_ID}, | |
| 459 {"Rasterizer", FONT_RASTERIZER_ID}, | |
| 460 | |
| 461 // Graphics | |
| 462 {"Drawable", GRAPHICS_DRAWABLE_ID}, | |
| 463 {"Image", GRAPHICS_IMAGE_ID}, | |
| 464 {"Quad", GRAPHICS_QUAD_ID}, | |
| 465 {"Font", GRAPHICS_FONT_ID}, | |
| 466 {"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID}, | |
| 467 {"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID}, | |
| 468 {"Canvas", GRAPHICS_CANVAS_ID}, | |
| 469 | |
| 470 // Image | |
| 471 {"ImageData", IMAGE_IMAGE_DATA_ID}, | |
| 472 | |
| 473 // Audio | |
| 474 {"Source", AUDIO_SOURCE_ID}, | |
| 475 | |
| 476 // Sound | |
| 477 {"SoundData", SOUND_SOUND_DATA_ID}, | |
| 478 {"Decoder", SOUND_DECODER_ID}, | |
| 479 | |
| 480 // Physics | |
| 481 {"World", PHYSICS_WORLD_ID}, | |
| 482 {"Contact", PHYSICS_CONTACT_ID}, | |
| 483 {"Body", PHYSICS_BODY_ID}, | |
| 484 {"Shape", PHYSICS_SHAPE_ID}, | |
| 485 {"CircleShape", PHYSICS_CIRCLE_SHAPE_ID}, | |
| 486 {"PolygonShape", PHYSICS_POLYGON_SHAPE_ID}, | |
| 487 {"Joint", PHYSICS_JOINT_ID}, | |
| 488 {"MouseJoint", PHYSICS_MOUSE_JOINT_ID}, | |
| 489 {"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID}, | |
| 490 {"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID}, | |
| 491 {"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID}, | |
| 492 {"PulleyJoint", PHYSICS_PULLEY_JOINT_ID}, | |
| 493 {"GearJoint", PHYSICS_GEAR_JOINT_ID}, | |
| 494 | |
| 495 // Thread | |
| 496 {"Thread", THREAD_THREAD_ID}, | |
|
1098
a74672ba1320
Merge in channels from love-experiments
Bart van Strien <bart.bes+projects@gmail.com>
parents:
1096
diff
changeset
|
497 {"Channel", THREAD_CHANNEL_ID}, |
| 1096 | 498 |
| 499 // The modules themselves. Only add abstracted modules here. | |
| 500 {"filesystem", MODULE_FILESYSTEM_ID}, | |
| 501 {"image", MODULE_IMAGE_ID}, | |
| 502 {"sound", MODULE_SOUND_ID}, | |
| 503 }; | |
| 504 | |
| 505 StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries)); | |
| 506 | |
| 507 Type luax_type(lua_State *L, int idx) | |
| 508 { | |
| 509 Type t = INVALID_ID; | |
| 510 types.find(luaL_checkstring(L, idx), t); | |
| 511 return t; | |
| 512 } | |
| 513 | |
| 514 } // love |
