diff --git a/src/app/script/properties_class.cpp b/src/app/script/properties_class.cpp index 8d91c55d1..7934128c3 100644 --- a/src/app/script/properties_class.cpp +++ b/src/app/script/properties_class.cpp @@ -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(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(L, 1); + auto obj = static_cast(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(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(L, 1); + auto obj = static_cast(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) diff --git a/tests/scripts/userdata.lua b/tests/scripts/userdata.lua index 9cb766d07..401deab03 100644 --- a/tests/scripts/userdata.lua +++ b/tests/scripts/userdata.lua @@ -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)