From f0779f57cb8e15381bc3882cf035f3f483e06f2c Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 4 Sep 2020 23:52:52 +0300 Subject: [PATCH] Discard previous approach. Left incomplete untill further notice. --- module/Misc/Privilege.cpp | 442 +++++++----------- module/Misc/Privilege.hpp | 934 +++++++------------------------------- 2 files changed, 309 insertions(+), 1067 deletions(-) diff --git a/module/Misc/Privilege.cpp b/module/Misc/Privilege.cpp index a38c94a9..e37c23c9 100644 --- a/module/Misc/Privilege.cpp +++ b/module/Misc/Privilege.cpp @@ -17,309 +17,189 @@ static constexpr size_t BAD_POS = ~static_cast< size_t >(0); // ------------------------------------------------------------------------------------------------ PvManagers PvManager::s_Managers; -// ------------------------------------------------------------------------------------------------ -PvManager & PvUnit::GetManager() const +/* ------------------------------------------------------------------------------------------------ + * Privilege unit wrapper. +*/ +class PvUnitWrap { - return m_Class->GetManager(); // Classes must always have a manager! -} -// ------------------------------------------------------------------------------------------------ -PvClass & PvUnit::GetClass() const -{ - return *m_Class; // Units must always have a class! -} -// ------------------------------------------------------------------------------------------------ -void PvUnit::SetClass(PvClass & cls) -{ - cls.AddUnit(*this); -} -// ------------------------------------------------------------------------------------------------ -bool PvUnit::Can(const PvEntry & entry) const -{ - return false; -} -// ------------------------------------------------------------------------------------------------ -bool PvUnit::Can(const PvEntry & entry, const PvUnit & unit) const -{ - return false; -} +private: -// ------------------------------------------------------------------------------------------------ -PvUnit * PvClass::GetUnitByID(SQInteger id) const -{ - // Locate the requested unit - for (const auto & e : m_Units) + /* -------------------------------------------------------------------------------------------- + * + */ + PvUnit::Ref mInst; + +public: + + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvUnitWrap(SQInteger id, PvClass * cls) { - if (e.first == id) - { - return e.second; - } } - // No such unit - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -PvUnit * PvClass::GetUnitByTag(StackStrF & name) const -{ - // Retrieve the hash - auto hash = name.HashIt(); - // Locate the requested unit - for (const auto & e : m_Units) + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvUnitWrap(SQInteger id, StackStrF && tag, PvClass * cls) { - // Does the string hash match? - if (e.second->GetTagW().GetHash() == hash && - // Check if the whole string matches as well - strncmp(name.mPtr, e.second->GetTagW().mPtr, - std::min(name.mLen, e.second->GetTagW().mLen)) == 0) - { - return e.second; // This is what we're looking for - } } - // No such unit - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -LightObj PvClass::CreateUnit(SQInteger id, StackStrF & name) -{ - return m_Manager->CreateUnitImpl(id, *this, name).second; -} + /* ------------------------------------------------------------------------------------------- + * Copy constructor (disabled). + */ + PvUnitWrap(const PvUnitWrap & o) = delete; -// ------------------------------------------------------------------------------------------------ -void PvClass::AddUnit(PvUnit & unit) -{ - // Is this unit already of this class? - if (&unit.GetClass() == this) + /* ------------------------------------------------------------------------------------------- + * Destructor. + */ + ~PvUnitWrap(); + + /* ------------------------------------------------------------------------------------------- + * Copy assignment operator (disabled). + */ + PvUnitWrap & operator = (const PvUnitWrap & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Release all script resources. Recursively forward request. + */ + void Release() { - return; // Nothing to change! - } - // Remove it from current class - unit.GetClass().UnlistUnit(unit); - // Enlist it with us - EnlistUnit(unit); - // Who's your daddy now! - unit.m_Class = this; -} -// ------------------------------------------------------------------------------------------------ -bool PvClass::EnlistUnit(PvUnit & unit) + } + +}; + +/* ------------------------------------------------------------------------------------------------ + * Privilege class wrapper. +*/ +class PvClassWrap { - // Does it exist already? - for (const auto & e : m_Units) + friend class PvManager; + +private: + + /* -------------------------------------------------------------------------------------------- + * + */ + PvClass::Ref mInst; + +public: + + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvClassWrap(SQInteger id, PvManager * mgr) { - if (e.first == unit.GetID()) - { - return false; // Already enlisted here! - } } - // Enlist it now - m_Units.emplace_back(unit.GetID(), &unit); - // Enlisted now - return true; -} -// ------------------------------------------------------------------------------------------------ -bool PvClass::UnlistUnit(PvUnit & unit) -{ - // Locate the entry in our list - auto it = std::find_if(m_Units.cbegin(), m_Units.cend(), - [=, id = unit.GetID()](PvUnitList::const_reference e) -> bool { - return e.first == id; - }); - // Is this unit enlisted here? - if (it == m_Units.end()) + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvClassWrap(SQInteger id, StackStrF && tag, PvManager * mgr) { - return false; // Not enlisted here! } - // Remove the unit from out container - m_Units.erase(it); - // Unlisted now - return true; -} -// ------------------------------------------------------------------------------------------------ + /* ------------------------------------------------------------------------------------------- + * Copy constructor (disabled). + */ + PvClassWrap(const PvClassWrap & o) = delete; -// ------------------------------------------------------------------------------------------------ + /* ------------------------------------------------------------------------------------------- + * Move constructor (disabled). + */ + PvClassWrap(PvClassWrap && o) = delete; -// ------------------------------------------------------------------------------------------------ + /* ------------------------------------------------------------------------------------------- + * Destructor. + */ + ~PvClassWrap(); -// ------------------------------------------------------------------------------------------------ -PvEntry * PvManager::GetEntryByID(SQInteger id) const -{ - // Locate the requested entry - for (const auto & e : m_Entries) + /* ------------------------------------------------------------------------------------------- + * Copy assignment operator (disabled). + */ + PvClassWrap & operator = (const PvClassWrap & o) = delete; + + /* ------------------------------------------------------------------------------------------- + * Move assignment operator (disabled). + */ + PvClassWrap & operator = (PvClassWrap && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Release all script resources. Recursively forward request. + */ + void Release() { - if (e.first == id) - { - return e.second; - } - } - // No such entry - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -PvEntry * PvManager::GetEntryByTag(StackStrF & name) const -{ - // Retrieve the hash - auto hash = name.HashIt(); - // Locate the requested entry - for (const auto & e : m_Entries) - { - // Does the string hash match? - if (e.second->GetTagW().GetHash() == hash && - // Check if the whole string matches as well - strncmp(name.mPtr, e.second->GetTagW().mPtr, - std::min(name.mLen, e.second->GetTagW().mLen)) == 0) - { - return e.second; // This is what we're looking for - } - } - // No such entry - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -LightObj PvManager::CreateEntry(SQInteger id, StackStrF & name) -{ - // See if this entry exists already - PvEntry * e = GetEntryByID(id); - // Return existing entry if already exists - if (e != nullptr) - { - return LightObj(e); - } - // Create an entry instance - LightObj o(DeleteGuard< PvEntry >(new PvEntry(id, std::move(name), this))); - // Get a pointer to the new instance - e = o.CastI< PvEntry >(); - // Append the new entry - m_Entries.emplace_back(id, e); - // Return the resulted object - return o; -} -// ------------------------------------------------------------------------------------------------ -PvClass *PvManager::GetClassByID(SQInteger id) const -{ - // Locate the requested class - for (const auto & e : m_Classes) - { - if (e.first == id) - { - return e.second; - } } - // No such class - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -PvClass * PvManager::GetClassByTag(StackStrF & name) const +}; + +/* ------------------------------------------------------------------------------------------------ + * Privilege entry wrapper. +*/ +class PvEntryWrap { - // Retrieve the hash - auto hash = name.HashIt(); - // Locate the requested class - for (const auto & e : m_Classes) + friend class PvManager; + +private: + + /* -------------------------------------------------------------------------------------------- + * + */ + PvEntry::Ref mInst; + +public: + + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvEntryWrap(SQInteger id, PvManager * mgr) { - // Does the string hash match? - if (e.second->GetTagW().GetHash() == hash && - // Check if the whole string matches as well - strncmp(name.mPtr, e.second->GetTagW().mPtr, - std::min(name.mLen, e.second->GetTagW().mLen)) == 0) - { - return e.second; // This is what we're looking for - } } - // No such class - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -LightObj PvManager::CreateClass(SQInteger id, StackStrF & name) -{ - // See if this class exists already - PvClass * e = GetClassByID(id); - // Return existing class if already exists - if (e != nullptr) + /* ------------------------------------------------------------------------------------------- + * Default constructor. + */ + PvEntryWrap(SQInteger id, StackStrF && tag, PvManager * mgr) + { - return LightObj(e); } - // Create an class instance - LightObj o(DeleteGuard< PvClass >(new PvClass(id, std::move(name), this))); - // Get a pointer to the new instance - e = o.CastI< PvClass >(); - // Append the new class - m_Classes.emplace_back(id, e); - // Return the resulted object - return o; -} -// ------------------------------------------------------------------------------------------------ -PvUnit * PvManager::GetUnitByID(SQInteger id) const -{ - // Locate the requested unit - for (const auto & e : m_Units) + /* ------------------------------------------------------------------------------------------- + * Copy constructor (disabled). + */ + PvEntryWrap(const PvEntryWrap & o) = delete; + + /* ------------------------------------------------------------------------------------------- + * Move constructor (disabled). + */ + PvEntryWrap(PvEntryWrap && o) = delete; + + /* ------------------------------------------------------------------------------------------- + * Destructor. + */ + ~PvEntryWrap(); + + /* ------------------------------------------------------------------------------------------- + * Copy assignment operator (disabled). + */ + PvEntryWrap & operator = (const PvEntryWrap & o) = delete; + + /* ------------------------------------------------------------------------------------------- + * Move assignment operator (disabled). + */ + PvEntryWrap & operator = (PvEntryWrap && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Release all script resources. Recursively forward request. + */ + void Release() { - if (e.first == id) - { - return e.second; - } + } - // No such unit - return nullptr; -} -// ------------------------------------------------------------------------------------------------ -PvUnit * PvManager::GetUnitByTag(StackStrF & name) const -{ - // Retrieve the hash - auto hash = name.HashIt(); - // Locate the requested unit - for (const auto & e : m_Units) - { - // Does the string hash match? - if (e.second->GetTagW().GetHash() == hash && - // Check if the whole string matches as well - strncmp(name.mPtr, e.second->GetTagW().mPtr, - std::min(name.mLen, e.second->GetTagW().mLen)) == 0) - { - return e.second; // This is what we're looking for - } - } - // No such unit - return nullptr; -} - -// ------------------------------------------------------------------------------------------------ -LightObj PvManager::CreateUnit(SQInteger id, PvClass & cls, StackStrF & name) -{ - // Return the resulted object - return CreateUnitImpl(id, cls, name).second; -} - -// ------------------------------------------------------------------------------------------------ -std::pair< PvUnit *, LightObj > PvManager::CreateUnitImpl(SQInteger id, PvClass & cls, StackStrF & name) -{ - // See if this unit exists already - PvUnit * unit = GetUnitByID(id); - // Return existing unit if already exists - if (unit != nullptr) - { - // Return the existing unit - return std::make_pair(unit, LightObj{unit}); - } - // Create a unit instance - LightObj o{DeleteGuard< PvUnit >(new PvUnit(id, std::move(name), &cls))}; - // Grab the pointer from the object - unit = o.CastI< PvUnit >(); - // Enlist the new unit with this manager - m_Units.emplace_back(id, unit); - // Enlist the new unit on the specified class - cls.EnlistUnit(*unit); - // Return the created unit - return std::make_pair(unit, std::move(o)); -} - -// ------------------------------------------------------------------------------------------------ +}; // ------------------------------------------------------------------------------------------------ void TerminatePrivileges() @@ -331,7 +211,7 @@ void TerminatePrivileges() void Register_Privilege(HSQUIRRELVM vm) { Table pns(vm); - +/* pns.Bind(_SC("Unit"), Class< PvUnit, NoConstructor< PvUnit > >(vm, UnitTn::Str) // Meta-methods @@ -407,8 +287,8 @@ void Register_Privilege(HSQUIRRELVM vm) .CbFunc(_SC("OnGained"), &PvEntry::SetOnGained) // Raw functions ); - - pns.Bind(_SC("Manager"), +*/ +/* pns.Bind(_SC("Manager"), Class< PvManager, NoCopy< PvManager > >(vm, ManagerTn::Str) // Constructors .Ctor() @@ -422,30 +302,12 @@ void Register_Privilege(HSQUIRRELVM vm) // Core Methods .FmtFunc(_SC("SetTag"), &PvManager::ApplyTag) // Member Methods - .Func(_SC("GetEntry"), &PvManager::GetEntryByID) - .Func(_SC("GetEntryByID"), &PvManager::GetEntryByID) - .Func(_SC("HaveEntryWithID"), &PvManager::HaveEntryWithID) - .FmtFunc(_SC("GetEntryByTag"), &PvManager::GetEntryByTag) - .FmtFunc(_SC("HaveEntryWithTag"), &PvManager::HaveEntryWithTag) - .FmtFunc(_SC("CreateEntry"), &PvManager::CreateEntry) - .Func(_SC("GetClass"), &PvManager::GetClassByID) - .Func(_SC("GetClassByID"), &PvManager::GetClassByID) - .Func(_SC("HaveClassWithID"), &PvManager::HaveClassWithID) - .FmtFunc(_SC("GetClassByTag"), &PvManager::GetClassByTag) - .FmtFunc(_SC("HaveClassWithTag"), &PvManager::HaveClassWithTag) - .FmtFunc(_SC("CreateClass"), &PvManager::CreateClass) - .Func(_SC("GetUnit"), &PvManager::GetUnitByID) - .Func(_SC("GetUnitByID"), &PvManager::GetUnitByID) - .Func(_SC("HaveUnitWithID"), &PvManager::HaveUnitWithID) - .FmtFunc(_SC("GetUnitByTag"), &PvManager::GetUnitByTag) - .FmtFunc(_SC("HaveUnitWithTag"), &PvManager::HaveUnitWithTag) - .FmtFunc(_SC("CreateUnit"), &PvManager::CreateUnit) .CbFunc(_SC("OnQuery"), &PvManager::SetOnQuery) .CbFunc(_SC("OnLost"), &PvManager::SetOnLost) .CbFunc(_SC("OnGained"), &PvManager::SetOnGained) // Raw functions ); - +*/ RootTable(vm).Bind(_SC("SqPrivilege"), pns); } diff --git a/module/Misc/Privilege.hpp b/module/Misc/Privilege.hpp index 2f5cbcd3..cf9ecaff 100644 --- a/module/Misc/Privilege.hpp +++ b/module/Misc/Privilege.hpp @@ -23,6 +23,11 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { +// ------------------------------------------------------------------------------------------------ +struct PvUnit; +struct PvClass; +struct PvEntry; + // ------------------------------------------------------------------------------------------------ class PvUnit; class PvClass; @@ -30,17 +35,9 @@ class PvEntry; class PvManager; // ------------------------------------------------------------------------------------------------ -// Type of container used to store privilege entries. -typedef std::vector< std::pair< SQInteger, PvEntry * > > PvEntryList; -// Type of container used to store privilege classes. -typedef std::vector< std::pair< SQInteger, PvClass * > > PvClassList; -// Type of container used to store privilege units. -typedef std::vector< std::pair< SQInteger, PvUnit * > > PvUnitList; - +typedef std::vector< PvManager * > PvManagers; // ------------------------------------------------------------------------------------------------ typedef std::vector< std::pair< SQInteger, SQInteger > > PvStatusList; -// ------------------------------------------------------------------------------------------------ -typedef std::vector< PvManager * > PvManagers; /* ------------------------------------------------------------------------------------------------ * An individual unit/entity that inherits the privileges of a class/group and can @@ -49,83 +46,92 @@ typedef std::vector< PvManager * > PvManagers; * Units cost more to query if they differ from their class but save memory in large numbers. * Each unit must have a unique numerical identifier within their associated manager. */ -class PvUnit +struct PvUnit { - friend class PvManager; - friend class PvClass; + /* -------------------------------------------------------------------------------------------- + * Strong and weak reference types. + */ + typedef SharedPtr< PvUnit > Ref; + typedef WeakPtr< PvUnit > Ptr; -private: + /* -------------------------------------------------------------------------------------------- + * Type of container used to store privilege units. + */ + typedef std::vector< std::pair< SQInteger, Ref > > List; /* -------------------------------------------------------------------------------------------- * User identifier associated with this unit instance. */ - SQInteger m_ID; + SQInteger mID; /* -------------------------------------------------------------------------------------------- * Authority level associated with a particular unit. */ - SQInteger m_Authority; + SQInteger mAuthority; /* -------------------------------------------------------------------------------------------- * A container with unique privilege status values associated with this unit. */ - PvStatusList m_Privileges; + PvStatusList mPrivileges; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege query event. */ - Function m_OnQuery; + Function mOnQuery; + + /* -------------------------------------------------------------------------------------------- + * Dedicated callback for privilege modify event. + */ + Function mOnModify; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege gained event. */ - Function m_OnGained; + Function mOnGained; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege lost event. */ - Function m_OnLost; + Function mOnLost; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - StackStrF m_Tag; + StackStrF mTag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - LightObj m_Data; + LightObj mData; /* -------------------------------------------------------------------------------------------- * Pointer to the associated class. */ - PvClass * m_Class; - -public: + WeakPtr< PvClass > mClass; /* ------------------------------------------------------------------------------------------- * Default constructor. */ - PvUnit(SQInteger id, PvClass * cls) - : m_ID(id) - , m_Authority(0) - , m_Privileges() - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Tag(), m_Data() - , m_Class(cls) + PvUnit(SQInteger id, WeakPtr< PvClass > cls) + : mID(id) + , mAuthority(0) + , mPrivileges() + , mOnQuery(), mOnGained(), mOnLost() + , mTag(), mData() + , mClass(std::move(cls)) { } /* ------------------------------------------------------------------------------------------- * Default constructor. */ - PvUnit(SQInteger id, StackStrF && tag, PvClass * cls) - : m_ID(id) - , m_Authority(0) - , m_Privileges() - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Tag(std::forward< StackStrF >(tag)), m_Data() - , m_Class(cls) + PvUnit(SQInteger id, StackStrF && tag, WeakPtr< PvClass > cls) + : mID(id) + , mAuthority(0) + , mPrivileges() + , mOnQuery(), mOnGained(), mOnLost() + , mTag(std::forward< StackStrF >(tag)), mData() + , mClass(std::move(cls)) { } @@ -137,9 +143,7 @@ public: /* ------------------------------------------------------------------------------------------- * Destructor. */ - ~PvUnit() - { - } + ~PvUnit(); /* ------------------------------------------------------------------------------------------- * Copy assignment operator (disabled). @@ -149,177 +153,23 @@ public: /* ------------------------------------------------------------------------------------------- * Comparison operators. Uses the identifier internally as that is guaranteed to be unique. */ - bool operator == (const PvUnit & o) const { return m_ID == o.m_ID; } - bool operator != (const PvUnit & o) const { return m_ID != o.m_ID; } - bool operator < (const PvUnit & o) const { return m_ID < o.m_ID; } - bool operator > (const PvUnit & o) const { return m_ID > o.m_ID; } - bool operator <= (const PvUnit & o) const { return m_ID <= o.m_ID; } - bool operator >= (const PvUnit & o) const { return m_ID >= o.m_ID; } + bool operator == (const PvUnit & o) const { return mID == o.mID; } + bool operator != (const PvUnit & o) const { return mID != o.mID; } + bool operator < (const PvUnit & o) const { return mID < o.mID; } + bool operator > (const PvUnit & o) const { return mID > o.mID; } + bool operator <= (const PvUnit & o) const { return mID <= o.mID; } + bool operator >= (const PvUnit & o) const { return mID >= o.mID; } /* -------------------------------------------------------------------------------------------- * Release all script resources. Recursively forward request. */ void Release() { - m_OnQuery.Release(); - m_OnGained.Release(); - m_OnLost.Release(); - m_Tag.Release(); - m_Data.Release(); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier associated with this unit. - */ - SQInteger GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - auto ToString() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag wrapper. - */ - const StackStrF & GetTagW() const - { - return m_Tag; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - auto GetTag() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(StackStrF & tag) - { - m_Tag = std::move(tag); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - PvUnit & ApplyTag(StackStrF & tag) - { - SetTag(tag); - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - LightObj & GetData() - { - return m_Data; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(LightObj & data) - { - m_Data = data; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the authority level associated with this unit. - */ - SQInteger GetAuthority() const - { - return m_Authority; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the authority level associated with this unit. - */ - void SetAuthority(SQInteger level) - { - m_Authority = level; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the manager associated with this unit. - */ - PvManager & GetManager() const; - - /* -------------------------------------------------------------------------------------------- - * Retrieve the class associated with this unit. - */ - PvClass & GetClass() const; - - /* -------------------------------------------------------------------------------------------- - * Modify the class associated with this unit. - */ - void SetClass(PvClass & cls); - - /* -------------------------------------------------------------------------------------------- - * Query if a unit has a certain privilege over itself. - */ - bool Can(const PvEntry & entry) const; - - /* -------------------------------------------------------------------------------------------- - * Query if a unit has a certain privilege over another unit. - */ - bool Can(const PvEntry & entry, const PvUnit & unit) const; - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status query callback. - */ - void SetOnQuery(Function & func) - { - m_OnQuery = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status query callback. - */ - Function & GetOnQuery() - { - return m_OnQuery; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status lost callback. - */ - void SetOnLost(Function & func) - { - m_OnLost = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status lost callback. - */ - Function & GetOnLost() - { - return m_OnLost; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status gained callback. - */ - void SetOnGained(Function & func) - { - m_OnGained = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status gained callback. - */ - Function & GetOnGained() - { - return m_OnGained; + mOnQuery.Release(); + mOnGained.Release(); + mOnLost.Release(); + mTag.Release(); + mData.Release(); } }; @@ -330,75 +180,85 @@ public: * These cost less to query but use more memory because they're fewer and they preallocate it. * Each class must have a unique numerical identifier within their associated manager. */ -class PvClass +struct PvClass { - friend class PvManager; + /* -------------------------------------------------------------------------------------------- + * Strong and weak reference types. + */ + typedef SharedPtr< PvClass > Ref; + typedef WeakPtr< PvClass > Ptr; -private: + /* -------------------------------------------------------------------------------------------- + * Type of container used to store privilege classes. + */ + typedef std::vector< std::pair< SQInteger, Ref > > List; /* -------------------------------------------------------------------------------------------- * User identifier associated with this class instance. */ - SQInteger m_ID; + SQInteger mID; /* -------------------------------------------------------------------------------------------- * The parent class from which we are inheriting privileges, if any. */ - PvClass * m_Parent; + PvClass * mParent; /* -------------------------------------------------------------------------------------------- * A container with unique privilege status values associated with this class. */ - PvStatusList m_Privileges; + PvStatusList mPrivileges; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege query event. */ - Function m_OnQuery; + Function mOnQuery; + + /* -------------------------------------------------------------------------------------------- + * Dedicated callback for privilege modify event. + */ + Function mOnModify; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege gained event. */ - Function m_OnGained; + Function mOnGained; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege lost event. */ - Function m_OnLost; + Function mOnLost; /* -------------------------------------------------------------------------------------------- * Container that stores all the associated units. */ - PvUnitList m_Units; + PvUnit::List mUnits; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - StackStrF m_Tag; + StackStrF mTag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - LightObj m_Data; + LightObj mData; /* -------------------------------------------------------------------------------------------- * Pointer to the associated manager. */ - PvManager * m_Manager; - -public: + PvManager * mManager; /* ------------------------------------------------------------------------------------------- * Default constructor. */ PvClass(SQInteger id, PvManager * mgr) - : m_ID(id) - , m_Parent(nullptr) - , m_Privileges() - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Units() - , m_Tag(), m_Data() - , m_Manager(mgr) + : mID(id) + , mParent(nullptr) + , mPrivileges() + , mOnQuery(), mOnGained(), mOnLost() + , mUnits() + , mTag(), mData() + , mManager(mgr) { } @@ -406,13 +266,13 @@ public: * Default constructor. */ PvClass(SQInteger id, StackStrF && tag, PvManager * mgr) - : m_ID(id) - , m_Parent(nullptr) - , m_Privileges() - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Units() - , m_Tag(std::forward< StackStrF >(tag)), m_Data() - , m_Manager(mgr) + : mID(id) + , mParent(nullptr) + , mPrivileges() + , mOnQuery(), mOnGained(), mOnLost() + , mUnits() + , mTag(std::forward< StackStrF >(tag)), mData() + , mManager(mgr) { } @@ -429,9 +289,7 @@ public: /* ------------------------------------------------------------------------------------------- * Destructor. */ - ~PvClass() - { - } + ~PvClass(); /* ------------------------------------------------------------------------------------------- * Copy assignment operator (disabled). @@ -446,279 +304,102 @@ public: /* ------------------------------------------------------------------------------------------- * Comparison operators. Uses the identifier internally as that is guaranteed to be unique. */ - bool operator == (const PvClass & o) const { return m_ID == o.m_ID; } - bool operator != (const PvClass & o) const { return m_ID != o.m_ID; } - bool operator < (const PvClass & o) const { return m_ID < o.m_ID; } - bool operator > (const PvClass & o) const { return m_ID > o.m_ID; } - bool operator <= (const PvClass & o) const { return m_ID <= o.m_ID; } - bool operator >= (const PvClass & o) const { return m_ID >= o.m_ID; } + bool operator == (const PvClass & o) const { return mID == o.mID; } + bool operator != (const PvClass & o) const { return mID != o.mID; } + bool operator < (const PvClass & o) const { return mID < o.mID; } + bool operator > (const PvClass & o) const { return mID > o.mID; } + bool operator <= (const PvClass & o) const { return mID <= o.mID; } + bool operator >= (const PvClass & o) const { return mID >= o.mID; } /* -------------------------------------------------------------------------------------------- * Release all script resources. Recursively forward request. */ void Release() { - m_OnQuery.Release(); - m_OnGained.Release(); - m_OnLost.Release(); - m_Tag.Release(); - m_Data.Release(); + mOnQuery.Release(); + mOnGained.Release(); + mOnLost.Release(); + mTag.Release(); + mData.Release(); } - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier associated with this manager. - */ - SQInteger GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - auto ToString() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag wrapper. - */ - const StackStrF & GetTagW() const - { - return m_Tag; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - auto GetTag() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(StackStrF & tag) - { - m_Tag = std::move(tag); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - PvClass & ApplyTag(StackStrF & tag) - { - SetTag(tag); - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - LightObj & GetData() - { - return m_Data; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(LightObj & data) - { - m_Data = data; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the manager associated with this unit. - */ - LightObj GetParent() const - { - return m_Parent ? LightObj(m_Parent) : LightObj{}; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the manager associated with this unit. - */ - void SetParent(LightObj & obj) - { - m_Parent = obj.IsNull() ? nullptr : obj.Cast< PvClass * >(); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the manager associated with this unit. - */ - PvManager & GetManager() const - { - return *m_Manager; // Classes must always have a manager! - } - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the unit associated with the given identifier. - */ - PvUnit * GetUnitByID(SQInteger id) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an unit associated with the given identifier. - */ - bool HaveUnitWithID(SQInteger id) const - { - return GetUnitByID(id) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the unit associated with the given name tag. - */ - PvUnit * GetUnitByTag(StackStrF & name) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an unit associated with the given name tag. - */ - bool HaveUnitWithTag(StackStrF & name) const - { - return GetUnitByTag(name) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Create a new privilege unit instance and manage it. - */ - LightObj CreateUnit(SQInteger id, StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Add a unit to this privilege class. - */ - void AddUnit(PvUnit & unit); - - /* -------------------------------------------------------------------------------------------- - * Add a unit to this class container (internal, assumes validation beforehand!). - */ - bool EnlistUnit(PvUnit & unit); - - /* -------------------------------------------------------------------------------------------- - * Remove a unit from this class container (internal, assumes validation beforehand!). - */ - bool UnlistUnit(PvUnit & unit); - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status query callback. - */ - void SetOnQuery(Function & func) - { - m_OnQuery = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status query callback. - */ - Function & GetOnQuery() - { - return m_OnQuery; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status lost callback. - */ - void SetOnLost(Function & func) - { - m_OnLost = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status lost callback. - */ - Function & GetOnLost() - { - return m_OnLost; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status gained callback. - */ - void SetOnGained(Function & func) - { - m_OnGained = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status gained callback. - */ - Function & GetOnGained() - { - return m_OnGained; - } }; /* ------------------------------------------------------------------------------------------------ * An entry represents a privilege that a class or unit can can have. * Each entry must have a unique numerical identifier within their associated manager. */ -class PvEntry +struct PvEntry { - friend class PvManager; + /* -------------------------------------------------------------------------------------------- + * Strong and weak reference types. + */ + typedef SharedPtr< PvEntry > Ref; + typedef WeakPtr< PvEntry > Ptr; -private: + /* -------------------------------------------------------------------------------------------- + * Type of container used to store privilege entries. + */ + typedef std::vector< std::pair< SQInteger, Ref > > List; /* -------------------------------------------------------------------------------------------- * User identifier associated with this instance. */ - SQInteger m_ID; + SQInteger mID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - StackStrF m_Tag; + StackStrF mTag; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege query event. */ - Function m_OnQuery; + Function mOnQuery; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege gained event. */ - Function m_OnGained; + Function mOnGained; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege lost event. */ - Function m_OnLost; + Function mOnLost; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - LightObj m_Data; + LightObj mData; /* -------------------------------------------------------------------------------------------- * Brief information about the privilege. */ - StackStrF m_Brief; + StackStrF mBrief; /* -------------------------------------------------------------------------------------------- * Detailed information about the privilege. */ - StackStrF m_Info; + StackStrF mInfo; /* -------------------------------------------------------------------------------------------- * Implicit privilege status value. */ - SQInteger m_Default; + SQInteger mDefault; /* -------------------------------------------------------------------------------------------- * Pointer to the associated manager. */ - PvManager * m_Manager; - -public: + PvManager * mManager; /* ------------------------------------------------------------------------------------------- * Default constructor. */ PvEntry(SQInteger id, PvManager * mgr) - : m_ID(id), m_Tag() - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Data(), m_Brief(), m_Info(), m_Default() - , m_Manager(mgr) + : mID(id), mTag() + , mOnQuery(), mOnGained(), mOnLost() + , mData(), mBrief(), mInfo(), mDefault() + , mManager(mgr) { } @@ -726,10 +407,10 @@ public: * Default constructor. */ PvEntry(SQInteger id, StackStrF && tag, PvManager * mgr) - : m_ID(id), m_Tag(std::forward< StackStrF >(tag)) - , m_OnQuery(), m_OnGained(), m_OnLost() - , m_Data(), m_Brief(), m_Info(), m_Default() - , m_Manager(mgr) + : mID(id), mTag(std::forward< StackStrF >(tag)) + , mOnQuery(), mOnGained(), mOnLost() + , mData(), mBrief(), mInfo(), mDefault() + , mManager(mgr) { } @@ -747,9 +428,7 @@ public: /* ------------------------------------------------------------------------------------------- * Destructor. */ - ~PvEntry() - { - } + ~PvEntry(); /* ------------------------------------------------------------------------------------------- * Copy assignment operator (disabled). @@ -764,213 +443,27 @@ public: /* ------------------------------------------------------------------------------------------- * Comparison operators. Uses the identifier internally as that is guaranteed to be unique. */ - bool operator == (const PvEntry & o) const { return m_ID == o.m_ID; } - bool operator != (const PvEntry & o) const { return m_ID != o.m_ID; } - bool operator < (const PvEntry & o) const { return m_ID < o.m_ID; } - bool operator > (const PvEntry & o) const { return m_ID > o.m_ID; } - bool operator <= (const PvEntry & o) const { return m_ID <= o.m_ID; } - bool operator >= (const PvEntry & o) const { return m_ID >= o.m_ID; } + bool operator == (const PvEntry & o) const { return mID == o.mID; } + bool operator != (const PvEntry & o) const { return mID != o.mID; } + bool operator < (const PvEntry & o) const { return mID < o.mID; } + bool operator > (const PvEntry & o) const { return mID > o.mID; } + bool operator <= (const PvEntry & o) const { return mID <= o.mID; } + bool operator >= (const PvEntry & o) const { return mID >= o.mID; } /* -------------------------------------------------------------------------------------------- * Release all script resources. Recursively forward request. */ void Release() { - m_Tag.Release(); - m_OnQuery.Release(); - m_OnGained.Release(); - m_OnLost.Release(); - m_Data.Release(); - m_Brief.Release(); - m_Info.Release(); + mTag.Release(); + mOnQuery.Release(); + mOnGained.Release(); + mOnLost.Release(); + mData.Release(); + mBrief.Release(); + mInfo.Release(); } - /* -------------------------------------------------------------------------------------------- - * Retrieve the manager associated with this unit. - */ - PvManager & GetManager() const - { - return *m_Manager; // Entries must always have a manager! - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the identifier associated with this manager. - */ - SQInteger GetID() const - { - return m_ID; - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - auto ToString() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag wrapper. - */ - const StackStrF & GetTagW() const - { - return m_Tag; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user tag. - */ - auto GetTag() const - { - return m_Tag.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - void SetTag(StackStrF & tag) - { - m_Tag = std::move(tag); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user tag. - */ - PvEntry & ApplyTag(StackStrF & tag) - { - SetTag(tag); - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - LightObj & GetData() - { - return m_Data; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(LightObj & data) - { - m_Data = data; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user brief. - */ - auto GetBrief() const - { - return m_Brief.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user brief. - */ - void SetBrief(StackStrF & brief) - { - m_Brief = std::move(brief); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user brief. - */ - PvEntry & ApplyBrief(StackStrF & brief) - { - SetBrief(brief); - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user info. - */ - auto GetInfo() const - { - return m_Info.mObj; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user info. - */ - void SetInfo(StackStrF & info) - { - m_Info = std::move(info); - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user info. - */ - PvEntry & ApplyInfo(StackStrF & info) - { - SetInfo(info); - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the implicit status value of this entry. - */ - SQInteger GetDefault() const - { - return m_Default; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the implicit status value of this entry. - */ - void SetDefault(SQInteger status) - { - m_Default = status; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status query callback. - */ - void SetOnQuery(Function & func) - { - m_OnQuery = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status query callback. - */ - Function & GetOnQuery() - { - return m_OnQuery; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status lost callback. - */ - void SetOnLost(Function & func) - { - m_OnLost = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status lost callback. - */ - Function & GetOnLost() - { - return m_OnLost; - } - - /* -------------------------------------------------------------------------------------------- - * Bind a script function to the status gained callback. - */ - void SetOnGained(Function & func) - { - m_OnGained = std::move(func); - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the function bound to the status gained callback. - */ - Function & GetOnGained() - { - return m_OnGained; - } }; /* ------------------------------------------------------------------------------------------------ @@ -983,42 +476,42 @@ private: /* -------------------------------------------------------------------------------------------- * Container that stores privilege entries. */ - PvEntryList m_Entries; + PvEntry::List m_Entries; /* -------------------------------------------------------------------------------------------- * Container that stores the managed classes. */ - PvClassList m_Classes; + PvClass::List m_Classes; /* -------------------------------------------------------------------------------------------- * Container that stores all the managed units. */ - PvUnitList m_Units; + PvUnit::List m_Units; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege query event. */ - Function m_OnQuery; + Function m_OnQuery; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege gained event. */ - Function m_OnGained; + Function m_OnGained; /* -------------------------------------------------------------------------------------------- * Dedicated callback for privilege lost event. */ - Function m_OnLost; + Function m_OnLost; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - StackStrF m_Tag; + StackStrF m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - LightObj m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * List of active privilege managers. @@ -1134,104 +627,6 @@ public: m_Data = data; } - /* -------------------------------------------------------------------------------------------- - * Find the instance of the entry associated with the given identifier. - */ - PvEntry * GetEntryByID(SQInteger id) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an entry associated with the given identifier. - */ - bool HaveEntryWithID(SQInteger id) const - { - return GetEntryByID(id) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the entry associated with the given name tag. - */ - PvEntry * GetEntryByTag(StackStrF & name) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an entry associated with the given name tag. - */ - bool HaveEntryWithTag(StackStrF & name) const - { - return GetEntryByTag(name) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Create a new privilege entry instance and manage it. - */ - LightObj CreateEntry(SQInteger id, StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the class associated with the given identifier. - */ - PvClass * GetClassByID(SQInteger id) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an class associated with the given identifier. - */ - bool HaveClassWithID(SQInteger id) const - { - return GetClassByID(id) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the class associated with the given name tag. - */ - PvClass * GetClassByTag(StackStrF & name) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an class associated with the given name tag. - */ - bool HaveClassWithTag(StackStrF & name) const - { - return GetClassByTag(name) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Create a new privilege class instance and manage it. - */ - LightObj CreateClass(SQInteger id, StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the unit associated with the given identifier. - */ - PvUnit * GetUnitByID(SQInteger id) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an unit associated with the given identifier. - */ - bool HaveUnitWithID(SQInteger id) const - { - return GetUnitByID(id) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Find the instance of the unit associated with the given name tag. - */ - PvUnit * GetUnitByTag(StackStrF & name) const; - - /* -------------------------------------------------------------------------------------------- - * Check for existence of an unit associated with the given name tag. - */ - bool HaveUnitWithTag(StackStrF & name) const - { - return GetUnitByTag(name) != nullptr; - } - - /* -------------------------------------------------------------------------------------------- - * Create a new privilege unit instance and manage it. - */ - LightObj CreateUnit(SQInteger id, PvClass & cls, StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Create a new privilege unit instance and manage it. - */ - std::pair< PvUnit *, LightObj > CreateUnitImpl(SQInteger id, PvClass & cls, StackStrF & name); - /* -------------------------------------------------------------------------------------------- * Bind a script function to the status query callback. */ @@ -1285,21 +680,6 @@ public: */ void Release() { - // Release objects from entries - for (auto & pve : m_Entries) - { - pve.second->Release(); - } - // Release objects from classes - for (auto & pvc : m_Classes) - { - pvc.second->Release(); - } - // Release objects from units - for (auto & pvu : m_Units) - { - pvu.second->Release(); - } // Release objects from this instance m_OnQuery.Release(); m_OnGained.Release();