A single-file-header for embedding lua, offering helper functions and classes for metatable/userdata creation.
NOTE: In order for the example project to compile without errors, building the static libs (win32) of Lua is required.
classEntity; DECLARE_LUA_OBJ(Entity, "Entity") // makes Lua_Entity wrapper namespace LuaEntity{intlua_destructor(lua_State* L); intlua_getname(lua_State* L); intlua_gethealth(lua_State* L); BEGIN_LUA_REG DEFINE_LUA_GCREG(lua_destructor) // garbage collectionDEFINE_LUA_REG("GetName", lua_getname) DEFINE_LUA_REG("GetHealth", lua_gethealth) END_LUA_REG staticintregisterclass(lua_State* L){luaL_newmetatable(L, "Player"); luaL_setfuncs(L, regs, 0); lua_pushvalue(L, -1); lua_setfield(L, -1, "__index"); lua_pop(L, 1); return0} }intLuaEntity::lua_destructor(lua_State* L){Lua_Entity* obj = lua_checkudata<Lua_Entity>(L, 1, "Entity"); delete obj; return0} intLuaEntity::lua_getname(lua_State* L){Lua_Entity* obj = lua_checkudata<Lua_Entity>(L, 1, "Entity"); lua_pushstring(L, obj->GetName()) return1} intLuaEntity::lua_gethealth(lua_State* L){Lua_Entity* obj = lua_checkudata<Lua_Entity>(L, 1, "Entity"); luaL_pushinteger(L, obj->GetHealth()) return1}With Lua, there is no official implementation of inheritance, meaning metatable/userdata cannot derive from a base class. As a result, [normally] the developer is required to implement the same function in each metatable. This header counters this.
namespaceLuaEnt{staticintlua_gethealth(lua_State* L){Lua_Entity* ptr = lua_checkudata<Lua_Entity>(L, 1, "Entity"); lua_pushinteger(L, ptr->GetHealth()); return1} staticintlua_sethealth(lua_State* L){Lua_Entity* ptr = lua_checkudata<Lua_Entity>(L, 1, "Entity"); int iHealth = luaL_checkint(L, 2); ptr->SetHealth(iHealth); return1} BEGIN_LUA_REG DEFINE_LUA_REG("GetHealth", lua_gethealth) DEFINE_LUA_REG("SetHealth", lua_sethealth) END_LUA_REG } namespaceLuaPlayer{// functiom from base class 'Entity'staticintlua_gethealth(lua_State* L){Lua_Player* ptr = lua_checkudata<Lua_Player>(L, 1, "Player"); lua_pushinteger(L, ptr->GetHealth()); return1} // functiom from base class 'Entity'staticintlua_sethealth(lua_State* L){Lua_Player* ptr = lua_checkudata<Lua_Player>(L, 1, "Player"); int iHealth = luaL_checkint(L, 2); ptr->SetHealth(iHealth); return1} // <insert other member functions here>... BEGIN_LUA_REG DEFINE_LUA_REG("GetHealth", lua_gethealth) DEFINE_LUA_REG("SetHealth", lua_sethealth) END_LUA_REG } namespaceLuaNPC{// functiom from base class 'Entity'staticintlua_gethealth(lua_State* L){Lua_NPC* ptr = lua_checkudata<Lua_NPC>(L, 1, "NPC"); lua_pushinteger(L, ptr->GetHealth()); return1} // functiom from base class 'Entity'staticintlua_sethealth(lua_State* L){Lua_NPC* ptr = lua_checkudata<Lua_NPC>(L, 1, "NPC"); int iHealth = luaL_checkint(L, 2); ptr->SetHealth(iHealth); return1} // <insert other member functions here>... BEGIN_LUA_REG DEFINE_LUA_REG("GetHealth", lua_gethealth) DEFINE_LUA_REG("SetHealth", lua_sethealth) END_LUA_REG }DECLARE_LUA_OBJ(NPC, "NPC") // wrapper for npc - Lua_NPC DECLARE_LUA_OBJ(Player, "Player") // wrapper for player - Lua_Player LuaTypes g_EntityTypes ={LuaTypeEntry("NPC", LUA_HANDLER_NAME(NPC)), LuaTypeEntry("Player", LUA_HANDLER_NAME(Player)) }; namespaceLuaEnt{staticintlua_gethealth(lua_State* L){Entity* ptr = lua_checkudata_poly<Entity>(L, 1, g_EntityTypes); lua_pushinteger(L, ptr->GetHealth()); return1} staticintlua_sethealth(lua_State* L){Entity* ptr = lua_checkudata_poly<Entity>(L, 1, g_EntityTypes); int iHealth = luaL_checkint(L, 2); ptr->SetHealth(iHealth); return1} } namespaceLuaPlayer{// <insert other member functions here>... BEGIN_LUA_REG DEFINE_LUA_REG("GetHealth", LuaEnt::lua_gethealth) DEFINE_LUA_REG("SetHealth", LuaEnt::lua_sethealth) END_LUA_REG } namespaceLuaNPC{// <insert other member functions here>... BEGIN_LUA_REG DEFINE_LUA_REG("GetHealth", LuaEnt::lua_gethealth) DEFINE_LUA_REG("SetHealth", LuaEnt::lua_sethealth) END_LUA_REG }MyClass* ptr = new MyClass(); lua_pushobject(L, new Lua_MyClass(ptr), "MyMetatableName");