meta-meta table is functioning correctly
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user