1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Disabled copy constructor and assignment in the global event type.

Added a compatibility member function in global event type to comply with the other event types.
Encapsulate constructors in global filters and disable them in script.
Disable the copy constructor in global filters.
Allow inclusion/exclusion member functions return boolean if the specified entity could be filtered or not.
Remove useless checks inside global filters since they cannot be unparented anymore.
Test whether an entity is enabled before hooking, unhooking from it inside global filters.
This commit is contained in:
Sandu Liviu Catalin 2015-10-11 21:06:02 +03:00
parent 0a8cf6afd2
commit c7e776a1f7
2 changed files with 351 additions and 453 deletions

View File

@ -53,38 +53,6 @@ GlobalEvent::GlobalEvent(SQInt32 type, bool suspended) noexcept
/* Entity filters are empty so there's nothing to hook to! */
}
// ------------------------------------------------------------------------------------------------
GlobalEvent::GlobalEvent(const GlobalEvent & o) noexcept
: m_Type(o.m_Type)
, m_Stride(o.m_Stride)
, m_Ignore(o.m_Ignore)
, m_Primary(o.m_Primary)
, m_Secondary(o.m_Secondary)
, m_Idle(o.m_Idle)
, m_OnTrigger(o.m_OnTrigger)
, m_OnInclude(o.m_OnInclude)
, m_OnExclude(o.m_OnExclude)
, m_OnCleared(o.m_OnCleared)
, m_OnRelease(o.m_OnRelease)
, m_Tag(o.m_Tag)
, m_Data(o.m_Data)
, m_Confined(o.m_Confined)
, m_Suspended(o.m_Suspended)
, m_Blips(o.m_Blips)
, m_Checkpoints(o.m_Checkpoints)
, m_Keybinds(o.m_Keybinds)
, m_Objects(o.m_Objects)
, m_Pickups(o.m_Pickups)
, m_Players(o.m_Players)
, m_Spheres(o.m_Spheres)
, m_Sprites(o.m_Sprites)
, m_Textdraws(o.m_Textdraws)
, m_Vehicles(o.m_Vehicles)
{
/* The filter copy constructor should already take care of hooking to the copied entities! */
}
// ------------------------------------------------------------------------------------------------
GlobalEvent::~GlobalEvent()
{
@ -93,46 +61,6 @@ GlobalEvent::~GlobalEvent()
/* We're expecting the entity filters to unhook themselves from the destroy signal! */
}
// ------------------------------------------------------------------------------------------------
GlobalEvent & GlobalEvent::operator = (const GlobalEvent & o) noexcept
{
// Make sure we're not doing self assignment
if (this != &o)
{
// Clear anything that cannot adapt to the new event type
Adaptable(o.m_Type);
// Now it's safe to copy the values from the other event instance
m_Type = o.m_Type;
m_Stride = o.m_Stride;
m_Ignore = o.m_Ignore;
m_Primary = o.m_Primary;
m_Secondary = o.m_Secondary;
m_Idle = o.m_Idle;
m_OnTrigger = o.m_OnTrigger;
m_OnInclude = o.m_OnInclude;
m_OnExclude = o.m_OnExclude;
m_OnCleared = o.m_OnCleared;
m_OnRelease = o.m_OnRelease;
m_Tag = o.m_Tag;
m_Data = o.m_Data;
m_Confined = o.m_Confined;
m_Suspended = o.m_Suspended;
m_Blips = o.m_Blips;
m_Checkpoints = o.m_Checkpoints;
m_Keybinds = o.m_Keybinds;
m_Objects = o.m_Objects;
m_Pickups = o.m_Pickups;
m_Players = o.m_Players;
m_Spheres = o.m_Spheres;
m_Sprites = o.m_Sprites;
m_Textdraws = o.m_Textdraws;
m_Vehicles = o.m_Vehicles;
/* The filter copy assignment should already take care of hooking to the copied entities! */
}
return *this;
}
// ------------------------------------------------------------------------------------------------
bool GlobalEvent::operator == (const GlobalEvent & o) const noexcept
{
@ -379,6 +307,101 @@ void GlobalEvent::SetOnRelease(const Function & func) noexcept
m_OnRelease = func;
}
// ------------------------------------------------------------------------------------------------
bool GlobalEvent::Compatible(SQInt32 type) const noexcept
{
switch (type)
{
case EVT_BLIPDESTROYED:
case EVT_CHECKPOINTDESTROYED:
case EVT_KEYBINDDESTROYED:
case EVT_OBJECTDESTROYED:
case EVT_PICKUPDESTROYED:
case EVT_PLAYERDESTROYED:
case EVT_SPHEREDESTROYED:
case EVT_SPRITEDESTROYED:
case EVT_TEXTDRAWDESTROYED:
case EVT_VEHICLEDESTROYED:
case EVT_BLIPCUSTOM:
case EVT_CHECKPOINTCUSTOM:
case EVT_KEYBINDCUSTOM:
case EVT_OBJECTCUSTOM:
case EVT_PICKUPCUSTOM:
case EVT_PLAYERCUSTOM:
case EVT_SPHERECUSTOM:
case EVT_SPRITECUSTOM:
case EVT_TEXTDRAWCUSTOM:
case EVT_VEHICLECUSTOM:
case EVT_PLAYERAWAY:
case EVT_PLAYERGAMEKEYS:
case EVT_PLAYERRENAME:
case EVT_PLAYERREQUESTCLASS:
case EVT_PLAYERREQUESTSPAWN:
case EVT_PLAYERSPAWN:
case EVT_PLAYERSTARTTYPING:
case EVT_PLAYERSTOPTYPING:
case EVT_PLAYERCHAT:
case EVT_PLAYERCOMMAND:
case EVT_PLAYERMESSAGE:
case EVT_PLAYERHEALTH:
case EVT_PLAYERARMOUR:
case EVT_PLAYERWEAPON:
case EVT_PLAYERMOVE:
case EVT_PLAYERWASTED:
case EVT_PLAYERKILLED:
case EVT_PLAYERTEAMKILL:
case EVT_PLAYERSPECTATE:
case EVT_PLAYERCRASHREPORT:
case EVT_PLAYERBURNING:
case EVT_PLAYERCROUCHING:
case EVT_PLAYERSTATE:
case EVT_PLAYERACTION:
case EVT_STATENONE:
case EVT_STATENORMAL:
case EVT_STATESHOOTING:
case EVT_STATEDRIVER:
case EVT_STATEPASSENGER:
case EVT_STATEENTERDRIVER:
case EVT_STATEENTERPASSENGER:
case EVT_STATEEXITVEHICLE:
case EVT_STATEUNSPAWNED:
case EVT_ACTIONNONE:
case EVT_ACTIONNORMAL:
case EVT_ACTIONAIMING:
case EVT_ACTIONSHOOTING:
case EVT_ACTIONJUMPING:
case EVT_ACTIONLIEDOWN:
case EVT_ACTIONGETTINGUP:
case EVT_ACTIONJUMPVEHICLE:
case EVT_ACTIONDRIVING:
case EVT_ACTIONDYING:
case EVT_ACTIONWASTED:
case EVT_ACTIONEMBARKING:
case EVT_ACTIONDISEMBARKING:
case EVT_VEHICLERESPAWN:
case EVT_VEHICLEEXPLODE:
case EVT_VEHICLEHEALTH:
case EVT_VEHICLEMOVE:
case EVT_PICKUPRESPAWN:
case EVT_KEYBINDKEYPRESS:
case EVT_KEYBINDKEYRELEASE:
case EVT_VEHICLEEMBARKING:
case EVT_VEHICLEEMBARKED:
case EVT_VEHICLEDISEMBARK:
case EVT_PICKUPCLAIMED:
case EVT_PICKUPCOLLECTED:
case EVT_OBJECTSHOT:
case EVT_OBJECTBUMP:
case EVT_CHECKPOINTENTERED:
case EVT_CHECKPOINTEXITED:
case EVT_SPHEREENTERED:
case EVT_SPHEREEXITED:
return true;
default:
return false;
}
}
// ------------------------------------------------------------------------------------------------
GlobalEvent::BlipFilter & GlobalEvent::GetBlipFilter() noexcept
{
@ -442,7 +465,6 @@ GlobalEvent::VehicleFilter & GlobalEvent::GetVehicleFilter() noexcept
// ------------------------------------------------------------------------------------------------
void GlobalEvent::BlipDestroyed(SQInt32 blip, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Blips.m_Filter[blip])
{
m_Blips.Release(blip);
@ -457,7 +479,6 @@ void GlobalEvent::BlipDestroyed(SQInt32 blip, SQInt32 header, Object & payload)
// ------------------------------------------------------------------------------------------------
void GlobalEvent::CheckpointDestroyed(SQInt32 checkpoint, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Checkpoints.m_Filter[checkpoint])
{
m_Checkpoints.Release(checkpoint);
@ -472,7 +493,6 @@ void GlobalEvent::CheckpointDestroyed(SQInt32 checkpoint, SQInt32 header, Object
// ------------------------------------------------------------------------------------------------
void GlobalEvent::KeybindDestroyed(SQInt32 keybind, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Keybinds.m_Filter[keybind])
{
m_Keybinds.Release(keybind);
@ -487,7 +507,6 @@ void GlobalEvent::KeybindDestroyed(SQInt32 keybind, SQInt32 header, Object & pay
// ------------------------------------------------------------------------------------------------
void GlobalEvent::ObjectDestroyed(SQInt32 object, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Objects.m_Filter[object])
{
m_Objects.Release(object);
@ -502,7 +521,6 @@ void GlobalEvent::ObjectDestroyed(SQInt32 object, SQInt32 header, Object & paylo
// ------------------------------------------------------------------------------------------------
void GlobalEvent::PickupDestroyed(SQInt32 pickup, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Pickups.m_Filter[pickup])
{
m_Pickups.Release(pickup);
@ -517,7 +535,6 @@ void GlobalEvent::PickupDestroyed(SQInt32 pickup, SQInt32 header, Object & paylo
// ------------------------------------------------------------------------------------------------
void GlobalEvent::PlayerDestroyed(SQInt32 player, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Players.m_Filter[player])
{
m_Players.Release(player);
@ -532,7 +549,6 @@ void GlobalEvent::PlayerDestroyed(SQInt32 player, SQInt32 header, Object & paylo
// ------------------------------------------------------------------------------------------------
void GlobalEvent::SphereDestroyed(SQInt32 sphere, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Spheres.m_Filter[sphere])
{
m_Spheres.Release(sphere);
@ -547,7 +563,6 @@ void GlobalEvent::SphereDestroyed(SQInt32 sphere, SQInt32 header, Object & paylo
// ------------------------------------------------------------------------------------------------
void GlobalEvent::SpriteDestroyed(SQInt32 sprite, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Sprites.m_Filter[sprite])
{
m_Sprites.Release(sprite);
@ -562,7 +577,6 @@ void GlobalEvent::SpriteDestroyed(SQInt32 sprite, SQInt32 header, Object & paylo
// ------------------------------------------------------------------------------------------------
void GlobalEvent::TextdrawDestroyed(SQInt32 textdraw, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Textdraws.m_Filter[textdraw])
{
m_Textdraws.Release(textdraw);
@ -577,7 +591,6 @@ void GlobalEvent::TextdrawDestroyed(SQInt32 textdraw, SQInt32 header, Object & p
// ------------------------------------------------------------------------------------------------
void GlobalEvent::VehicleDestroyed(SQInt32 vehicle, SQInt32 header, Object & payload) noexcept
{
// If the entity was included then block the signal an exclude it from filters
if (m_Vehicles.m_Filter[vehicle])
{
m_Vehicles.Release(vehicle);
@ -2046,101 +2059,6 @@ void GlobalEvent::Adaptable(SQInt32 type) noexcept
}
}
// ------------------------------------------------------------------------------------------------
bool GlobalEvent::Compatible(SQInt32 type) noexcept
{
switch (type)
{
case EVT_BLIPDESTROYED:
case EVT_CHECKPOINTDESTROYED:
case EVT_KEYBINDDESTROYED:
case EVT_OBJECTDESTROYED:
case EVT_PICKUPDESTROYED:
case EVT_PLAYERDESTROYED:
case EVT_SPHEREDESTROYED:
case EVT_SPRITEDESTROYED:
case EVT_TEXTDRAWDESTROYED:
case EVT_VEHICLEDESTROYED:
case EVT_BLIPCUSTOM:
case EVT_CHECKPOINTCUSTOM:
case EVT_KEYBINDCUSTOM:
case EVT_OBJECTCUSTOM:
case EVT_PICKUPCUSTOM:
case EVT_PLAYERCUSTOM:
case EVT_SPHERECUSTOM:
case EVT_SPRITECUSTOM:
case EVT_TEXTDRAWCUSTOM:
case EVT_VEHICLECUSTOM:
case EVT_PLAYERAWAY:
case EVT_PLAYERGAMEKEYS:
case EVT_PLAYERRENAME:
case EVT_PLAYERREQUESTCLASS:
case EVT_PLAYERREQUESTSPAWN:
case EVT_PLAYERSPAWN:
case EVT_PLAYERSTARTTYPING:
case EVT_PLAYERSTOPTYPING:
case EVT_PLAYERCHAT:
case EVT_PLAYERCOMMAND:
case EVT_PLAYERMESSAGE:
case EVT_PLAYERHEALTH:
case EVT_PLAYERARMOUR:
case EVT_PLAYERWEAPON:
case EVT_PLAYERMOVE:
case EVT_PLAYERWASTED:
case EVT_PLAYERKILLED:
case EVT_PLAYERTEAMKILL:
case EVT_PLAYERSPECTATE:
case EVT_PLAYERCRASHREPORT:
case EVT_PLAYERBURNING:
case EVT_PLAYERCROUCHING:
case EVT_PLAYERSTATE:
case EVT_PLAYERACTION:
case EVT_STATENONE:
case EVT_STATENORMAL:
case EVT_STATESHOOTING:
case EVT_STATEDRIVER:
case EVT_STATEPASSENGER:
case EVT_STATEENTERDRIVER:
case EVT_STATEENTERPASSENGER:
case EVT_STATEEXITVEHICLE:
case EVT_STATEUNSPAWNED:
case EVT_ACTIONNONE:
case EVT_ACTIONNORMAL:
case EVT_ACTIONAIMING:
case EVT_ACTIONSHOOTING:
case EVT_ACTIONJUMPING:
case EVT_ACTIONLIEDOWN:
case EVT_ACTIONGETTINGUP:
case EVT_ACTIONJUMPVEHICLE:
case EVT_ACTIONDRIVING:
case EVT_ACTIONDYING:
case EVT_ACTIONWASTED:
case EVT_ACTIONEMBARKING:
case EVT_ACTIONDISEMBARKING:
case EVT_VEHICLERESPAWN:
case EVT_VEHICLEEXPLODE:
case EVT_VEHICLEHEALTH:
case EVT_VEHICLEMOVE:
case EVT_PICKUPRESPAWN:
case EVT_KEYBINDKEYPRESS:
case EVT_KEYBINDKEYRELEASE:
case EVT_VEHICLEEMBARKING:
case EVT_VEHICLEEMBARKED:
case EVT_VEHICLEDISEMBARK:
case EVT_PICKUPCLAIMED:
case EVT_PICKUPCOLLECTED:
case EVT_OBJECTSHOT:
case EVT_OBJECTBUMP:
case EVT_CHECKPOINTENTERED:
case EVT_CHECKPOINTEXITED:
case EVT_SPHEREENTERED:
case EVT_SPHEREEXITED:
return true;
default:
return false;
}
}
// ================================================================================================
template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQChar * cname)
{
@ -2148,9 +2066,9 @@ template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQC
LogDbg("Beginning registration of <%s> type", cname);
// Avoid using the long name of the type we're about to register
typedef GlobalFilter< T > Filter;
// Filters should not be constructed
// Filters should not be constructed to avoid further complications
typedef NoConstructor< Filter > Allocator;
// Attempt to register the specified type
// Attempt to register the specified filtertype
Sqrat::RootTable(vm).Bind(cname, Sqrat::Class< Filter, Allocator >(vm, cname)
.Func(_SC("_cmp"), &Filter::Cmp)
.Func(_SC("_tostring"), &Filter::ToString)
@ -2160,10 +2078,10 @@ template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQC
.Prop(_SC("none"), &Filter::None)
.Prop(_SC("all"), &Filter::All)
.template Overload< void (Filter::*)(const typename Filter::RefType &) >(_SC("include"), &Filter::Include)
.template Overload< void (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("include"), &Filter::Include)
.template Overload< void (Filter::*)(const typename Filter::RefType &) >(_SC("exclude"), &Filter::Exclude)
.template Overload< void (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("exclude"), &Filter::Exclude)
.template Overload< bool (Filter::*)(const typename Filter::RefType &) >(_SC("include"), &Filter::Include)
.template Overload< bool (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("include"), &Filter::Include)
.template Overload< bool (Filter::*)(const typename Filter::RefType &) >(_SC("exclude"), &Filter::Exclude)
.template Overload< bool (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("exclude"), &Filter::Exclude)
//.Func(_SC("exclude"), &Filter::Exclude)
.Func(_SC("enabled"), &Filter::Enabled)
.Func(_SC("clear"), &Filter::Clear)
@ -2193,8 +2111,10 @@ bool Register_GlobalEvent(HSQUIRRELVM vm)
}
// Output debugging information
LogDbg("Beginning registration of <GlobalEvent> type");
// Events should not be copied for the sake of simplicity
typedef NoCopy< GlobalEvent > Allocator;
// Attempt to register the specified type
Sqrat::RootTable(vm).Bind(_SC("GlobalEvent"), Sqrat::Class< GlobalEvent >(vm, _SC("GlobalEvent"))
Sqrat::RootTable(vm).Bind(_SC("GlobalEvent"), Sqrat::Class< GlobalEvent, Allocator >(vm, _SC("GlobalEvent"))
.Ctor()
.Ctor<SQInt32>()
.Ctor<SQInt32, bool>()
@ -2213,6 +2133,7 @@ bool Register_GlobalEvent(HSQUIRRELVM vm)
.Prop(_SC("secondary"), &GlobalEvent::GetSecondary, &GlobalEvent::SetSecondary)
.Prop(_SC("confined"), &GlobalEvent::GetConfined, &GlobalEvent::SetConfined)
.Prop(_SC("suspended"), &GlobalEvent::GetSuspended, &GlobalEvent::SetSuspended)
.Prop(_SC("compatible"), &GlobalEvent::Compatible)
.Prop(_SC("name"), &GlobalEvent::GetName)
.Prop(_SC("on_trigger"), &GlobalEvent::GetOnTrigger, &GlobalEvent::SetOnTrigger)
@ -2238,5 +2159,4 @@ bool Register_GlobalEvent(HSQUIRRELVM vm)
return true;
}
} // Namespace:: SqMod

View File

@ -23,8 +23,9 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* ...
// ------------------------------------------------------------------------------------------------
/** Internal class used to reduce code duplication when filtering entities in a global event.
*
*/
template < class T > class GlobalFilter
{
@ -45,14 +46,7 @@ public:
typedef Reference< T > RefType; /* Short name for the entity reference type */
typedef Ent< T > EntType; /* Short name for the entity specification structure */
/* --------------------------------------------------------------------------------------------
* Default constructor
*/
GlobalFilter() noexcept
: m_Filter(), m_Event(nullptr)
{
/* This kind of filter should now be nothing more than dead weight! */
}
private:
/* --------------------------------------------------------------------------------------------
* Construct the filter for the specified event.
@ -64,24 +58,17 @@ public:
}
/* --------------------------------------------------------------------------------------------
* Copy constructor
* Copy constructor (disabled)
*/
GlobalFilter(const GlobalFilter< T > & o) noexcept
: m_Filter(o.m_Filter), m_Event(o.m_Event)
{
// Make sure we have a parent to be considered suitable for hooking
if (m_Event != nullptr)
{
Hook();
}
/* Parent is ignored intentionally as filters should not copy parents! */
}
GlobalFilter(const GlobalFilter< T > &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled)
*/
GlobalFilter(GlobalFilter< T > &&) = delete;
public:
/* --------------------------------------------------------------------------------------------
* Destructor
*/
@ -140,27 +127,27 @@ public:
/* --------------------------------------------------------------------------------------------
* Include the specified entity in the filter.
*/
void Include(const RefType & ent, SQInt32 header) noexcept;
bool Include(const RefType & ent, SQInt32 header) noexcept;
/* --------------------------------------------------------------------------------------------
* Include the specified entity in the filter.
*/
void Include(const RefType & ent) noexcept
bool Include(const RefType & ent) noexcept
{
Include(ent, 0);
return Include(ent, 0);
}
/* --------------------------------------------------------------------------------------------
* Exclude the specified entity from the filter.
*/
void Exclude(const RefType & ent, SQInt32 header) noexcept;
bool Exclude(const RefType & ent, SQInt32 header) noexcept;
/* --------------------------------------------------------------------------------------------
* Exclude the specified entity from the filter.
*/
void Exclude(const RefType & ent) noexcept
bool Exclude(const RefType & ent) noexcept
{
Exclude(ent, 0);
return Exclude(ent, 0);
}
/* --------------------------------------------------------------------------------------------
@ -247,6 +234,7 @@ protected:
* Unhook from the entity destroy signal that the parent didn't.
*/
void Unhook() noexcept;
private:
// --------------------------------------------------------------------------------------------
@ -301,7 +289,7 @@ public:
/* --------------------------------------------------------------------------------------------
* ...
*/
GlobalEvent(const GlobalEvent & o) noexcept;
GlobalEvent(const GlobalEvent &) = delete;
/* --------------------------------------------------------------------------------------------
* ...
@ -316,7 +304,7 @@ public:
/* --------------------------------------------------------------------------------------------
* ...
*/
GlobalEvent & operator = (const GlobalEvent & o) noexcept;
GlobalEvent & operator = (const GlobalEvent &) = delete;
/* --------------------------------------------------------------------------------------------
* ...
@ -542,6 +530,11 @@ public:
*/
void SetOnRelease(const Function & func) noexcept;
/* --------------------------------------------------------------------------------------------
* ...
*/
bool Compatible(SQInt32 type) const noexcept;
/* --------------------------------------------------------------------------------------------
* ...
*/
@ -1044,11 +1037,6 @@ protected:
*/
void Adaptable(SQInt32 type) noexcept;
/* --------------------------------------------------------------------------------------------
* ...
*/
bool Compatible(SQInt32 type) noexcept;
private:
// --------------------------------------------------------------------------------------------
@ -1097,7 +1085,7 @@ private:
template < class T > GlobalFilter< T > & GlobalFilter< T >::operator = (const GlobalFilter< T > & o) noexcept
{
// Make sure we're not doing self assignment, work with orphan filters or incompatible events
if (this != &o && m_Event != nullptr && EntType::InEvent(m_Event->m_Type))
if (this != &o && EntType::InEvent(m_Event->m_Type))
{
// Unhook from the currently filtered entities
Unhook();
@ -1112,16 +1100,10 @@ template < class T > GlobalFilter< T > & GlobalFilter< T >::operator = (const Gl
}
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Include(const RefType & ent, SQInt32 header) noexcept
template < class T > bool GlobalFilter< T >::Include(const RefType & ent, SQInt32 header) noexcept
{
// Make sure the filter is parented before proceeeding
if (m_Event == nullptr)
{
LogErr("Attempting to <filter %s events> using an orphan entity filter", \
EntType::Name);
}
// Make sure the entity is valid before we proceed
else if (!ent)
if (!ent)
{
LogErr("Attempting to <filter %s events> using an invalid entity instance: %d", \
EntType::Name, _SCI32(ent));
@ -1156,20 +1138,18 @@ template < class T > void GlobalFilter< T >::Include(const RefType & ent, SQInt3
// Enable the specified entity instance in our filter
m_Filter.set(_SCU32(ent), true);
}
// Return whether this was included or not
return allow;
}
// Reaching here means failure
return false;
}
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Exclude(const RefType & ent, SQInt32 header) noexcept
template < class T > bool GlobalFilter< T >::Exclude(const RefType & ent, SQInt32 header) noexcept
{
// Make sure the filter is parented before proceeeding
if (m_Event == nullptr)
{
LogErr("Attempting to <unfilter %s events> using an orphan entity filter", \
EntType::Name);
}
// Make sure the entity is valid before we proceed
else if (!ent)
if (!ent)
{
LogErr("Attempting to <unfilter %s events> using an invalid entity instance: %d", \
EntType::Name, _SCI32(ent));
@ -1201,23 +1181,21 @@ template < class T > void GlobalFilter< T >::Exclude(const RefType & ent, SQInt3
{
RefType::Get(_SCI32(ent)).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this);
}
// Enable the specified entity instance in our filter
// Disable the specified entity instance in our filter
m_Filter.set(_SCU32(ent), false);
}
// Return whether this was excluded or not
return allow;
}
// Reaching here means failure
return false;
}
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Clear(SQInt32 header) noexcept
{
// Make sure the filter is parented before proceeeding
if (m_Event == nullptr)
{
LogWrn("Attempting to <clear %s filter> using an orphan entity filter", \
EntType::Name);
}
// Make sure the filter is compatible with the parent event type
else if (!EntType::InEvent(m_Event->m_Type))
// Make sure the filter is compatible with the specified event type
if (!EntType::InEvent(m_Event->m_Type))
{
LogWrn("Attempting to <clear %s filter> using an incompatible event type: %s", \
EntType::Name, GetEventName(m_Event->m_Type));
@ -1240,14 +1218,8 @@ template < class T > void GlobalFilter< T >::Clear(SQInt32 header) noexcept
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Flip(SQInt32 header) noexcept
{
// Make sure the filter is parented before proceeeding
if (m_Event == nullptr)
{
LogWrn("Attempting to <flip %s filter> using an orphan entity filter", \
EntType::Name);
}
// Make sure the filter is compatible with the parent event type
else if (!EntType::InEvent(m_Event->m_Type))
if (!EntType::InEvent(m_Event->m_Type))
{
LogWrn("Attempting to <flip %s filter> using an incompatible event type: %s", \
EntType::Name, GetEventName(m_Event->m_Type));
@ -1266,15 +1238,6 @@ template < class T > void GlobalFilter< T >::Flip(SQInt32 header) noexcept
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Release(SQInt32 id) noexcept
{
// Make sure the filter is parented before proceeeding
if (m_Event == nullptr)
{
LogErr("Attempting to <release %s entity> using an orphan entity filter", \
EntType::Name);
}
// Now it's safe to release
else
{
// Do we have to notify someone that this entity is about to be released?
if (!m_Event->m_OnRelease.IsNull())
@ -1284,22 +1247,29 @@ template < class T > void GlobalFilter< T >::Release(SQInt32 id) noexcept
// Now disable the entity in the filter
m_Filter.set(id, false);
}
}
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Hook() noexcept
{
// Make sure the entities inform us when being destroyed as long as we're parented
if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type)
// Make sure the filter is unaware of the destroy event before proceeeding
if (EntType::DestroyEvID == m_Event->m_Type)
{
return;
}
// No iterators here because we're dealing with a bitset!
for (unsigned i = 0; i < m_Filter.size(); ++i)
unsigned i = 0;
bool enabled = RefType::Verify(i);
for (; i < m_Filter.size(); enabled = RefType::Verify(++i))
{
// If this bit is enabled then this entity is included so we must hook to it
if (m_Filter[i])
if (m_Filter[i] && enabled)
{
RefType::Get(i).Destroyed().template Connect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this);
}
// If this entity is not active then disable it from the filter as well
else if (!enabled)
{
m_Filter.set(i, false);
}
}
}
@ -1307,17 +1277,25 @@ template < class T > void GlobalFilter< T >::Hook() noexcept
// ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Unhook() noexcept
{
// Make sure the entities will not inform us when being destroyed as long as we're parented
if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type)
// Make sure the filter is unaware of the destroy event before proceeeding
if (EntType::DestroyEvID == m_Event->m_Type)
{
return;
}
// No iterators here because we're dealing with a bitset!
for (unsigned i = 0; i < m_Filter.size(); ++i)
unsigned i = 0;
bool enabled = RefType::Verify(i);
for (; i < m_Filter.size(); enabled = RefType::Verify(++i))
{
// If this bit is enabled then this entity is included so we must unhook from it
if (m_Filter[i])
if (m_Filter[i] && enabled)
{
RefType::Get(i).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this);
}
// If this entity is not active then disable it from the filter as well
else if (!enabled)
{
m_Filter.set(i, false);
}
}
}