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)
|
doorUtility.createDoorPair("pair 1", overworld, 0, -64, underworld, 0, 0)
|
||||||
|
|
||||||
--testing the metatables
|
--testing the metatables
|
||||||
local meta = getmetatable(underworld)
|
print("debug")
|
||||||
print("", "userdata metatable: ", meta)
|
overworld["key"] = "value"
|
||||||
|
local key = overworld["key"]
|
||||||
|
print("", "result: ", key)
|
||||||
|
|
||||||
|
local key = underworld["key"]
|
||||||
|
print("", "result: ", key)
|
||||||
|
--end test
|
||||||
|
|
||||||
print("Finished the lua script")
|
print("Finished the lua script")
|
||||||
|
|||||||
+70
-1
@@ -23,13 +23,71 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#define METAMETA "__metameta"
|
||||||
|
|
||||||
static int index(lua_State* L) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static luaL_Reg metatable[] = {
|
static luaL_Reg metatable[] = {
|
||||||
{"__index", index},
|
{"__index", index},
|
||||||
|
{"__newindex", newindex},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,6 +96,17 @@ int createUserdataMetatable(lua_State* L) {
|
|||||||
lua_pushlightuserdata(L, nullptr); //anon userdata
|
lua_pushlightuserdata(L, nullptr); //anon userdata
|
||||||
lua_createtable(L, 0, 0); //table
|
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++) {
|
for (luaL_Reg* it = metatable; it->name; it++) {
|
||||||
lua_pushstring(L, it->name);
|
lua_pushstring(L, it->name);
|
||||||
lua_pushcfunction(L, it->func);
|
lua_pushcfunction(L, it->func);
|
||||||
|
|||||||
Reference in New Issue
Block a user