[lua] Add support to iterate properties using pairs()

This commit is contained in:
David Capello 2023-01-02 14:36:49 -03:00
parent ef0596fd01
commit 9f0491ddb6
2 changed files with 51 additions and 0 deletions

View File

@ -26,6 +26,8 @@ struct Properties {
Properties(doc::ObjectId id) : id(id) { }
};
using PropertiesIterator = doc::UserData::Properties::iterator;
int Properties_len(lua_State* L)
{
auto propObj = get_obj<Properties>(L, 1);
@ -116,20 +118,59 @@ int Properties_newindex(lua_State* L)
return 1;
}
int Properties_pairs_next(lua_State* L)
{
auto propObj = get_obj<Properties>(L, 1);
auto obj = static_cast<doc::WithUserData*>(get_object(propObj->id));
if (!obj)
return luaL_error(L, "the object with these properties was destroyed");
auto& properties = obj->userData().properties();
auto& it = *get_obj<PropertiesIterator>(L, lua_upvalueindex(1));
if (it == properties.end())
return 0;
lua_pushstring(L, (*it).first.c_str());
push_value_to_lua(L, (*it).second);
++it;
return 2;
}
int Properties_pairs(lua_State* L)
{
auto propObj = get_obj<Properties>(L, 1);
auto obj = static_cast<doc::WithUserData*>(get_object(propObj->id));
if (!obj)
return luaL_error(L, "the object with these properties was destroyed");
auto& properties = obj->userData().properties();
push_obj(L, properties.begin());
lua_pushcclosure(L, Properties_pairs_next, 1);
lua_pushvalue(L, 1); // Copy the same propObj as the second return value
return 2;
}
const luaL_Reg Properties_methods[] = {
{ "__len", Properties_len },
{ "__index", Properties_index },
{ "__newindex", Properties_newindex },
{ "__pairs", Properties_pairs },
{ nullptr, nullptr }
};
const luaL_Reg PropertiesIterator_methods[] = {
{ nullptr, nullptr }
};
} // anonymous namespace
DEF_MTNAME(Properties);
DEF_MTNAME(PropertiesIterator);
void register_properties_class(lua_State* L)
{
REG_CLASS(L, Properties);
REG_CLASS(L, PropertiesIterator);
}
void push_properties(lua_State* L, doc::WithUserData* userData)

View File

@ -17,6 +17,16 @@ do
assert(math.abs(spr.properties.d - 2.3) < 0.00001)
assert(#spr.properties == 4)
-- Iterate all properties
local t = {}
for k,v in pairs(spr.properties) do
t[k] = v
end
assert(t.a == true)
assert(t.b == 1)
assert(t.c == "hi")
assert(math.abs(t.d - 2.3) < 0.00001)
spr.properties.a = false
assert(spr.properties.a == false)