Lua: allow jarray and jobject to convert existing tables

[skip ci]
This commit is contained in:
Kae 2024-03-17 01:52:02 +11:00
parent 8f8741bcb2
commit d577a98980
2 changed files with 37 additions and 12 deletions

View File

@ -370,8 +370,8 @@ LuaEnginePtr LuaEngine::create(bool safe) {
self->m_scriptDefaultEnvRegistryId = luaL_ref(self->m_state, LUA_REGISTRYINDEX); self->m_scriptDefaultEnvRegistryId = luaL_ref(self->m_state, LUA_REGISTRYINDEX);
lua_pop(self->m_state, 1); lua_pop(self->m_state, 1);
self->setGlobal("jarray", self->createFunction(&LuaDetail::jarrayCreate)); self->setGlobal("jarray", self->createFunction(&LuaDetail::jarray));
self->setGlobal("jobject", self->createFunction(&LuaDetail::jobjectCreate)); self->setGlobal("jobject", self->createFunction(&LuaDetail::jobject));
self->setGlobal("jremove", self->createFunction(&LuaDetail::jcontRemove)); self->setGlobal("jremove", self->createFunction(&LuaDetail::jcontRemove));
self->setGlobal("jsize", self->createFunction(&LuaDetail::jcontSize)); self->setGlobal("jsize", self->createFunction(&LuaDetail::jcontSize));
self->setGlobal("jresize", self->createFunction(&LuaDetail::jcontResize)); self->setGlobal("jresize", self->createFunction(&LuaDetail::jcontResize));
@ -1308,10 +1308,7 @@ void LuaDetail::shallowCopy(lua_State* state, int sourceIndex, int targetIndex)
} }
} }
LuaTable LuaDetail::jsonContainerToTable(LuaEngine& engine, Json const& container) { LuaTable LuaDetail::insertJsonMetatable(LuaEngine& engine, LuaTable const& table, Json::Type type) {
if (!container.isType(Json::Type::Array) && !container.isType(Json::Type::Object))
throw LuaException("jsonContainerToTable called on improper json type");
auto newIndexMetaMethod = [](LuaTable const& table, LuaValue const& key, LuaValue const& value) { auto newIndexMetaMethod = [](LuaTable const& table, LuaValue const& key, LuaValue const& value) {
auto mt = table.getMetatable(); auto mt = table.getMetatable();
auto nils = mt->rawGet<LuaTable>("__nils"); auto nils = mt->rawGet<LuaTable>("__nils");
@ -1330,13 +1327,16 @@ LuaTable LuaDetail::jsonContainerToTable(LuaEngine& engine, Json const& containe
auto nils = engine.createTable(); auto nils = engine.createTable();
mt.rawSet("__nils", nils); mt.rawSet("__nils", nils);
mt.rawSet("__newindex", engine.createFunction(newIndexMetaMethod)); mt.rawSet("__newindex", engine.createFunction(newIndexMetaMethod));
if (container.isType(Json::Type::Array)) mt.rawSet("__typehint", type == Json::Type::Array ? 1 : 2);
mt.rawSet("__typehint", 1); return nils;
else }
mt.rawSet("__typehint", 2);
LuaTable LuaDetail::jsonContainerToTable(LuaEngine& engine, Json const& container) {
if (!container.isType(Json::Type::Array) && !container.isType(Json::Type::Object))
throw LuaException("jsonContainerToTable called on improper json type");
auto table = engine.createTable(); auto table = engine.createTable();
table.setMetatable(mt); auto nils = insertJsonMetatable(engine, table, container.type());
if (container.isType(Json::Type::Array)) { if (container.isType(Json::Type::Array)) {
auto vlist = container.arrayPtr(); auto vlist = container.arrayPtr();
@ -1437,6 +1437,25 @@ Json LuaDetail::jobjectCreate() {
return JsonObject(); return JsonObject();
} }
LuaTable LuaDetail::jarray(LuaEngine& engine, Maybe<LuaTable> table) {
if (auto t = table.ptr()) {
insertJsonMetatable(engine, *t, Json::Type::Array);
return *t;
} else {
return jsonContainerToTable(engine, JsonArray());
}
}
LuaTable LuaDetail::jobject(LuaEngine& engine, Maybe<LuaTable> table) {
if (auto t = table.ptr()) {
insertJsonMetatable(engine, *t, Json::Type::Object);
return *t;
} else {
return jsonContainerToTable(engine, JsonObject());
}
}
void LuaDetail::jcontRemove(LuaTable const& table, LuaValue const& key) { void LuaDetail::jcontRemove(LuaTable const& table, LuaValue const& key) {
if (auto mt = table.getMetatable()) { if (auto mt = table.getMetatable()) {
if (auto nils = mt->rawGet<Maybe<LuaTable>>("__nils")) if (auto nils = mt->rawGet<Maybe<LuaTable>>("__nils"))

View File

@ -1467,6 +1467,8 @@ namespace LuaDetail {
// index. // index.
void shallowCopy(lua_State* state, int sourceIndex, int targetIndex); void shallowCopy(lua_State* state, int sourceIndex, int targetIndex);
LuaTable insertJsonMetatable(LuaEngine& engine, LuaTable const& table, Json::Type type);
// Creates a custom lua table from a JsonArray or JsonObject that has // Creates a custom lua table from a JsonArray or JsonObject that has
// slightly different behavior than a standard lua table. The table // slightly different behavior than a standard lua table. The table
// remembers nil entries, as well as whether it was initially constructed // remembers nil entries, as well as whether it was initially constructed
@ -1489,10 +1491,14 @@ namespace LuaDetail {
// Create a JsonList container table // Create a JsonList container table
Json jarrayCreate(); Json jarrayCreate();
// Create a JsonMap container table // Create a JsonMap container table
Json jobjectCreate(); Json jobjectCreate();
// Adds the Json array metatable to a Lua table or creates one.
LuaTable jarray(LuaEngine& engine, Maybe<LuaTable> table);
// Adds the Json object metatable to a Lua table or creates one.
LuaTable jobject(LuaEngine& engine, Maybe<LuaTable> table);
// *Really* remove an entry from a JsonList or JsonMap container table, // *Really* remove an entry from a JsonList or JsonMap container table,
// including removing it from the __nils table. If the given table is not a // including removing it from the __nils table. If the given table is not a
// special container table, is equivalent to setting the key entry to nil. // special container table, is equivalent to setting the key entry to nil.