diff --git a/module/Core/Privilege.cpp b/module/Core/Privilege.cpp index c8c6fd99..fe74306f 100644 --- a/module/Core/Privilege.cpp +++ b/module/Core/Privilege.cpp @@ -342,6 +342,8 @@ bool PvManager::HaveUnitWithTag(StackStrF & tag) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveEntryWithID(SQInteger id) { + ModifyEntries(); + // Remove this entry from the units for (const auto & u : m_Units) { @@ -359,6 +361,8 @@ void PvManager::RemoveEntryWithID(SQInteger id) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveEntryWithTag(StackStrF & tag) { + ModifyEntries(); + PvEntry & e = *GetValidEntryWithTag(tag); // Remove this entry from the units for (const auto & u : m_Units) @@ -383,6 +387,8 @@ void PvManager::RemoveEntryWithTag(StackStrF & tag) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveClassWithID(SqPvClass & sub, SQInteger id) { + ModifyClasses(); + PvClass::Ref cls = sub.mI.lock(); // Remove this entry from units for (const auto & u : m_Units) @@ -409,6 +415,8 @@ void PvManager::RemoveClassWithID(SqPvClass & sub, SQInteger id) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveClassWithTag(SqPvClass & sub, StackStrF & tag) { + ModifyClasses(); + PvClass::Ref cls = sub.mI.lock(); // Remove this class from units for (const auto & u : m_Units) @@ -441,6 +449,8 @@ void PvManager::RemoveClassWithTag(SqPvClass & sub, StackStrF & tag) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveUnitWithID(SQInteger id) { + ModifyUnits(); + // Remove this class from classes for (const auto & c : m_Classes) { @@ -453,6 +463,8 @@ void PvManager::RemoveUnitWithID(SQInteger id) // ------------------------------------------------------------------------------------------------ void PvManager::RemoveUnitWithTag(StackStrF & tag) { + ModifyUnits(); + PvUnit & u = *GetValidUnitWithTag(tag); // Remove this class from classes for (const auto & c : m_Classes) @@ -469,6 +481,42 @@ void PvManager::RemoveUnitWithTag(StackStrF & tag) } } +// ------------------------------------------------------------------------------------------------ +void PvManager::EachEntryID(Object & ctx, Function & func) +{ + // Prevent any changes to entries during this operation + AutoAssign< bool > aag(m_LockEntries, false, true); + // Iterate entries and forward the ID to the callback + for (const auto & e : m_Entries) + { + func(ctx, e.second->mID); + } +} + +// ------------------------------------------------------------------------------------------------ +void PvManager::EachClassID(Object & ctx, Function & func) +{ + // Prevent any changes to classes during this operation + AutoAssign< bool > aag(m_LockClasses, false, true); + // Iterate classes and forward the ID to the callback + for (const auto & c : m_Classes) + { + func(ctx, c.second->mID); + } +} + +// ------------------------------------------------------------------------------------------------ +void PvManager::EachUnitID(Object & ctx, Function & func) +{ + // Prevent any changes to units during this operation + AutoAssign< bool > aag(m_LockUnits, false, true); + // Iterate units and forward the ID to the callback + for (const auto & u : m_Units) + { + func(ctx, u.second->mID); + } +} + // ------------------------------------------------------------------------------------------------ extern void Register_Privilege_Class(HSQUIRRELVM vm, Table & ns); extern void Register_Privilege_Entry(HSQUIRRELVM vm, Table & ns); @@ -523,6 +571,9 @@ void Register_Privilege(HSQUIRRELVM vm) .FmtFunc(_SC("RemoveEntryWithTag"), &PvManager::RemoveEntryWithTag) .Func(_SC("RemoveClass"), &PvManager::RemoveClassWithID) .FmtFunc(_SC("RemoveClassWithTag"), &PvManager::RemoveClassWithTag) + .FmtFunc(_SC("EachEntryID"), &PvManager::EachEntryID) + .FmtFunc(_SC("EachClassID"), &PvManager::EachClassID) + .FmtFunc(_SC("EachUnitID"), &PvManager::EachUnitID) ); RootTable(vm).Bind(_SC("SqPrivilege"), ns); diff --git a/module/Core/Privilege.hpp b/module/Core/Privilege.hpp index a88c2474..5db702ec 100644 --- a/module/Core/Privilege.hpp +++ b/module/Core/Privilege.hpp @@ -646,6 +646,21 @@ public: * Remove a unit with a certain tag from this manager. */ void RemoveUnitWithTag(StackStrF & tag); + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every known entry identifier. + */ + void EachEntryID(Object & ctx, Function & func); + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every known class identifier. + */ + void EachClassID(Object & ctx, Function & func); + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every known unit identifier. + */ + void EachUnitID(Object & ctx, Function & func); }; } // Namespace:: SqMod diff --git a/module/Core/Privilege/Class.cpp b/module/Core/Privilege/Class.cpp index 1b792a67..4a39753b 100644 --- a/module/Core/Privilege/Class.cpp +++ b/module/Core/Privilege/Class.cpp @@ -390,6 +390,30 @@ bool PvClass::HaveUnitWithTag(StackStrF & tag) return false; } +// ------------------------------------------------------------------------------------------------ +void PvClass::EachEntryID(Object & ctx, Function & func) +{ + // In order to be safe from modifications while iterating, create a copy + PvStatusList list(mPrivileges); + // Iterate entries and forward the ID to the callback + for (const auto & e : list) + { + func(ctx, e.first); + } +} + +// ------------------------------------------------------------------------------------------------ +void PvClass::EachUnitID(Object & ctx, Function & func) +{ + // In order to be safe from modifications while iterating, create a copy + PvUnit::List list(mUnits); + // Iterate units and forward the ID to the callback + for (const auto & u : list) + { + func(ctx, u.second->mID); + } +} + // ================================================================================================ bool SqPvClass::Can(LightObj & obj) const { @@ -462,6 +486,8 @@ void Register_Privilege_Class(HSQUIRRELVM vm, Table & ns) .FmtFunc(_SC("GetUnitWithTag"), &SqPvClass::GetUnitWithTag) .Func(_SC("HaveUnit"), &SqPvClass::HaveUnitWithID) .FmtFunc(_SC("HaveUnitWithTag"), &SqPvClass::HaveUnitWithTag) + .FmtFunc(_SC("EachEntryID"), &SqPvClass::EachEntryID) + .FmtFunc(_SC("EachUnitID"), &SqPvClass::EachUnitID) ); } diff --git a/module/Core/Privilege/Class.hpp b/module/Core/Privilege/Class.hpp index 168aa191..b4149864 100644 --- a/module/Core/Privilege/Class.hpp +++ b/module/Core/Privilege/Class.hpp @@ -296,6 +296,16 @@ struct PvClass * See if a unit with a certain tag inherits this class. */ bool HaveUnitWithTag(StackStrF & tag); + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every owned entry identifier. + */ + void EachEntryID(Object & ctx, Function & func); + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every parented unit identifier. + */ + void EachUnitID(Object & ctx, Function & func); }; /* ------------------------------------------------------------------------------------------------ @@ -358,6 +368,9 @@ struct SqPvClass SQMOD_NODISCARD LightObj GetUnitWithTag(StackStrF & tag) const { return Valid().GetUnitWithTag(tag); } SQMOD_NODISCARD bool HaveUnitWithID(SQInteger id) const { return Valid().HaveUnitWithID(id); } SQMOD_NODISCARD bool HaveUnitWithTag(StackStrF & tag) const { return Valid().HaveUnitWithTag(tag); } + // -------------------------------------------------------------------------------------------- + void EachEntryID(Object & ctx, Function & func) { return Valid().EachEntryID(ctx, func); } + void EachUnitID(Object & ctx, Function & func) { return Valid().EachUnitID(ctx, func); } }; } // Namespace:: SqMod diff --git a/module/Core/Privilege/Unit.cpp b/module/Core/Privilege/Unit.cpp index dea307d8..69bbe130 100644 --- a/module/Core/Privilege/Unit.cpp +++ b/module/Core/Privilege/Unit.cpp @@ -342,6 +342,18 @@ bool PvUnit::Can(SQInteger id) const return false; } +// ------------------------------------------------------------------------------------------------ +void PvUnit::EachEntryID(Object & ctx, Function & func) +{ + // In order to be safe from modifications while iterating, create a copy + PvStatusList list(mPrivileges); + // Iterate entries and forward the ID to the callback + for (const auto & e : list) + { + func(ctx, e.first); + } +} + // ================================================================================================ LightObj SqPvUnit::GetClass() const { @@ -429,6 +441,7 @@ void Register_Privilege_Unit(HSQUIRRELVM vm, Table & ns) .Func(_SC("Modify"), &SqPvUnit::ModifyPrivilegeWithID) .FmtFunc(_SC("ModifyWithTag"), &SqPvUnit::ModifyPrivilegeWithTag) .Func(_SC("RemoveAll"), &SqPvUnit::RemoveAllPrivileges) + .Func(_SC("EachEntryID"), &SqPvUnit::EachEntryID) ); } diff --git a/module/Core/Privilege/Unit.hpp b/module/Core/Privilege/Unit.hpp index eec10d54..ea3b629e 100644 --- a/module/Core/Privilege/Unit.hpp +++ b/module/Core/Privilege/Unit.hpp @@ -249,6 +249,11 @@ struct PvUnit * Check if this unit has a certain privilege. */ SQMOD_NODISCARD bool Can(SQInteger id) const; + + /* -------------------------------------------------------------------------------------------- + * Invoke a given callback with every owned entry identifier. + */ + void EachEntryID(Object & ctx, Function & func); }; /* ------------------------------------------------------------------------------------------------ @@ -304,6 +309,8 @@ struct SqPvUnit void ModifyPrivilegeWithID(SQInteger id, SQInteger value) { Valid().ModifyPrivilege(id, value); } void ModifyPrivilegeWithTag(StackStrF & tag, SQInteger value) { Valid().ModifyPrivilege(tag, value); } void RemoveAllPrivileges() { Valid().RemoveAllPrivileges(); } + // -------------------------------------------------------------------------------------------- + void EachEntryID(Object & ctx, Function & func) { return Valid().EachEntryID(ctx, func); } }; } // Namespace:: SqMod