mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 16:57:16 +01:00
377 lines
17 KiB
C++
377 lines
17 KiB
C++
#pragma once
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#include "Core/Privilege/Unit.hpp"
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
namespace SqMod {
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* An individual class/group that can optionally inherit the privileges of another and can
|
|
* change their status to affect their children but not their parent class.
|
|
* A class can extend it's privileges to units and/or other classes.
|
|
* 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.
|
|
*/
|
|
struct PvClass
|
|
{
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Strong and weak reference types.
|
|
*/
|
|
typedef std::shared_ptr< PvClass > Ref;
|
|
typedef std::weak_ptr< PvClass > Ptr;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Type of container used to store privilege classes.
|
|
*/
|
|
typedef VecMap< PvIdentity, Ref, PvIdPred > List;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* User identifier associated with this class instance. Always unique in the same manager!
|
|
*/
|
|
const SQInteger mID;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The parent class from which we are inheriting privileges, if any.
|
|
*/
|
|
Ptr mParent;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* A container with unique privilege status values associated with this class.
|
|
*/
|
|
PvStatusList mPrivileges;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Dedicated callback for privilege query event.
|
|
*/
|
|
Function mOnQuery;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Dedicated callback for privilege gained event.
|
|
*/
|
|
Function mOnGained;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Dedicated callback for privilege lost event.
|
|
*/
|
|
Function mOnLost;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Container that stores all the associated units.
|
|
*/
|
|
PvUnit::List mUnits;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* User tag associated with this instance.
|
|
*/
|
|
StackStrF mTag;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* User data associated with this instance.
|
|
*/
|
|
LightObj mData;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Pointer to the associated manager. Should always be present.
|
|
*
|
|
*/
|
|
PvManager * mManager;
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Default constructor.
|
|
*/
|
|
PvClass(SQInteger id, PvManager * mgr)
|
|
: mID(id)
|
|
, mParent()
|
|
, mPrivileges()
|
|
, mOnQuery(), mOnGained(), mOnLost()
|
|
, mUnits()
|
|
, mTag(), mData()
|
|
, mManager(mgr)
|
|
{
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Default constructor.
|
|
*/
|
|
PvClass(SQInteger id, StackStrF && tag, PvManager * mgr)
|
|
: mID(id)
|
|
, mParent()
|
|
, mPrivileges()
|
|
, mOnQuery(), mOnGained(), mOnLost()
|
|
, mUnits()
|
|
, mTag(std::move(tag)), mData()
|
|
, mManager(mgr)
|
|
{
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Copy constructor (disabled).
|
|
*/
|
|
PvClass(const PvClass & o) = delete;
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Move constructor (disabled).
|
|
*/
|
|
PvClass(PvClass && o) = delete;
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Destructor.
|
|
*/
|
|
~PvClass() = default;
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Copy assignment operator (disabled).
|
|
*/
|
|
PvClass & operator = (const PvClass & o) = delete;
|
|
|
|
/* -------------------------------------------------------------------------------------------
|
|
* Move assignment operator (disabled).
|
|
*/
|
|
PvClass & operator = (PvClass && o) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Update the hash of the specified unit.
|
|
*/
|
|
void UpdateUnitHash(SQInteger id, size_t hash)
|
|
{
|
|
auto itr = mUnits.find(PvIdentity(id));
|
|
// Only update if it exists
|
|
if (itr != mUnits.end())
|
|
{
|
|
itr->first.mHash = hash;
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Modify the associated user tag.
|
|
*/
|
|
void SetTag(StackStrF & tag);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Release all script resources. Recursively forward request.
|
|
*/
|
|
void Release();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Make sure the referenced parent class is valid.
|
|
*/
|
|
void ValidateParent() const
|
|
{
|
|
if (mParent.expired())
|
|
{
|
|
STHROWF("Class ({} : {}) has invalid parent class reference", mID, mTag.mPtr);
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Make sure the referenced parent class is valid and return a reference to it.
|
|
*/
|
|
SQMOD_NODISCARD PvClass & ValidParent() const
|
|
{
|
|
ValidateParent();
|
|
// Acquire a reference and return it
|
|
return *(mParent.lock().get());
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Make sure the referenced manager is valid.
|
|
*/
|
|
void ValidateManager() const
|
|
{
|
|
if (!mManager)
|
|
{
|
|
STHROWF("Class ({} : {}) has invalid manager reference", mID, mTag.mPtr);
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Make sure the referenced manger is valid and return a reference to it.
|
|
*/
|
|
SQMOD_NODISCARD PvManager & ValidManager() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Find out the callback that must be invoked to handle query events for a certain entry.
|
|
*/
|
|
SQMOD_NODISCARD const Function & GetOnQuery(SQInteger id) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Find out the callback that must be invoked to handle gained events for a certain entry.
|
|
*/
|
|
SQMOD_NODISCARD const Function & GetOnGained(SQInteger id) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Find out the callback that must be invoked to handle lost events for a certain entry.
|
|
*/
|
|
SQMOD_NODISCARD const Function & GetOnLost(SQInteger id) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the current value of an entry for this particular class.
|
|
*/
|
|
SQMOD_NODISCARD SQInteger GetEntryValue(SQInteger id) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the inherited value of an entry for this particular class.
|
|
*/
|
|
SQMOD_NODISCARD SQInteger GetInheritedEntryValue(SQInteger id) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Perform the actions necessary to handle a privilege gain event.
|
|
*/
|
|
void DoGained(SQInteger id, SQInteger value) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Perform the actions necessary to handle a privilege lost event.
|
|
*/
|
|
void DoLost(SQInteger id, SQInteger value) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Perform the actions necessary to handle a privilege change event.
|
|
*/
|
|
void DoChanged(SQInteger id, bool status, SQInteger value) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Assign a status value. Does not care if a parent (class or global) has the same status.
|
|
* Later if the parent changes this status, we will keep having this status value.
|
|
*/
|
|
void AssignPrivilege(SQInteger id, SQInteger value);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Remove a status value. If the specified status value is not assigned, nothing happens.
|
|
*/
|
|
void RemovePrivilege(SQInteger id);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Assign a status value. If a parent (class or global) has the same value, nothing changes.
|
|
* Same as AssignStatus but the status will not be enforced if we have it (inherited or not).
|
|
*/
|
|
void ModifyPrivilege(SQInteger id, SQInteger value);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See AssignPrivilege().
|
|
*/
|
|
void AssignPrivilege(StackStrF & tag, SQInteger value);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See RemovePrivilege().
|
|
*/
|
|
void RemovePrivilege(StackStrF & tag);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See ModifyPrivilege().
|
|
*/
|
|
void ModifyPrivilege(StackStrF & tag, SQInteger value);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Remove all status values. Basically it reverts to the parent class privileges.
|
|
*/
|
|
void RemoveAllPrivileges();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the parent class.
|
|
*/
|
|
void AssignParent(const Ref & parent);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Check if this class has a certain privilege.
|
|
*/
|
|
SQMOD_NODISCARD bool Can(SQInteger id, SQInteger req) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See if a unit with a certain identifier inherits this class.
|
|
*/
|
|
SQMOD_NODISCARD LightObj GetUnitWithID(SQInteger id);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See if a unit with a certain tag inherits this class.
|
|
*/
|
|
SQMOD_NODISCARD LightObj GetUnitWithTag(StackStrF & tag);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See if a unit with a certain identifier inherits this class.
|
|
*/
|
|
bool HaveUnitWithID(SQInteger id);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* 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) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Invoke a given callback with every parented unit identifier.
|
|
*/
|
|
void EachUnitID(Object & ctx, Function & func) const;
|
|
};
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* Privilege class wrapper. Mostly calls functions of the actual implementation.
|
|
* Used to avoid having to involve hard script references that can persist.
|
|
* Breaks away from usual formatting.
|
|
*/
|
|
struct SqPvClass
|
|
{
|
|
PvClass::Ptr mI;
|
|
// --------------------------------------------------------------------------------------------
|
|
explicit SqPvClass(PvClass::Ptr i) : mI(std::move(i)) { } // NOLINT(modernize-pass-by-value)
|
|
explicit SqPvClass(const PvClass::Ref & i) : mI(i) { }
|
|
SqPvClass(const SqPvClass & o) = default;
|
|
SqPvClass(SqPvClass && o) noexcept = default;
|
|
~SqPvClass() = default;
|
|
SqPvClass & operator = (const SqPvClass & o) = default;
|
|
SqPvClass & operator = (SqPvClass && o) noexcept = default;
|
|
// --------------------------------------------------------------------------------------------
|
|
void Validate() const { if (mI.expired()) STHROWF("Invalid unit reference"); }
|
|
SQMOD_NODISCARD PvClass & Valid() const { Validate(); return *(mI.lock().get()); }
|
|
// --------------------------------------------------------------------------------------------
|
|
SQMOD_NODISCARD SQInteger GetID() const { return Valid().mID; }
|
|
// --------------------------------------------------------------------------------------------
|
|
SQMOD_NODISCARD auto ToString() const { return Valid().mTag.mObj; }
|
|
SQMOD_NODISCARD auto GetTag() const { return Valid().mTag.mObj; }
|
|
void SetTag(StackStrF & tag) const { Valid().SetTag(tag); }
|
|
SQMOD_NODISCARD SqPvClass & ApplyTag(StackStrF & tag) { SetTag(tag); return *this; }
|
|
SQMOD_NODISCARD LightObj & GetData() const { return Valid().mData; }
|
|
void SetData(LightObj & data) const { Valid().mData = data; }
|
|
// --------------------------------------------------------------------------------------------
|
|
void SetOnQuery(Function & func) const { Valid().mOnQuery = std::move(func); }
|
|
void SetOnLost(Function & func) const { Valid().mOnLost = std::move(func); }
|
|
void SetOnGained(Function & func) const { Valid().mOnGained = std::move(func); }
|
|
// --------------------------------------------------------------------------------------------
|
|
SQMOD_NODISCARD LightObj GetManager() const { return LightObj(Valid().mManager); }
|
|
// --------------------------------------------------------------------------------------------
|
|
SQMOD_NODISCARD LightObj GetParent() const
|
|
{
|
|
return LightObj(SqTypeIdentity< SqPvClass >{}, SqVM(), Valid().mParent);
|
|
}
|
|
void SetParent(const SqPvClass & cls) const
|
|
{
|
|
Validate();
|
|
cls.Validate();
|
|
mI.lock()->AssignParent(cls.mI.lock());
|
|
}
|
|
// --------------------------------------------------------------------------------------------
|
|
bool Can(LightObj & obj, SQInteger req) const;
|
|
// --------------------------------------------------------------------------------------------
|
|
void AssignPrivilegeWithID(SQInteger id, SQInteger value) const { Valid().AssignPrivilege(id, value); }
|
|
void AssignPrivilegeWithTag(StackStrF & tag, SQInteger value) const { Valid().AssignPrivilege(tag, value); }
|
|
void RemovePrivilegeWithID(SQInteger id) const { Valid().RemovePrivilege(id); }
|
|
void RemovePrivilegeWithTag(StackStrF & tag) const { Valid().RemovePrivilege(tag); }
|
|
void ModifyPrivilegeWithID(SQInteger id, SQInteger value) const { Valid().ModifyPrivilege(id, value); }
|
|
void ModifyPrivilegeWithTag(StackStrF & tag, SQInteger value) const { Valid().ModifyPrivilege(tag, value); }
|
|
void RemoveAllPrivileges() const { Valid().RemoveAllPrivileges(); }
|
|
// --------------------------------------------------------------------------------------------
|
|
SQMOD_NODISCARD LightObj GetUnitWithID(SQInteger id) const { return Valid().GetUnitWithID(id); }
|
|
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) const { return Valid().EachEntryID(ctx, func); }
|
|
void EachUnitID(Object & ctx, Function & func) const { return Valid().EachUnitID(ctx, func); }
|
|
};
|
|
|
|
} // Namespace:: SqMod
|