meta-meta table is functioning correctly

This commit is contained in:
Kayne Ruse
2015-03-27 21:54:41 +11:00
parent 9a5c447d0c
commit 39f03b2da8
2 changed files with 78 additions and 3 deletions
+8 -2
View File
@@ -37,7 +37,13 @@ roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrass
doorUtility.createDoorPair("pair 1", overworld, 0, -64, underworld, 0, 0)
--testing the metatables
local meta = getmetatable(underworld)
print("", "userdata metatable: ", meta)
print("debug")
overworld["key"] = "value"
local key = overworld["key"]
print("", "result: ", key)
local key = underworld["key"]
print("", "result: ", key)
--end test
print("Finished the lua script")
+70 -1
View File
@@ -23,13 +23,71 @@
#include <iostream>
#define METAMETA "__metameta"
static int index(lua_State* L) {
std::cout << "WARNING: userdataIndex called" << std::endl;
std::cout << "debug: index" << std::endl;
//get __metameta
lua_getmetatable(L, 1); //get the userdata metatable
lua_pushstring(L, METAMETA); //push the __metameta name
lua_gettable(L, -2); //get the __metameta field from the metatable
//get __metameta[userdata]
lua_pushvalue(L, 1); //copy of the userdata
lua_gettable(L, -2); //get the table at __metameta[userdata]
//table doesn't exist yet
if (lua_isnil(L, -1)) {
std::cout << "debug: index (no table)" << std::endl;
return 1;
}
//get the value at __metameta[userdata][key]
lua_pushvalue(L, 2); //copy the key
lua_gettable(L, -2); //get value from the deepest table
//return
return 1;
}
static int newindex(lua_State* L) {
std::cout << "debug: newindex" << std::endl;
//get __metameta
lua_getmetatable(L, 1); //get the userdata metatable
lua_pushstring(L, METAMETA); //push the __metameta name
lua_gettable(L, -2); //get the __metameta field from the metatable
//get __metameta[userdata]
lua_pushvalue(L, 1); //copy of the userdata
lua_gettable(L, -2); //get the table at __metameta[userdata]
//if this table doesn't exist yet
if (lua_isnil(L, -1)) {
std::cout << "debug: newindex (new table)" << std::endl;
lua_pop(L, 1); //pop nil
lua_pushvalue(L, 1); //copy userdata (key)
lua_createtable(L, 0, 0); //new table (value)
lua_settable(L, -3); //create the new table in __metameta
lua_pushvalue(L, 1); //copy userdata (key)
lua_gettable(L, -2); //get the newly created table
}
//set the value at __metameta[userdata][key] = value
lua_pushvalue(L, 2); //copy the key
lua_pushvalue(L, 3); //copy the value
lua_settable(L, -3); //set value in the deepest table
//return
return 0;
}
static luaL_Reg metatable[] = {
{"__index", index},
{"__newindex", newindex},
{nullptr, nullptr}
};
@@ -38,6 +96,17 @@ int createUserdataMetatable(lua_State* L) {
lua_pushlightuserdata(L, nullptr); //anon userdata
lua_createtable(L, 0, 0); //table
//insert meta-metatable
lua_pushstring(L, METAMETA);
lua_createtable(L, 0, 0);
lua_settable(L, -3);
//insert metatable blocker
lua_pushstring(L, "__metatable");
lua_createtable(L, 0, 0);
lua_settable(L, -3);
//insert metamethods
for (luaL_Reg* it = metatable; it->name; it++) {
lua_pushstring(L, it->name);
lua_pushcfunction(L, it->func);