Mercurial > code
view C++/Luae.cpp @ 186:d4b8416e9ab1
Move C
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 23 Nov 2013 16:14:05 +0100 |
parents | 15b264d9e833 |
children | 258087829c66 |
line wrap: on
line source
/* * Luae.cpp -- Lua helpers and such * * Copyright (c) 2011, 2012, 2013 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "Luae.h" void LuaeClass::createClass(lua_State *L, const LuaObject &cls) { LUA_STACK_CHECKBEGIN(L); // Already registered? if (luaL_newmetatable(L, cls.name) == 0) return; // Add it's "name" field lua_pushstring(L, cls.name); lua_setfield(L, -2, LUAE_CLASS_FIELDNAME); // Create a list of parent for a faster cast lua_createtable(L, 0, 0); int i = 0; for (auto p = cls.parent; p != nullptr; p = p->parent) { lua_pushstring(L, p->name); lua_rawseti(L, -2, ++i); } lua_setfield(L, -2, LUAE_CLASS_FIELDPARENTS); // Metamethods if (cls.metamethods.size() > 0) luaL_setfuncs(L, cls.metamethods.data(), 0); // Methods lua_createtable(L, 0, 0); if (cls.methods.size() > 0) { luaL_setfuncs(L, cls.methods.data(), 0); } /* * Add a metatable to this __index table so that if * a method is not found it use the parent table recursively */ if (cls.parent) { // 1. Get the parent luaL_getmetatable(L, cls.parent->name); assert(lua_type(L, -1) != LUA_TNIL); // 2. Create an anonymous metatable lua_createtable(L, 1, 1); // 3. Get the __index field from this metatable lua_getfield(L, -2, "__index"); assert(lua_type(L, -1) != LUA_TNIL); lua_setfield(L, -2, "__index"); lua_setmetatable(L, -3); lua_pop(L, 1); } lua_setfield(L, -2, "__index"); // Pop that metatable lua_pop(L, 1); LUA_STACK_CHECKEQUALS(L); } /* -------------------------------------------------------- * Luae public methods * -------------------------------------------------------- */ void Luae::createEnum(lua_State *L, const LuaEnum *enumeration) { lua_createtable(L, 0, 0); for (int i = 0; enumeration[i].name != nullptr; ++i) { lua_pushinteger(L, enumeration[i].value); lua_setfield(L, -2, enumeration[i].name); } } void Luae::createLibrary(lua_State *L, const luaL_Reg *functions) { LUA_STACK_CHECKBEGIN(L); lua_createtable(L, 0, 0); luaL_setfuncs(L, functions, 0); LUA_STACK_CHECKEND(L, - 1); } template <> bool Luae::getField(lua_State *L, int idx, const std::string & name) { bool value = false; lua_getfield(L, idx, name.c_str()); if (lua_type(L, idx) == LUA_TBOOLEAN) value = lua_toboolean(L, -1) == 1; lua_pop(L, 1); return value; } template <> double Luae::getField(lua_State *L, int idx, const std::string & name) { double value = 0; lua_getfield(L, idx, name.c_str()); if (lua_type(L, idx) == LUA_TNUMBER) value = lua_tonumber(L, -1); lua_pop(L, 1); return value; } template <> int Luae::getField(lua_State *L, int idx, const std::string & name) { int value = 0; lua_getfield(L, idx, name.c_str()); if (lua_type(L, idx) == LUA_TNUMBER) value = lua_tointeger(L, -1); lua_pop(L, 1); return value; } template <> std::string Luae::getField(lua_State *L, int idx, const std::string & name) { std::string value; lua_getfield(L, idx, name.c_str()); if (lua_type(L, idx) == LUA_TSTRING) value = lua_tostring(L, -1); lua_pop(L, 1); return value; } void Luae::preload(lua_State *L, const std::string & name, lua_CFunction func) { LUA_STACK_CHECKBEGIN(L); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_pushcfunction(L, func); lua_setfield(L, -2, name.c_str()); lua_pop(L, 2); LUA_STACK_CHECKEQUALS(L); } void Luae::readTable(lua_State *L, int idx, ReadFunction func) { lua_pushnil(L); if (idx < 0) --idx; while (lua_next(L, idx)) { func(L, lua_type(L, -2), lua_type(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); } int Luae::referenceField(lua_State *L, int idx, int type, const std::string & name) { int ref = LUA_REFNIL; lua_getfield(L, idx, name.c_str()); if (lua_type(L, -1) == type) { lua_pushvalue(L, -1); ref = luaL_ref(L, LUA_REGISTRYINDEX); } lua_pop(L, 1); return ref; } void Luae::require(lua_State *L, const std::string & name, lua_CFunction func, bool global) { LUA_STACK_CHECKBEGIN(L); luaL_requiref(L, name.c_str(), func, global); lua_pop(L, 1); LUA_STACK_CHECKEQUALS(L); } void * operator new(size_t size, lua_State *L) { return lua_newuserdata(L, size); } void * operator new(size_t size, lua_State *L, const char *metaname) { void *object; object = lua_newuserdata(L, size); luaL_setmetatable(L, metaname); return object; } void operator delete(void *, lua_State *) { } void operator delete(void *, lua_State *L, const char *) { lua_pushnil(L); lua_setmetatable(L, -2); }