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

File diff suppressed because it is too large Load Diff

View File

@ -23,8 +23,9 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
/* ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
* ... /** Internal class used to reduce code duplication when filtering entities in a global event.
*
*/ */
template < class T > class GlobalFilter template < class T > class GlobalFilter
{ {
@ -45,14 +46,7 @@ public:
typedef Reference< T > RefType; /* Short name for the entity reference type */ typedef Reference< T > RefType; /* Short name for the entity reference type */
typedef Ent< T > EntType; /* Short name for the entity specification structure */ typedef Ent< T > EntType; /* Short name for the entity specification structure */
/* -------------------------------------------------------------------------------------------- private:
* Default constructor
*/
GlobalFilter() noexcept
: m_Filter(), m_Event(nullptr)
{
/* This kind of filter should now be nothing more than dead weight! */
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Construct the filter for the specified event. * Construct the filter for the specified event.
@ -64,24 +58,17 @@ public:
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor * Copy constructor (disabled)
*/ */
GlobalFilter(const GlobalFilter< T > & o) noexcept GlobalFilter(const GlobalFilter< T > &) = delete;
: 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! */
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Move constructor (disabled) * Move constructor (disabled)
*/ */
GlobalFilter(GlobalFilter< T > &&) = delete; GlobalFilter(GlobalFilter< T > &&) = delete;
public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Destructor * Destructor
*/ */
@ -140,27 +127,27 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Include the specified entity in the filter. * 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. * 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. * 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. * 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. * Unhook from the entity destroy signal that the parent didn't.
*/ */
void Unhook() noexcept; void Unhook() noexcept;
private: 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; void SetOnRelease(const Function & func) noexcept;
/* --------------------------------------------------------------------------------------------
* ...
*/
bool Compatible(SQInt32 type) const noexcept;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* ... * ...
*/ */
@ -1044,11 +1037,6 @@ protected:
*/ */
void Adaptable(SQInt32 type) noexcept; void Adaptable(SQInt32 type) noexcept;
/* --------------------------------------------------------------------------------------------
* ...
*/
bool Compatible(SQInt32 type) noexcept;
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -1097,7 +1085,7 @@ private:
template < class T > GlobalFilter< T > & GlobalFilter< T >::operator = (const GlobalFilter< T > & o) noexcept 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 // 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 from the currently filtered entities
Unhook(); 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 // 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", \ LogErr("Attempting to <filter %s events> using an invalid entity instance: %d", \
EntType::Name, _SCI32(ent)); 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 // Enable the specified entity instance in our filter
m_Filter.set(_SCU32(ent), true); 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 // 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", \ LogErr("Attempting to <unfilter %s events> using an invalid entity instance: %d", \
EntType::Name, _SCI32(ent)); 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); 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); 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 template < class T > void GlobalFilter< T >::Clear(SQInt32 header) noexcept
{ {
// Make sure the filter is parented before proceeeding // Make sure the filter is compatible with the specified event type
if (m_Event == nullptr) if (!EntType::InEvent(m_Event->m_Type))
{
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))
{ {
LogWrn("Attempting to <clear %s filter> using an incompatible event type: %s", \ LogWrn("Attempting to <clear %s filter> using an incompatible event type: %s", \
EntType::Name, GetEventName(m_Event->m_Type)); 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 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 // 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", \ LogWrn("Attempting to <flip %s filter> using an incompatible event type: %s", \
EntType::Name, GetEventName(m_Event->m_Type)); EntType::Name, GetEventName(m_Event->m_Type));
@ -1267,39 +1239,37 @@ template < class T > void GlobalFilter< T >::Flip(SQInt32 header) noexcept
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Release(SQInt32 id) noexcept template < class T > void GlobalFilter< T >::Release(SQInt32 id) noexcept
{ {
// Make sure the filter is parented before proceeeding // Do we have to notify someone that this entity is about to be released?
if (m_Event == nullptr) if (!m_Event->m_OnRelease.IsNull())
{ {
LogErr("Attempting to <release %s entity> using an orphan entity filter", \ m_Event->m_OnRelease.Execute< SQInt32 >(id);
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())
{
m_Event->m_OnRelease.Execute< SQInt32 >(id);
}
// Now disable the entity in the filter
m_Filter.set(id, false);
} }
// Now disable the entity in the filter
m_Filter.set(id, false);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template < class T > void GlobalFilter< T >::Hook() noexcept template < class T > void GlobalFilter< T >::Hook() noexcept
{ {
// Make sure the entities inform us when being destroyed as long as we're parented // Make sure the filter is unaware of the destroy event before proceeeding
if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type) if (EntType::DestroyEvID == m_Event->m_Type)
{ {
// No iterators here because we're dealing with a bitset! return;
for (unsigned i = 0; i < m_Filter.size(); ++i) }
// No iterators here because we're dealing with a bitset!
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] && enabled)
{ {
// If this bit is enabled then this entity is included so we must hook to it RefType::Get(i).Destroyed().template Connect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this);
if (m_Filter[i]) }
{ // If this entity is not active then disable it from the filter as well
RefType::Get(i).Destroyed().template Connect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); 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 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 // Make sure the filter is unaware of the destroy event before proceeeding
if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type) if (EntType::DestroyEvID == m_Event->m_Type)
{ {
// No iterators here because we're dealing with a bitset! return;
for (unsigned i = 0; i < m_Filter.size(); ++i) }
// No iterators here because we're dealing with a bitset!
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] && enabled)
{ {
// If this bit is enabled then this entity is included so we must unhook from it RefType::Get(i).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this);
if (m_Filter[i]) }
{ // If this entity is not active then disable it from the filter as well
RefType::Get(i).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); else if (!enabled)
} {
m_Filter.set(i, false);
} }
} }
} }