diff --git a/cbp/Module.cbp b/cbp/Module.cbp index 67862dd4..be04375d 100644 --- a/cbp/Module.cbp +++ b/cbp/Module.cbp @@ -469,6 +469,7 @@ + @@ -540,8 +541,6 @@ - - @@ -549,6 +548,8 @@ + + diff --git a/shared/Base/Utility.hpp b/shared/Base/Utility.hpp index e631bc8a..c96fb8a3 100644 --- a/shared/Base/Utility.hpp +++ b/shared/Base/Utility.hpp @@ -108,6 +108,11 @@ bool SToB(CSStr str); */ Object & NullObject(); +/* ------------------------------------------------------------------------------------------------ + * Retrieve a reference to a null script object. +*/ +LightObj & NullLightObj(); + /* ------------------------------------------------------------------------------------------------ * Retrieve a reference to a null/empty script table. */ @@ -1303,83 +1308,6 @@ typedef BitGuard< Uint8 > BitGuardU8; typedef BitGuard< Uint16 > BitGuardU16; typedef BitGuard< Uint32 > BitGuardU32; -/* ------------------------------------------------------------------------------------------------ - * RAII approach to make sure an instance is deleted regardless of what exceptions are thrown. -*/ -template < typename T > struct DeleteGuard -{ -private: - - // -------------------------------------------------------------------------------------------- - T * m_Ptr; // Pointer to the instance to manage. - -public: - - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - DeleteGuard(T * ptr) - : m_Ptr(ptr) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - DeleteGuard(const DeleteGuard & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - DeleteGuard(DeleteGuard && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~DeleteGuard() - { - if (m_Ptr) - { - delete m_Ptr; - } - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - DeleteGuard & operator = (const DeleteGuard & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - DeleteGuard & operator = (DeleteGuard && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion the managed instance type. - */ - operator T * () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the managed instance. - */ - T * Get() const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Release the managed instance. - */ - void Release() - { - m_Ptr = nullptr; - } -}; - /* ------------------------------------------------------------------------------------------------ * RAII approach to make sure a value is assigned regardless of what exceptions are thrown. */ diff --git a/shared/Base/Utility.inl b/shared/Base/Utility.inl index 7634d612..64d34663 100644 --- a/shared/Base/Utility.inl +++ b/shared/Base/Utility.inl @@ -235,6 +235,14 @@ Object & NullObject() return o; } +// ------------------------------------------------------------------------------------------------ +LightObj & NullLightObj() +{ + static LightObj o; + o.Release(); + return o; +} + // ------------------------------------------------------------------------------------------------ Table & NullTable() { diff --git a/source/Base/Algo.cpp b/source/Base/Algo.cpp index 10fecae6..448e0ee1 100644 --- a/source/Base/Algo.cpp +++ b/source/Base/Algo.cpp @@ -111,7 +111,7 @@ struct PlayerName }; // ------------------------------------------------------------------------------------------------ -static const Object & Blip_FindBySprID(Int32 sprid) +static const LightObj & Blip_FindBySprID(Int32 sprid) { // Perform a range check on the specified identifier if (sprid < 0) @@ -131,7 +131,7 @@ static const Object & Blip_FindBySprID(Int32 sprid) } } // Unable to locate a blip matching the specified identifier - return NullObject(); + return NullLightObj(); } /* ------------------------------------------------------------------------------------------------ @@ -227,7 +227,7 @@ static inline Array Player_AllWhereNameMatches(bool neg, bool cs, CSStr name) /* ------------------------------------------------------------------------------------------------ * Retrieve the first player where the name matches or not the specified one. */ -static inline Object Player_FirstWhereNameEquals(bool neg, bool cs, CSStr name) +static inline LightObj Player_FirstWhereNameEquals(bool neg, bool cs, CSStr name) { SQMOD_VALID_NAME_STR(name) // Create a new element receiver @@ -243,7 +243,7 @@ static inline Object Player_FirstWhereNameEquals(bool neg, bool cs, CSStr name) /* ------------------------------------------------------------------------------------------------ * Retrieve the first player where the name begins or not with the specified string. */ -static inline Object Player_FirstWhereNameBegins(bool neg, bool cs, CSStr name) +static inline LightObj Player_FirstWhereNameBegins(bool neg, bool cs, CSStr name) { SQMOD_VALID_NAME_STR(name) // Create a new element receiver @@ -259,7 +259,7 @@ static inline Object Player_FirstWhereNameBegins(bool neg, bool cs, CSStr name) /* ------------------------------------------------------------------------------------------------ * Retrieve the first player where the name ends or not with the specified string. */ -static inline Object Player_FirstWhereNameEnds(bool neg, bool cs, CSStr name) +static inline LightObj Player_FirstWhereNameEnds(bool neg, bool cs, CSStr name) { SQMOD_VALID_NAME_STR(name) // Create a new element receiver @@ -275,7 +275,7 @@ static inline Object Player_FirstWhereNameEnds(bool neg, bool cs, CSStr name) /* ------------------------------------------------------------------------------------------------ * Retrieve the first player where the name contains or not the specified string. */ -static inline Object Player_FirstWhereNameContains(bool neg, bool cs, CSStr name) +static inline LightObj Player_FirstWhereNameContains(bool neg, bool cs, CSStr name) { SQMOD_VALID_NAME_STR(name) // Create a new element receiver @@ -291,7 +291,7 @@ static inline Object Player_FirstWhereNameContains(bool neg, bool cs, CSStr name /* ------------------------------------------------------------------------------------------------ * Retrieve the first player where the name matches or not the specified filter. */ -static inline Object Player_FirstWhereNameMatches(bool neg, bool cs, CSStr name) +static inline LightObj Player_FirstWhereNameMatches(bool neg, bool cs, CSStr name) { SQMOD_VALID_NAME_STR(name) // Create a new element receiver @@ -307,7 +307,7 @@ static inline Object Player_FirstWhereNameMatches(bool neg, bool cs, CSStr name) /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name matches or not the specified one. */ -static inline Uint32 Player_EachWhereNameEquals(bool neg, bool cs, CSStr name, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameEquals(bool neg, bool cs, CSStr name, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -323,7 +323,7 @@ static inline Uint32 Player_EachWhereNameEquals(bool neg, bool cs, CSStr name, O /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name matches or not the specified one. */ -static inline Uint32 Player_EachWhereNameEqualsData(bool neg, bool cs, CSStr name, Object & data, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameEqualsData(bool neg, bool cs, CSStr name, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -339,7 +339,7 @@ static inline Uint32 Player_EachWhereNameEqualsData(bool neg, bool cs, CSStr nam /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name begins with the specified string. */ -static inline Uint32 Player_EachWhereNameBegins(bool neg, bool cs, CSStr name, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameBegins(bool neg, bool cs, CSStr name, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -355,7 +355,7 @@ static inline Uint32 Player_EachWhereNameBegins(bool neg, bool cs, CSStr name, O /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name begins with the specified string. */ -static inline Uint32 Player_EachWhereNameBeginsData(bool neg, bool cs, CSStr name, Object & data, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameBeginsData(bool neg, bool cs, CSStr name, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -371,7 +371,7 @@ static inline Uint32 Player_EachWhereNameBeginsData(bool neg, bool cs, CSStr nam /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name ends or not with the specified string. */ -static inline Uint32 Player_EachWhereNameEnds(bool neg, bool cs, CSStr name, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameEnds(bool neg, bool cs, CSStr name, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -387,7 +387,7 @@ static inline Uint32 Player_EachWhereNameEnds(bool neg, bool cs, CSStr name, Obj /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name ends or not with the specified string. */ -static inline Uint32 Player_EachWhereNameEndsData(bool neg, bool cs, CSStr name, Object & data, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameEndsData(bool neg, bool cs, CSStr name, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -403,7 +403,7 @@ static inline Uint32 Player_EachWhereNameEndsData(bool neg, bool cs, CSStr name, /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name contains the specified string. */ -static inline Uint32 Player_EachWhereNameContains(bool neg, bool cs, CSStr name, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameContains(bool neg, bool cs, CSStr name, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -419,7 +419,7 @@ static inline Uint32 Player_EachWhereNameContains(bool neg, bool cs, CSStr name, /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name contains the specified string. */ -static inline Uint32 Player_EachWhereNameContainsData(bool neg, bool cs, CSStr name, Object & data, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameContainsData(bool neg, bool cs, CSStr name, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -435,7 +435,7 @@ static inline Uint32 Player_EachWhereNameContainsData(bool neg, bool cs, CSStr n /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name matches the specified filter. */ -static inline Uint32 Player_EachWhereNameMatches(bool neg, bool cs, CSStr name, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameMatches(bool neg, bool cs, CSStr name, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder @@ -451,7 +451,7 @@ static inline Uint32 Player_EachWhereNameMatches(bool neg, bool cs, CSStr name, /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the name matches the specified filter. */ -static inline Uint32 Player_EachWhereNameMatchesData(bool neg, bool cs, CSStr name, Object & data, Object & env, Function & func) +static inline Uint32 Player_EachWhereNameMatchesData(bool neg, bool cs, CSStr name, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_NAME_STR(name) // Create a new element forwarder diff --git a/source/Base/Algo.hpp b/source/Base/Algo.hpp index 8c2f5884..f6ccc8f2 100644 --- a/source/Base/Algo.hpp +++ b/source/Base/Algo.hpp @@ -457,7 +457,7 @@ template <> struct InstSpec< CBlip > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullBlip(); } @@ -498,7 +498,7 @@ template <> struct InstSpec< CCheckpoint > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullCheckpoint(); } @@ -539,7 +539,7 @@ template <> struct InstSpec< CKeybind > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullKeybind(); } @@ -580,7 +580,7 @@ template <> struct InstSpec< CObject > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullObject(); } @@ -621,7 +621,7 @@ template <> struct InstSpec< CPickup > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullPickup(); } @@ -662,7 +662,7 @@ template <> struct InstSpec< CPlayer > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullPlayer(); } @@ -703,7 +703,7 @@ template <> struct InstSpec< CVehicle > /* -------------------------------------------------------------------------------------------- * Reference to the NULL instance. */ - static inline Object & Null() + static inline LightObj & Null() { return Core::Get().GetNullVehicle(); } @@ -776,7 +776,7 @@ template < typename T > struct AppendElemFunc template < typename T > struct RecvElemFunc { // -------------------------------------------------------------------------------------------- - Object mObj; // Reference to the received object. + LightObj mObj; // Reference to the received object. /* -------------------------------------------------------------------------------------------- * Default constructor. @@ -798,7 +798,7 @@ template < typename T > struct RecvElemFunc /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed object. */ - operator Object () + operator LightObj () { return mObj; } @@ -806,7 +806,7 @@ template < typename T > struct RecvElemFunc /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed object. */ - operator Object & () + operator LightObj & () { return mObj; } @@ -814,7 +814,7 @@ template < typename T > struct RecvElemFunc /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed object. */ - operator const Object & () const + operator const LightObj & () const { return mObj; } @@ -834,7 +834,7 @@ public: /* -------------------------------------------------------------------------------------------- * Base constructor. */ - ForwardElemFunc(Object & env, Function & func) + ForwardElemFunc(LightObj & env, Function & func) : mFunc(env.IsNull() ? func : Function(env.GetVM(), env, func.GetFunc())), mCount(0) { if (mFunc.IsNull()) @@ -894,13 +894,13 @@ public: // -------------------------------------------------------------------------------------------- Function mFunc; // The script callback to forward the element. - Object mData; // The script payload to accompany the element. + LightObj mData; // The script payload to accompany the element. Uint32 mCount; // The number of elements forwarded by this functor. /* -------------------------------------------------------------------------------------------- * Base constructor. */ - ForwardElemDataFunc(Object & data, Object & env, Function & func) + ForwardElemDataFunc(LightObj & data, LightObj & env, Function & func) : mFunc(env.IsNull() ? func : Function(env.GetVM(), env, func.GetFunc())), mData(data), mCount(0) { if (mFunc.IsNull()) @@ -945,7 +945,7 @@ public: /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed payload. */ - operator Object () + operator LightObj () { return mData; } @@ -953,7 +953,7 @@ public: /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed payload. */ - operator Object & () + operator LightObj & () { return mData; } @@ -961,7 +961,7 @@ public: /* -------------------------------------------------------------------------------------------- * Implicit cast to the managed payload. */ - operator const Object & () const + operator const LightObj & () const { return mData; } @@ -1066,7 +1066,7 @@ public: /* -------------------------------------------------------------------------------------------- * Find the entity that matches the specified identifier. */ - static inline const Object & FindByID(Int32 id) + static inline const LightObj & FindByID(Int32 id) { // Perform a range check on the specified identifier if (INVALID_ENTITYEX(id, Inst::Max)) @@ -1186,7 +1186,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the first entity of this type where the tag matches or not the specified one. */ - static inline Object FirstWhereTagEquals(bool neg, bool cs, CSStr tag) + static inline LightObj FirstWhereTagEquals(bool neg, bool cs, CSStr tag) { SQMOD_VALID_TAG_STR(tag) // Create a new element receiver @@ -1201,7 +1201,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the first entity of this type where the tag begins or not with the specified string. */ - static inline Object FirstWhereTagBegins(bool neg, bool cs, CSStr tag) + static inline LightObj FirstWhereTagBegins(bool neg, bool cs, CSStr tag) { SQMOD_VALID_TAG_STR(tag) // Create a new element receiver @@ -1216,7 +1216,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the first entity of this type where the tag ends or not with the specified string. */ - static inline Object FirstWhereTagEnds(bool neg, bool cs, CSStr tag) + static inline LightObj FirstWhereTagEnds(bool neg, bool cs, CSStr tag) { SQMOD_VALID_TAG_STR(tag) // Create a new element receiver @@ -1231,7 +1231,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the first entity of this type where the tag contains or not the specified string. */ - static inline Object FirstWhereTagContains(bool neg, bool cs, CSStr tag) + static inline LightObj FirstWhereTagContains(bool neg, bool cs, CSStr tag) { SQMOD_VALID_TAG_STR(tag) // Create a new element receiver @@ -1246,7 +1246,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the first entity of this type where the tag matches or not the specified filter. */ - static inline Object FirstWhereTagMatches(bool neg, bool cs, CSStr tag) + static inline LightObj FirstWhereTagMatches(bool neg, bool cs, CSStr tag) { SQMOD_VALID_TAG_STR(tag) // Create a new element receiver @@ -1261,7 +1261,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all active entities of this type. */ - static inline Uint32 EachActive(Object & env, Function & func) + static inline Uint32 EachActive(LightObj & env, Function & func) { // Create a new element forwarder ForwardElem fwd(env, func); @@ -1275,7 +1275,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all active entities of this type. */ - static inline Uint32 EachActiveData(Object & data, Object & env, Function & func) + static inline Uint32 EachActiveData(LightObj & data, LightObj & env, Function & func) { // Create a new element forwarder ForwardElemData fwd(data, env, func); @@ -1289,7 +1289,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag matches or not the specified one. */ - static inline Uint32 EachWhereTagEquals(bool neg, bool cs, CSStr tag, Object & env, Function & func) + static inline Uint32 EachWhereTagEquals(bool neg, bool cs, CSStr tag, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1304,7 +1304,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag matches or not the specified one. */ - static inline Uint32 EachWhereTagEqualsData(bool neg, bool cs, CSStr tag, Object & data, Object & env, Function & func) + static inline Uint32 EachWhereTagEqualsData(bool neg, bool cs, CSStr tag, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1319,7 +1319,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag begins with the specified string. */ - static inline Uint32 EachWhereTagBegins(bool neg, bool cs, CSStr tag, Object & env, Function & func) + static inline Uint32 EachWhereTagBegins(bool neg, bool cs, CSStr tag, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1334,7 +1334,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag begins with the specified string. */ - static inline Uint32 EachWhereTagBeginsData(bool neg, bool cs, CSStr tag, Object & data, Object & env, Function & func) + static inline Uint32 EachWhereTagBeginsData(bool neg, bool cs, CSStr tag, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1349,7 +1349,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag ends or not with the specified string. */ - static inline Uint32 EachWhereTagEnds(bool neg, bool cs, CSStr tag, Object & env, Function & func) + static inline Uint32 EachWhereTagEnds(bool neg, bool cs, CSStr tag, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1364,7 +1364,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag ends or not with the specified string. */ - static inline Uint32 EachWhereTagEndsData(bool neg, bool cs, CSStr tag, Object & data, Object & env, Function & func) + static inline Uint32 EachWhereTagEndsData(bool neg, bool cs, CSStr tag, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1379,7 +1379,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag contains the specified string. */ - static inline Uint32 EachWhereTagContains(bool neg, bool cs, CSStr tag, Object & env, Function & func) + static inline Uint32 EachWhereTagContains(bool neg, bool cs, CSStr tag, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1394,7 +1394,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag contains the specified string. */ - static inline Uint32 EachWhereTagContainsData(bool neg, bool cs, CSStr tag, Object & data, Object & env, Function & func) + static inline Uint32 EachWhereTagContainsData(bool neg, bool cs, CSStr tag, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1409,7 +1409,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag match the specified filter. */ - static inline Uint32 EachWhereTagMatches(bool neg, bool cs, CSStr tag, Object & env, Function & func) + static inline Uint32 EachWhereTagMatches(bool neg, bool cs, CSStr tag, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder @@ -1424,7 +1424,7 @@ public: /* -------------------------------------------------------------------------------------------- * Process all entities of this type where the tag match the specified filter. */ - static inline Uint32 EachWhereTagMatchesData(bool neg, bool cs, CSStr tag, Object & data, Object & env, Function & func) + static inline Uint32 EachWhereTagMatchesData(bool neg, bool cs, CSStr tag, LightObj & data, LightObj & env, Function & func) { SQMOD_VALID_TAG_STR(tag) // Create a new element forwarder diff --git a/source/Base/Shared.hpp b/source/Base/Shared.hpp index 4888407c..4fe6252b 100644 --- a/source/Base/Shared.hpp +++ b/source/Base/Shared.hpp @@ -38,6 +38,11 @@ enum Intersection SQMODI_INSIDE, }; +/* ------------------------------------------------------------------------------------------------ + * Helper used to reference and keep track of signal instances. +*/ +typedef std::pair< Signal *, LightObj > SignalPair; + /* ------------------------------------------------------------------------------------------------ * Forward declarations of the logging functions to avoid including the logger everywhere. * Primary logging functions. @@ -193,6 +198,16 @@ const ULongInt & GetULongInt(); const ULongInt & GetULongInt(Uint64 n); const ULongInt & GetULongInt(CSStr s); +/* ------------------------------------------------------------------------------------------------ + * Initialize a signal instance into the specified pair. +*/ +extern void InitSignalPair(SignalPair & sp, LightObj & et, const char * name); + +/* ------------------------------------------------------------------------------------------------ + * Reset/release the specified signal pair. +*/ +extern void ResetSignalPair(SignalPair & sp, bool clear = true); + /* ------------------------------------------------------------------------------------------------ * A simple implementation of name filtering. */ diff --git a/source/Command.cpp b/source/Command.cpp index 489da976..b73da53f 100644 --- a/source/Command.cpp +++ b/source/Command.cpp @@ -212,7 +212,7 @@ Int32 Controller::Run(const Guard & guard, CCStr command) ++split; } // Are there any arguments specified? - if (split != '\0') + if (*split != '\0') { // Save the command name ctx.mCommand.assign(command, (split - command)); @@ -665,13 +665,13 @@ bool Controller::Parse(Context & ctx) { // Let's us know if the whole argument was part of the resulted value CStr next = nullptr; - // Attempt to extract the integer value from the string + // Attempt to extract the float value from the string #ifdef SQUSEDOUBLE const Float64 value = std::strtod(str, &next); #else const Float32 value = std::strtof(str, &next); #endif // SQUSEDOUBLE - // See if this whole string was indeed an integer + // See if this whole string was indeed an float if (next == end) { // Remember the current stack size diff --git a/source/Core.cpp b/source/Core.cpp index 63be4e16..adc8526a 100644 --- a/source/Core.cpp +++ b/source/Core.cpp @@ -1,6 +1,7 @@ // ------------------------------------------------------------------------------------------------ #include "Core.hpp" #include "Logger.hpp" +#include "Signal.hpp" #include "SqMod.h" // ------------------------------------------------------------------------------------------------ @@ -30,15 +31,6 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { -// -------------------------------------------------------------------------------------------- -#define SQMOD_CATCH_EVENT_EXCEPTION(action) /* -*/ catch (const Sqrat::Exception & e) /* -*/ { /* -*/ LogErr("Squirrel exception caught " action); /* -*/ Logger::Get().Debug("%s", e.what()); /* -*/ } /* -*/ - // ------------------------------------------------------------------------------------------------ extern bool RegisterAPI(HSQUIRRELVM vm); @@ -50,9 +42,6 @@ extern void TerminateRoutines(); extern void TerminateCommands(); extern void TerminateSignals(); -// ------------------------------------------------------------------------------------------------ -extern void CleanupTasks(Int32 id, Int32 type); - // ------------------------------------------------------------------------------------------------ extern Buffer GetRealFilePath(CSStr path); @@ -121,7 +110,7 @@ public: { for (auto & ent : container) { - ent.Destroy(destroy, SQMOD_DESTROY_CLEANUP, NullObject()); + ent.Destroy(destroy, SQMOD_DESTROY_CLEANUP, NullLightObj()); } } @@ -151,6 +140,7 @@ Core::Core() , m_Pickups() , m_Players() , m_Vehicles() + , m_Events() , m_CircularLocks(0) , m_ReloadHeader(0) , m_ReloadPayload() @@ -278,6 +268,7 @@ bool Core::Initialize() NullArray() = Array(); NullTable() = Table(); NullObject() = Object(); + NullLightObj() = LightObj(); NullFunction() = Function(); cLogDbg(m_Verbosity >= 1, "Registering the standard libraries"); @@ -311,6 +302,14 @@ bool Core::Initialize() return false; // Can't execute scripts without a valid API! } + // Initialize the module global events + InitEvents(); + + // Initialize load stage signals + InitSignalPair(mOnPreLoad, NullLightObj(), nullptr); + InitSignalPair(mOnPostLoad, NullLightObj(), nullptr); + InitSignalPair(mOnUnload, NullLightObj(), nullptr); + CSimpleIniA::TNamesDepend scripts; // Attempt to retrieve the list of keys to make sure there's actually something to process if (conf.GetAllKeys("Scripts", scripts) && scripts.size() > 0) @@ -412,34 +411,28 @@ bool Core::Execute() } // Create the null entity instances - m_NullBlip = Object(new CBlip(-1)); - m_NullCheckpoint = Object(new CCheckpoint(-1)); - m_NullKeybind = Object(new CKeybind(-1)); - m_NullObject = Object(new CObject(-1)); - m_NullPickup = Object(new CPickup(-1)); - m_NullPlayer = Object(new CPlayer(-1)); - m_NullVehicle = Object(new CVehicle(-1)); + m_NullBlip = LightObj(new CBlip(-1)); + m_NullCheckpoint = LightObj(new CCheckpoint(-1)); + m_NullKeybind = LightObj(new CKeybind(-1)); + m_NullObject = LightObj(new CObject(-1)); + m_NullPickup = LightObj(new CPickup(-1)); + m_NullPlayer = LightObj(new CPlayer(-1)); + m_NullVehicle = LightObj(new CVehicle(-1)); m_LockPreLoadSignal = true; - // Trigger functions that must initialize stuff before the loaded event is triggered - for (FuncData & fn : m_PreLoadSignal) - { - Emit(fn.first, fn.second); - } - // Clear the functions - m_PreLoadSignal.clear(); + // Trigger callbacks that must initialize stuff before the loaded event is triggered + (*mOnPreLoad.first)(); + // Clear the callbacks + ResetSignalPair(mOnPreLoad); // Notify the script callback that the scripts were loaded EmitScriptLoaded(); m_LockPostLoadSignal = true; - // Trigger functions that must initialize stuff after the loaded event is triggered - for (FuncData & fn : m_PostLoadSignal) - { - Emit(fn.first, fn.second); - } - // Clear the functions - m_PostLoadSignal.clear(); + // Trigger callbacks that must initialize stuff after the loaded event is triggered + (*mOnPostLoad.first)(); + // Clear the callbacks + ResetSignalPair(mOnPostLoad); // Import already existing entities ImportPlayers(); @@ -449,7 +442,6 @@ bool Core::Execute() ImportObjects(); ImportPickups(); ImportVehicles(); - // Successfully executed return (m_Executed = true); } @@ -462,13 +454,10 @@ void Core::Terminate(bool shutdown) if (m_VM) { m_LockUnloadSignal = true; - // Trigger functions that must de-initialize stuff before the scripts are unloaded - for (FuncData & fn : m_UnloadSignal) - { - Emit(fn.first, fn.second, shutdown); - } - // Clear the functions - m_UnloadSignal.clear(); + // Trigger callbacks that must de-initialize stuff before the scripts are unloaded + (*mOnUnload.first)(); + // Clear the callbacks + ResetSignalPair(mOnUnload); cLogDbg(m_Verbosity >= 1, "Signaling outside plug-ins to release their resources"); // Tell modules to do their monkey business @@ -497,6 +486,7 @@ void Core::Terminate(bool shutdown) NullArray().Release(); NullTable().Release(); NullObject().Release(); + NullLightObj().Release(); NullFunction().ReleaseGently(); // Release null entity instances m_NullBlip.Release(); @@ -506,16 +496,12 @@ void Core::Terminate(bool shutdown) m_NullPickup.Release(); m_NullPlayer.Release(); m_NullVehicle.Release(); - // Clear any functions added during shutdown - m_PreLoadSignal.clear(); - m_PostLoadSignal.clear(); - m_UnloadSignal.clear(); // Is there a VM to close? if (m_VM) { cLogDbg(m_Verbosity >= 1, "Releasing any final resources and all loaded scripts"); // Release all script callbacks - ResetFunc(); + DropEvents(); // Release the script instances m_Scripts.clear(); m_PendingScripts.clear(); // Just in case @@ -847,376 +833,4 @@ void Core::CompilerErrorHandler(HSQUIRRELVM /*vm*/, CSStr desc, CSStr src, SQInt LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %d\n=>Column: %d\n]", desc, src, line, column); } -// ------------------------------------------------------------------------------------------------ -void Core::BindPreLoad(Object & env, Function & func, Object & payload) -{ - if (m_LockPreLoadSignal) - { - STHROWF("Cannot bind functions to pre-load signal anymore"); - } - else if (func.IsNull()) - { - STHROWF("Cannot bind null as callback to pre-load signal"); - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - m_PreLoadSignal.emplace_back(func, payload); - } - // Assign the specified environment and function - else - { - m_PreLoadSignal.emplace_back(Function(env.GetVM(), env, func.GetFunc()), payload); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::BindPostLoad(Object & env, Function & func, Object & payload) -{ - if (m_LockPostLoadSignal) - { - STHROWF("Cannot bind functions to post-load signal anymore"); - } - else if (func.IsNull()) - { - STHROWF("Cannot bind null as callback to post-load signal"); - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - m_PostLoadSignal.emplace_back(func, payload); - } - // Assign the specified environment and function - else - { - m_PostLoadSignal.emplace_back(Function(env.GetVM(), env, func.GetFunc()), payload); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::BindUnload(Object & env, Function & func, Object & payload) -{ - if (m_LockUnloadSignal) - { - STHROWF("Cannot bind functions to unload signal anymore"); - } - else if (func.IsNull()) - { - STHROWF("Cannot bind null as callback to unload signal"); - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - m_UnloadSignal.emplace_back(func, payload); - } - // Assign the specified environment and function - else - { - m_UnloadSignal.emplace_back(Function(env.GetVM(), env, func.GetFunc()), payload); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::BindEvent(Int32 id, Object & env, Function & func) -{ - // Obtain the function instance called for this event - Function & event = GetEvent(id); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } -} - -// ------------------------------------------------------------------------------------------------ -void Core::BlipInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitBlipDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying blip") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_BLIP); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->DestroyCoordBlip(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::CheckpointInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitCheckpointDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying checkpoint") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_CHECKPOINT); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->DeleteCheckPoint(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::KeybindInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitKeybindDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying keybind") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_KEYBIND); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->RemoveKeyBind(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ObjectInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitObjectDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying object") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_OBJECT); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->DeleteObject(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::PickupInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitPickupDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying pickup") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_PICKUP); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->DeletePickup(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::PlayerInst::Destroy(bool /*destroy*/, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitPlayerDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying player") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - // Release the used memory buffer - mInst->m_Buffer.ResetAll(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_PLAYER); - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - -// ------------------------------------------------------------------------------------------------ -void Core::VehicleInst::Destroy(bool destroy, Int32 header, Object & payload) -{ - // Should we notify that this entity is being cleaned up? - if (VALID_ENTITY(mID)) - { - // Don't leave exceptions to prevent us from releasing this instance - try - { - Core::Get().EmitVehicleDestroyed(mID, header, payload); - } - SQMOD_CATCH_EVENT_EXCEPTION("while destroying vehicle") - } - // Is there a manager instance associated with this entity? - if (mInst) - { - // Prevent further use of this entity - mInst->m_ID = -1; - // Release user data to avoid dangling or circular references - mInst->m_Data.Release(); - } - // Prevent further use of the manager instance - mInst = nullptr; - // Release the script object, if any - mObj.Release(); - // Release tasks, if any - CleanupTasks(mID, ENT_VEHICLE); - // Are we supposed to clean up this entity? (only at reload) - if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) - { - // Block the entity pool changes notification from triggering the destroy event - const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); - // Now attempt to destroy this entity from the server - _Func->DeleteVehicle(mID); - } - // Reset the instance to it's initial state - Core::ResetInst(*this); - // Don't release the callbacks abruptly - Core::ResetFunc(*this); -} - } // Namespace:: SqMod diff --git a/source/Core.hpp b/source/Core.hpp index 7afe5243..c9d5730b 100644 --- a/source/Core.hpp +++ b/source/Core.hpp @@ -76,7 +76,7 @@ protected: */ BlipInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -86,20 +86,35 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CBlip * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- Int32 mWorld; // The identifier of the world in which this blip was created. @@ -108,13 +123,16 @@ protected: // ---------------------------------------------------------------------------------------- Int32 mSprID; + // ---------------------------------------------------------------------------------------- + LightObj mEvents; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- Vector3 mPosition; Color4 mColor; // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + SignalPair mOnDestroyed; + SignalPair mOnCustom; }; /* -------------------------------------------------------------------------------------------- @@ -127,7 +145,7 @@ protected: */ CheckpointInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -137,30 +155,48 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CCheckpoint * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnEntered; - Function mOnExited; - Function mOnWorld; - Function mOnRadius; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnEntered; + SignalPair mOnExited; + SignalPair mOnWorld; + SignalPair mOnRadius; }; /* -------------------------------------------------------------------------------------------- @@ -173,7 +209,7 @@ protected: */ KeybindInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -183,20 +219,35 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CKeybind * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- Int32 mFirst; // Key-code of the first button from the triggering combination. @@ -205,12 +256,15 @@ protected: Int32 mRelease; // Whether the key-bind reacts to button press or release. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnKeyPress; - Function mOnKeyRelease; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnKeyPress; + SignalPair mOnKeyRelease; }; /* -------------------------------------------------------------------------------------------- @@ -223,7 +277,7 @@ protected: */ ObjectInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -233,31 +287,49 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CObject * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnShot; - Function mOnTouched; - Function mOnWorld; - Function mOnAlpha; - Function mOnReport; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnShot; + SignalPair mOnTouched; + SignalPair mOnWorld; + SignalPair mOnAlpha; + SignalPair mOnReport; }; /* -------------------------------------------------------------------------------------------- @@ -270,7 +342,7 @@ protected: */ PickupInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -280,33 +352,51 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CPickup * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnRespawn; - Function mOnClaimed; - Function mOnCollected; - Function mOnWorld; - Function mOnAlpha; - Function mOnAutomatic; - Function mOnAutoTimer; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnRespawn; + SignalPair mOnClaimed; + SignalPair mOnCollected; + SignalPair mOnWorld; + SignalPair mOnAlpha; + SignalPair mOnAutomatic; + SignalPair mOnAutoTimer; }; /* -------------------------------------------------------------------------------------------- @@ -319,7 +409,7 @@ protected: */ PlayerInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -329,20 +419,35 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(false, SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(false, SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CPlayer * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- SQInteger mTrackPosition; // The number of times to track position changes. @@ -350,11 +455,11 @@ protected: // ---------------------------------------------------------------------------------------- Int32 mTrackPositionHeader; // Header to send when triggering position callback. - Object mTrackPositionPayload; // Payload to send when triggering position callback. + LightObj mTrackPositionPayload; // Payload to send when triggering position callback. // ---------------------------------------------------------------------------------------- Int32 mKickBanHeader; // Header to send when triggering kick/ban callback. - Object mKickBanPayload; // Payload to send when triggering kick/ban callback. + LightObj mKickBanPayload; // Payload to send when triggering kick/ban callback. // ---------------------------------------------------------------------------------------- Int32 mLastWeapon; // Last known weapon of the player entity. @@ -367,79 +472,82 @@ protected: Int32 mAuthority; // The authority level of the managed player. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnRequestClass; - Function mOnRequestSpawn; - Function mOnSpawn; - Function mOnWasted; - Function mOnKilled; - Function mOnEmbarking; - Function mOnEmbarked; - Function mOnDisembark; - Function mOnRename; - Function mOnState; - Function mOnStateNone; - Function mOnStateNormal; - Function mOnStateAim; - Function mOnStateDriver; - Function mOnStatePassenger; - Function mOnStateEnterDriver; - Function mOnStateEnterPassenger; - Function mOnStateExit; - Function mOnStateUnspawned; - Function mOnAction; - Function mOnActionNone; - Function mOnActionNormal; - Function mOnActionAiming; - Function mOnActionShooting; - Function mOnActionJumping; - Function mOnActionLieDown; - Function mOnActionGettingUp; - Function mOnActionJumpVehicle; - Function mOnActionDriving; - Function mOnActionDying; - Function mOnActionWasted; - Function mOnActionEmbarking; - Function mOnActionDisembarking; - Function mOnBurning; - Function mOnCrouching; - Function mOnGameKeys; - Function mOnStartTyping; - Function mOnStopTyping; - Function mOnAway; - Function mOnMessage; - Function mOnCommand; - Function mOnPrivateMessage; - Function mOnKeyPress; - Function mOnKeyRelease; - Function mOnSpectate; - Function mOnCrashreport; - Function mOnObjectShot; - Function mOnObjectTouched; - Function mOnPickupClaimed; - Function mOnPickupCollected; - Function mOnCheckpointEntered; - Function mOnCheckpointExited; - Function mOnClientScriptData; - Function mOnUpdate; - Function mOnHealth; - Function mOnArmour; - Function mOnWeapon; - Function mOnHeading; - Function mOnPosition; - Function mOnOption; - Function mOnAdmin; - Function mOnWorld; - Function mOnTeam; - Function mOnSkin; - Function mOnMoney; - Function mOnScore; - Function mOnWantedLevel; - Function mOnImmunity; - Function mOnAlpha; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnRequestClass; + SignalPair mOnRequestSpawn; + SignalPair mOnSpawn; + SignalPair mOnWasted; + SignalPair mOnKilled; + SignalPair mOnEmbarking; + SignalPair mOnEmbarked; + SignalPair mOnDisembark; + SignalPair mOnRename; + SignalPair mOnState; + SignalPair mOnStateNone; + SignalPair mOnStateNormal; + SignalPair mOnStateAim; + SignalPair mOnStateDriver; + SignalPair mOnStatePassenger; + SignalPair mOnStateEnterDriver; + SignalPair mOnStateEnterPassenger; + SignalPair mOnStateExit; + SignalPair mOnStateUnspawned; + SignalPair mOnAction; + SignalPair mOnActionNone; + SignalPair mOnActionNormal; + SignalPair mOnActionAiming; + SignalPair mOnActionShooting; + SignalPair mOnActionJumping; + SignalPair mOnActionLieDown; + SignalPair mOnActionGettingUp; + SignalPair mOnActionJumpVehicle; + SignalPair mOnActionDriving; + SignalPair mOnActionDying; + SignalPair mOnActionWasted; + SignalPair mOnActionEmbarking; + SignalPair mOnActionDisembarking; + SignalPair mOnBurning; + SignalPair mOnCrouching; + SignalPair mOnGameKeys; + SignalPair mOnStartTyping; + SignalPair mOnStopTyping; + SignalPair mOnAway; + SignalPair mOnMessage; + SignalPair mOnCommand; + SignalPair mOnPrivateMessage; + SignalPair mOnKeyPress; + SignalPair mOnKeyRelease; + SignalPair mOnSpectate; + SignalPair mOnCrashreport; + SignalPair mOnObjectShot; + SignalPair mOnObjectTouched; + SignalPair mOnPickupClaimed; + SignalPair mOnPickupCollected; + SignalPair mOnCheckpointEntered; + SignalPair mOnCheckpointExited; + SignalPair mOnClientScriptData; + SignalPair mOnUpdate; + SignalPair mOnHealth; + SignalPair mOnArmour; + SignalPair mOnWeapon; + SignalPair mOnHeading; + SignalPair mOnPosition; + SignalPair mOnOption; + SignalPair mOnAdmin; + SignalPair mOnWorld; + SignalPair mOnTeam; + SignalPair mOnSkin; + SignalPair mOnMoney; + SignalPair mOnScore; + SignalPair mOnWantedLevel; + SignalPair mOnImmunity; + SignalPair mOnAlpha; }; /* -------------------------------------------------------------------------------------------- @@ -452,7 +560,7 @@ protected: */ VehicleInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) { - Core::Get().ResetInst(*this); + ResetInstance(); } /* ---------------------------------------------------------------------------------------- @@ -462,20 +570,35 @@ protected: { if (VALID_ENTITY(mID)) { - Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject()); + Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullLightObj()); } } /* ---------------------------------------------------------------------------------------- * Destroy the entity instance from the server, if necessary. */ - void Destroy(bool destroy, Int32 header, Object & payload); + void Destroy(bool destroy, Int32 header, LightObj & payload); + + /* ---------------------------------------------------------------------------------------- + * Reset the instance to the default values. + */ + void ResetInstance(); + + /* ---------------------------------------------------------------------------------------- + * Create the associated signals. + */ + void InitEvents(); + + /* ---------------------------------------------------------------------------------------- + * Clear the associated signals. + */ + void DropEvents(); // ---------------------------------------------------------------------------------------- Int32 mID; // The unique number that identifies this entity on the server. Uint16 mFlags; // Various options and states that can be toggled on the instance. CVehicle * mInst; // Pointer to the actual instance used to interact this entity. - Object mObj; // Script object of the instance used to interact this entity. + LightObj mObj; // Script object of the instance used to interact this entity. // ---------------------------------------------------------------------------------------- SQInteger mTrackPosition; // The number of times to track position changes. @@ -489,28 +612,31 @@ protected: Quaternion mLastRotation; // Last known rotation of the player entity. // ---------------------------------------------------------------------------------------- - Function mOnDestroyed; - Function mOnCustom; + LightObj mEvents; // Table containing the emitted entity events. // ---------------------------------------------------------------------------------------- - Function mOnEmbarking; - Function mOnEmbarked; - Function mOnDisembark; - Function mOnExplode; - Function mOnRespawn; - Function mOnUpdate; - Function mOnColor; - Function mOnHealth; - Function mOnPosition; - Function mOnRotation; - Function mOnOption; - Function mOnWorld; - Function mOnImmunity; - Function mOnPartStatus; - Function mOnTyreStatus; - Function mOnDamageData; - Function mOnRadio; - Function mOnHandlingRule; + SignalPair mOnDestroyed; + SignalPair mOnCustom; + + // ---------------------------------------------------------------------------------------- + SignalPair mOnEmbarking; + SignalPair mOnEmbarked; + SignalPair mOnDisembark; + SignalPair mOnExplode; + SignalPair mOnRespawn; + SignalPair mOnUpdate; + SignalPair mOnColor; + SignalPair mOnHealth; + SignalPair mOnPosition; + SignalPair mOnRotation; + SignalPair mOnOption; + SignalPair mOnWorld; + SignalPair mOnImmunity; + SignalPair mOnPartStatus; + SignalPair mOnTyreStatus; + SignalPair mOnDamageData; + SignalPair mOnRadio; + SignalPair mOnHandlingRule; }; public: @@ -526,9 +652,6 @@ public: // -------------------------------------------------------------------------------------------- typedef std::vector< ScriptSrc > Scripts; // List of loaded scripts. - typedef std::pair< Function, Object > FuncData; // Data about a function to be called. - typedef std::vector< FuncData > Functions; // List of functions to execute. - // -------------------------------------------------------------------------------------------- typedef std::unordered_map< String, String > Options; // List of custom options. @@ -550,12 +673,15 @@ private: Players m_Players; // Players pool. Vehicles m_Vehicles; // Vehicles pool. + // -------------------------------------------------------------------------------------------- + LightObj m_Events; // Table containing the emitted module events. + // -------------------------------------------------------------------------------------------- Uint32 m_CircularLocks; // Prevent events from triggering themselves. // -------------------------------------------------------------------------------------------- Int32 m_ReloadHeader; // The specified reload header. - Object m_ReloadPayload; // The specified reload payload. + LightObj m_ReloadPayload; // The specified reload payload. // -------------------------------------------------------------------------------------------- CStr m_IncomingNameBuffer; // Name of an incoming connection. @@ -574,18 +700,13 @@ private: Int32 m_Verbosity; // Restrict the amount of outputted information. // -------------------------------------------------------------------------------------------- - Functions m_PreLoadSignal; // Functions to call before the loaded event. - Functions m_PostLoadSignal; // Functions to call after the loaded event. - Functions m_UnloadSignal; // Functions to call before unloading scripts. - - // -------------------------------------------------------------------------------------------- - Object m_NullBlip; // Null Blips instance. - Object m_NullCheckpoint; // Null Checkpoints instance. - Object m_NullKeybind; // Null Key-instance pool. - Object m_NullObject; // Null Objects instance. - Object m_NullPickup; // Null Pickups instance. - Object m_NullPlayer; // Null Players instance. - Object m_NullVehicle; // Null Vehicles instance. + LightObj m_NullBlip; // Null Blips instance. + LightObj m_NullCheckpoint; // Null Checkpoints instance. + LightObj m_NullKeybind; // Null Key-instance pool. + LightObj m_NullObject; // Null Objects instance. + LightObj m_NullPickup; // Null Pickups instance. + LightObj m_NullPlayer; // Null Players instance. + LightObj m_NullVehicle; // Null Vehicles instance. public: @@ -680,6 +801,14 @@ public: return m_VM; } + /* -------------------------------------------------------------------------------------------- + * Retrieve the global events table. + */ + LightObj & GetEvents() + { + return m_Events; + } + /* -------------------------------------------------------------------------------------------- * Retrieve the circular locks. */ @@ -699,7 +828,7 @@ public: /* -------------------------------------------------------------------------------------------- * Set the header and payload for the reload. */ - void SetReloadInfo(Int32 header, Object & payload) + void SetReloadInfo(Int32 header, LightObj & payload) { m_ReloadHeader = header; m_ReloadPayload = payload; @@ -725,7 +854,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the specified reload header. */ - Object & GetReloadPayload() + LightObj & GetReloadPayload() { return m_ReloadPayload; } @@ -782,67 +911,67 @@ protected: /* -------------------------------------------------------------------------------------------- * Entity allocators. */ - BlipInst & AllocBlip(Int32 id, bool owned, Int32 header, Object & payload); - CheckpointInst & AllocCheckpoint(Int32 id, bool owned, Int32 header, Object & payload); - KeybindInst & AllocKeybind(Int32 id, bool owned, Int32 header, Object & payload); - ObjectInst & AllocObject(Int32 id, bool owned, Int32 header, Object & payload); - PickupInst & AllocPickup(Int32 id, bool owned, Int32 header, Object & payload); - VehicleInst & AllocVehicle(Int32 id, bool owned, Int32 header, Object & payload); + BlipInst & AllocBlip(Int32 id, bool owned, Int32 header, LightObj & payload); + CheckpointInst & AllocCheckpoint(Int32 id, bool owned, Int32 header, LightObj & payload); + KeybindInst & AllocKeybind(Int32 id, bool owned, Int32 header, LightObj & payload); + ObjectInst & AllocObject(Int32 id, bool owned, Int32 header, LightObj & payload); + PickupInst & AllocPickup(Int32 id, bool owned, Int32 header, LightObj & payload); + VehicleInst & AllocVehicle(Int32 id, bool owned, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Entity deallocator. */ - void DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload); - void DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload); + void DeallocBlip(Int32 id, bool destroy, Int32 header, LightObj & payload); + void DeallocCheckpoint(Int32 id, bool destroy, Int32 header, LightObj & payload); + void DeallocKeybind(Int32 id, bool destroy, Int32 header, LightObj & payload); + void DeallocObject(Int32 id, bool destroy, Int32 header, LightObj & payload); + void DeallocPickup(Int32 id, bool destroy, Int32 header, LightObj & payload); + void DeallocVehicle(Int32 id, bool destroy, Int32 header, LightObj & payload); public: /* -------------------------------------------------------------------------------------------- * Entity creators. */ - Object & NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, + LightObj & NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint32 color, Int32 sprid, - Int32 header, Object & payload); + Int32 header, LightObj & payload); - Object & NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, + LightObj & NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload); + Int32 header, LightObj & payload); - Object & NewKeybind(Int32 slot, bool release, + LightObj & NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, - Int32 header, Object & payload); + Int32 header, LightObj & payload); - Object & NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, - Int32 alpha, Int32 header, Object & payload); + LightObj & NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, + Int32 alpha, Int32 header, LightObj & payload); - Object & NewPickup(Int32 model, Int32 world, Int32 quantity, + LightObj & NewPickup(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, - Int32 header, Object & payload); + Int32 header, LightObj & payload); - Object & NewSprite(Int32 index, CSStr file, Int32 xp, Int32 yp, + LightObj & NewSprite(Int32 index, CSStr file, Int32 xp, Int32 yp, Int32 xr, Int32 yr, Float32 angle, Int32 alpha, bool rel, - Int32 header, Object & payload); + Int32 header, LightObj & payload); - Object & NewTextdraw(Int32 index, CSStr text, Int32 xp, Int32 yp, - Uint32 color, bool rel, Int32 header, Object & payload); + LightObj & NewTextdraw(Int32 index, CSStr text, Int32 xp, Int32 yp, + Uint32 color, bool rel, Int32 header, LightObj & payload); - Object & NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, + LightObj & NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, Int32 primary, Int32 secondary, - Int32 header, Object & payload); + Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Entity destroyers. */ - bool DelBlip(Int32 id, Int32 header, Object & payload); - bool DelCheckpoint(Int32 id, Int32 header, Object & payload); - bool DelKeybind(Int32 id, Int32 header, Object & payload); - bool DelObject(Int32 id, Int32 header, Object & payload); - bool DelPickup(Int32 id, Int32 header, Object & payload); - bool DelVehicle(Int32 id, Int32 header, Object & payload); + bool DelBlip(Int32 id, Int32 header, LightObj & payload); + bool DelCheckpoint(Int32 id, Int32 header, LightObj & payload); + bool DelKeybind(Int32 id, Int32 header, LightObj & payload); + bool DelObject(Int32 id, Int32 header, LightObj & payload); + bool DelPickup(Int32 id, Int32 header, LightObj & payload); + bool DelVehicle(Int32 id, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Entity retrievers. @@ -869,13 +998,13 @@ public: /* -------------------------------------------------------------------------------------------- * Null instance retrievers. */ - Object & GetNullBlip() { return m_NullBlip; } - Object & GetNullCheckpoint() { return m_NullCheckpoint; } - Object & GetNullKeybind() { return m_NullKeybind; } - Object & GetNullObject() { return m_NullObject; } - Object & GetNullPickup() { return m_NullPickup; } - Object & GetNullPlayer() { return m_NullPlayer; } - Object & GetNullVehicle() { return m_NullVehicle; } + LightObj & GetNullBlip() { return m_NullBlip; } + LightObj & GetNullCheckpoint() { return m_NullCheckpoint; } + LightObj & GetNullKeybind() { return m_NullKeybind; } + LightObj & GetNullObject() { return m_NullObject; } + LightObj & GetNullPickup() { return m_NullPickup; } + LightObj & GetNullPlayer() { return m_NullPlayer; } + LightObj & GetNullVehicle() { return m_NullVehicle; } /* -------------------------------------------------------------------------------------------- * Container cleaner. @@ -885,103 +1014,48 @@ public: protected: /* -------------------------------------------------------------------------------------------- - * Instance cleaners. + * Signal initialization and termination. */ - static void ResetInst(BlipInst & inst); - static void ResetInst(CheckpointInst & inst); - static void ResetInst(KeybindInst & inst); - static void ResetInst(ObjectInst & inst); - static void ResetInst(PickupInst & inst); - static void ResetInst(PlayerInst & inst); - static void ResetInst(VehicleInst & inst); - - /* -------------------------------------------------------------------------------------------- - * Bindings cleaners. - */ - static void ResetFunc(BlipInst & inst); - static void ResetFunc(CheckpointInst & inst); - static void ResetFunc(KeybindInst & inst); - static void ResetFunc(ObjectInst & inst); - static void ResetFunc(PickupInst & inst); - static void ResetFunc(PlayerInst & inst); - static void ResetFunc(VehicleInst & inst); - static void ResetFunc(); - - // -------------------------------------------------------------------------------------------- - static void Emit(Function & func) - { - if (!func.IsNull()) - { - func.Execute(); - } - } - - // -------------------------------------------------------------------------------------------- - template < typename... Args > static void Emit(Function & func, Args&&... args) - { - if (!func.IsNull()) - { - func.Execute(std::forward< Args >(args)...); - } - } + void InitEvents(); + void DropEvents(); public: - /* -------------------------------------------------------------------------------------------- - * Pre load signal binder. - */ - void BindPreLoad(Object & env, Function & func, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Post load signal binder. - */ - void BindPostLoad(Object & env, Function & func, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Unload signal binder. - */ - void BindUnload(Object & env, Function & func, Object & payload); - - /* -------------------------------------------------------------------------------------------- - * Global event binder. - */ - void BindEvent(Int32 id, Object & env, Function & func); - /* -------------------------------------------------------------------------------------------- * Player lifetime management. */ - void ConnectPlayer(Int32 id, Int32 header, Object & payload); - void DisconnectPlayer(Int32 id, Int32 header, Object & payload); + void ConnectPlayer(Int32 id, Int32 header, LightObj & payload); + void DisconnectPlayer(Int32 id, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Emit a custom event. */ - void EmitCustomEvent(Int32 group, Int32 header, Object & payload); + void EmitCustomEvent(Int32 group, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Server events. */ - void EmitBlipCreated(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointCreated(Int32 forcefield, Int32 header, Object & payload); - void EmitKeybindCreated(Int32 keybind, Int32 header, Object & payload); - void EmitObjectCreated(Int32 object, Int32 header, Object & payload); - void EmitPickupCreated(Int32 pickup, Int32 header, Object & payload); - void EmitPlayerCreated(Int32 player, Int32 header, Object & payload); - void EmitVehicleCreated(Int32 vehicle, Int32 header, Object & payload); - void EmitBlipDestroyed(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointDestroyed(Int32 forcefield, Int32 header, Object & payload); - void EmitKeybindDestroyed(Int32 keybind, Int32 header, Object & payload); - void EmitObjectDestroyed(Int32 object, Int32 header, Object & payload); - void EmitPickupDestroyed(Int32 pickup, Int32 header, Object & payload); - void EmitPlayerDestroyed(Int32 player, Int32 header, Object & payload); - void EmitVehicleDestroyed(Int32 vehicle, Int32 header, Object & payload); - void EmitBlipCustom(Int32 blip, Int32 header, Object & payload); - void EmitCheckpointCustom(Int32 forcefield, Int32 header, Object & payload); - void EmitKeybindCustom(Int32 keybind, Int32 header, Object & payload); - void EmitObjectCustom(Int32 object, Int32 header, Object & payload); - void EmitPickupCustom(Int32 pickup, Int32 header, Object & payload); - void EmitPlayerCustom(Int32 player, Int32 header, Object & payload); - void EmitVehicleCustom(Int32 vehicle, Int32 header, Object & payload); + void EmitBlipCreated(Int32 blip, Int32 header, LightObj & payload); + void EmitCheckpointCreated(Int32 forcefield, Int32 header, LightObj & payload); + void EmitKeybindCreated(Int32 keybind, Int32 header, LightObj & payload); + void EmitObjectCreated(Int32 object, Int32 header, LightObj & payload); + void EmitPickupCreated(Int32 pickup, Int32 header, LightObj & payload); + void EmitPlayerCreated(Int32 player, Int32 header, LightObj & payload); + void EmitVehicleCreated(Int32 vehicle, Int32 header, LightObj & payload); + void EmitBlipDestroyed(Int32 blip, Int32 header, LightObj & payload); + void EmitCheckpointDestroyed(Int32 forcefield, Int32 header, LightObj & payload); + void EmitKeybindDestroyed(Int32 keybind, Int32 header, LightObj & payload); + void EmitObjectDestroyed(Int32 object, Int32 header, LightObj & payload); + void EmitPickupDestroyed(Int32 pickup, Int32 header, LightObj & payload); + void EmitPlayerDestroyed(Int32 player, Int32 header, LightObj & payload); + void EmitVehicleDestroyed(Int32 vehicle, Int32 header, LightObj & payload); + void EmitBlipCustom(Int32 blip, Int32 header, LightObj & payload); + void EmitCheckpointCustom(Int32 forcefield, Int32 header, LightObj & payload); + void EmitKeybindCustom(Int32 keybind, Int32 header, LightObj & payload); + void EmitObjectCustom(Int32 object, Int32 header, LightObj & payload); + void EmitPickupCustom(Int32 pickup, Int32 header, LightObj & payload); + void EmitPlayerCustom(Int32 player, Int32 header, LightObj & payload); + void EmitVehicleCustom(Int32 vehicle, Int32 header, LightObj & payload); void EmitServerStartup(); void EmitServerShutdown(); void EmitServerFrame(Float32 elapsed_time); @@ -1060,7 +1134,7 @@ public: void EmitPlayerWeapon(Int32 player_id, Int32 old_weapon, Int32 new_weapon); void EmitPlayerHeading(Int32 player_id, Float32 old_heading, Float32 new_heading); void EmitPlayerPosition(Int32 player_id); - void EmitPlayerOption(Int32 player_id, Int32 option_id, bool value, Int32 header, Object & payload); + void EmitPlayerOption(Int32 player_id, Int32 option_id, bool value, Int32 header, LightObj & payload); void EmitPlayerAdmin(Int32 player_id, bool old_status, bool new_status); void EmitPlayerWorld(Int32 player_id, Int32 old_world, Int32 new_world, bool secondary); void EmitPlayerTeam(Int32 player_id, Int32 old_team, Int32 new_team); @@ -1074,7 +1148,7 @@ public: void EmitVehicleHealth(Int32 vehicle_id, Float32 old_health, Float32 new_health); void EmitVehiclePosition(Int32 vehicle_id); void EmitVehicleRotation(Int32 vehicle_id); - void EmitVehicleOption(Int32 vehicle_id, Int32 option_id, bool value, Int32 header, Object & payload); + void EmitVehicleOption(Int32 vehicle_id, Int32 option_id, bool value, Int32 header, LightObj & payload); void EmitVehicleWorld(Int32 vehicle_id, Int32 old_world, Int32 new_world); void EmitVehicleImmunity(Int32 vehicle_id, Int32 old_immunity, Int32 new_immunity); void EmitVehiclePartStatus(Int32 vehicle_id, Int32 part, Int32 old_status, Int32 new_status); @@ -1082,8 +1156,8 @@ public: void EmitVehicleDamageData(Int32 vehicle_id, Uint32 old_data, Uint32 new_data); void EmitVehicleRadio(Int32 vehicle_id, Int32 old_radio, Int32 new_radio); void EmitVehicleHandlingRule(Int32 vehicle_id, Int32 rule, Float32 old_data, Float32 new_data); - void EmitServerOption(Int32 option, bool value, Int32 header, Object & payload); - void EmitScriptReload(Int32 header, Object & payload); + void EmitServerOption(Int32 option, bool value, Int32 header, LightObj & payload); + void EmitScriptReload(Int32 header, LightObj & payload); void EmitScriptLoaded(); /* -------------------------------------------------------------------------------------------- @@ -1102,151 +1176,142 @@ public: */ void EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t size); - /* -------------------------------------------------------------------------------------------- - * Retrieve global event bindings. - */ - Function & GetEvent(Int32 evid); +public: /* -------------------------------------------------------------------------------------------- - * Retrieve local event bindings. + * Module signals. */ - Function & GetBlipEvent(Int32 id, Int32 evid); - Function & GetCheckpointEvent(Int32 id, Int32 evid); - Function & GetKeybindEvent(Int32 id, Int32 evid); - Function & GetObjectEvent(Int32 id, Int32 evid); - Function & GetPickupEvent(Int32 id, Int32 evid); - Function & GetPlayerEvent(Int32 id, Int32 evid); - Function & GetVehicleEvent(Int32 id, Int32 evid); - -private: + SignalPair mOnPreLoad; + SignalPair mOnPostLoad; + SignalPair mOnUnload; /* -------------------------------------------------------------------------------------------- - * Global event bindings. + * Server signals. */ - Function mOnCustomEvent; - Function mOnBlipCreated; - Function mOnCheckpointCreated; - Function mOnKeybindCreated; - Function mOnObjectCreated; - Function mOnPickupCreated; - Function mOnPlayerCreated; - Function mOnVehicleCreated; - Function mOnBlipDestroyed; - Function mOnCheckpointDestroyed; - Function mOnKeybindDestroyed; - Function mOnObjectDestroyed; - Function mOnPickupDestroyed; - Function mOnPlayerDestroyed; - Function mOnVehicleDestroyed; - Function mOnBlipCustom; - Function mOnCheckpointCustom; - Function mOnKeybindCustom; - Function mOnObjectCustom; - Function mOnPickupCustom; - Function mOnPlayerCustom; - Function mOnVehicleCustom; - Function mOnServerStartup; - Function mOnServerShutdown; - Function mOnServerFrame; - Function mOnIncomingConnection; - Function mOnPlayerRequestClass; - Function mOnPlayerRequestSpawn; - Function mOnPlayerSpawn; - Function mOnPlayerWasted; - Function mOnPlayerKilled; - Function mOnPlayerEmbarking; - Function mOnPlayerEmbarked; - Function mOnPlayerDisembark; - Function mOnPlayerRename; - Function mOnPlayerState; - Function mOnStateNone; - Function mOnStateNormal; - Function mOnStateAim; - Function mOnStateDriver; - Function mOnStatePassenger; - Function mOnStateEnterDriver; - Function mOnStateEnterPassenger; - Function mOnStateExit; - Function mOnStateUnspawned; - Function mOnPlayerAction; - Function mOnActionNone; - Function mOnActionNormal; - Function mOnActionAiming; - Function mOnActionShooting; - Function mOnActionJumping; - Function mOnActionLieDown; - Function mOnActionGettingUp; - Function mOnActionJumpVehicle; - Function mOnActionDriving; - Function mOnActionDying; - Function mOnActionWasted; - Function mOnActionEmbarking; - Function mOnActionDisembarking; - Function mOnPlayerBurning; - Function mOnPlayerCrouching; - Function mOnPlayerGameKeys; - Function mOnPlayerStartTyping; - Function mOnPlayerStopTyping; - Function mOnPlayerAway; - Function mOnPlayerMessage; - Function mOnPlayerCommand; - Function mOnPlayerPrivateMessage; - Function mOnPlayerKeyPress; - Function mOnPlayerKeyRelease; - Function mOnPlayerSpectate; - Function mOnPlayerCrashreport; - Function mOnVehicleExplode; - Function mOnVehicleRespawn; - Function mOnObjectShot; - Function mOnObjectTouched; - Function mOnObjectWorld; - Function mOnObjectAlpha; - Function mOnObjectReport; - Function mOnPickupClaimed; - Function mOnPickupCollected; - Function mOnPickupRespawn; - Function mOnPickupWorld; - Function mOnPickupAlpha; - Function mOnPickupAutomatic; - Function mOnPickupAutoTimer; - Function mOnCheckpointEntered; - Function mOnCheckpointExited; - Function mOnCheckpointWorld; - Function mOnCheckpointRadius; - Function mOnEntityPool; - Function mOnClientScriptData; - Function mOnPlayerUpdate; - Function mOnVehicleUpdate; - Function mOnPlayerHealth; - Function mOnPlayerArmour; - Function mOnPlayerWeapon; - Function mOnPlayerHeading; - Function mOnPlayerPosition; - Function mOnPlayerOption; - Function mOnPlayerAdmin; - Function mOnPlayerWorld; - Function mOnPlayerTeam; - Function mOnPlayerSkin; - Function mOnPlayerMoney; - Function mOnPlayerScore; - Function mOnPlayerWantedLevel; - Function mOnPlayerImmunity; - Function mOnPlayerAlpha; - Function mOnVehicleColor; - Function mOnVehicleHealth; - Function mOnVehiclePosition; - Function mOnVehicleRotation; - Function mOnVehicleOption; - Function mOnVehicleWorld; - Function mOnVehicleImmunity; - Function mOnVehiclePartStatus; - Function mOnVehicleTyreStatus; - Function mOnVehicleDamageData; - Function mOnVehicleRadio; - Function mOnVehicleHandlingRule; - Function mOnServerOption; - Function mOnScriptReload; - Function mOnScriptLoaded; + SignalPair mOnCustomEvent; + SignalPair mOnBlipCreated; + SignalPair mOnCheckpointCreated; + SignalPair mOnKeybindCreated; + SignalPair mOnObjectCreated; + SignalPair mOnPickupCreated; + SignalPair mOnPlayerCreated; + SignalPair mOnVehicleCreated; + SignalPair mOnBlipDestroyed; + SignalPair mOnCheckpointDestroyed; + SignalPair mOnKeybindDestroyed; + SignalPair mOnObjectDestroyed; + SignalPair mOnPickupDestroyed; + SignalPair mOnPlayerDestroyed; + SignalPair mOnVehicleDestroyed; + SignalPair mOnBlipCustom; + SignalPair mOnCheckpointCustom; + SignalPair mOnKeybindCustom; + SignalPair mOnObjectCustom; + SignalPair mOnPickupCustom; + SignalPair mOnPlayerCustom; + SignalPair mOnVehicleCustom; + SignalPair mOnServerStartup; + SignalPair mOnServerShutdown; + SignalPair mOnServerFrame; + SignalPair mOnIncomingConnection; + SignalPair mOnPlayerRequestClass; + SignalPair mOnPlayerRequestSpawn; + SignalPair mOnPlayerSpawn; + SignalPair mOnPlayerWasted; + SignalPair mOnPlayerKilled; + SignalPair mOnPlayerEmbarking; + SignalPair mOnPlayerEmbarked; + SignalPair mOnPlayerDisembark; + SignalPair mOnPlayerRename; + SignalPair mOnPlayerState; + SignalPair mOnStateNone; + SignalPair mOnStateNormal; + SignalPair mOnStateAim; + SignalPair mOnStateDriver; + SignalPair mOnStatePassenger; + SignalPair mOnStateEnterDriver; + SignalPair mOnStateEnterPassenger; + SignalPair mOnStateExit; + SignalPair mOnStateUnspawned; + SignalPair mOnPlayerAction; + SignalPair mOnActionNone; + SignalPair mOnActionNormal; + SignalPair mOnActionAiming; + SignalPair mOnActionShooting; + SignalPair mOnActionJumping; + SignalPair mOnActionLieDown; + SignalPair mOnActionGettingUp; + SignalPair mOnActionJumpVehicle; + SignalPair mOnActionDriving; + SignalPair mOnActionDying; + SignalPair mOnActionWasted; + SignalPair mOnActionEmbarking; + SignalPair mOnActionDisembarking; + SignalPair mOnPlayerBurning; + SignalPair mOnPlayerCrouching; + SignalPair mOnPlayerGameKeys; + SignalPair mOnPlayerStartTyping; + SignalPair mOnPlayerStopTyping; + SignalPair mOnPlayerAway; + SignalPair mOnPlayerMessage; + SignalPair mOnPlayerCommand; + SignalPair mOnPlayerPrivateMessage; + SignalPair mOnPlayerKeyPress; + SignalPair mOnPlayerKeyRelease; + SignalPair mOnPlayerSpectate; + SignalPair mOnPlayerCrashreport; + SignalPair mOnVehicleExplode; + SignalPair mOnVehicleRespawn; + SignalPair mOnObjectShot; + SignalPair mOnObjectTouched; + SignalPair mOnObjectWorld; + SignalPair mOnObjectAlpha; + SignalPair mOnObjectReport; + SignalPair mOnPickupClaimed; + SignalPair mOnPickupCollected; + SignalPair mOnPickupRespawn; + SignalPair mOnPickupWorld; + SignalPair mOnPickupAlpha; + SignalPair mOnPickupAutomatic; + SignalPair mOnPickupAutoTimer; + SignalPair mOnCheckpointEntered; + SignalPair mOnCheckpointExited; + SignalPair mOnCheckpointWorld; + SignalPair mOnCheckpointRadius; + SignalPair mOnEntityPool; + SignalPair mOnClientScriptData; + SignalPair mOnPlayerUpdate; + SignalPair mOnVehicleUpdate; + SignalPair mOnPlayerHealth; + SignalPair mOnPlayerArmour; + SignalPair mOnPlayerWeapon; + SignalPair mOnPlayerHeading; + SignalPair mOnPlayerPosition; + SignalPair mOnPlayerOption; + SignalPair mOnPlayerAdmin; + SignalPair mOnPlayerWorld; + SignalPair mOnPlayerTeam; + SignalPair mOnPlayerSkin; + SignalPair mOnPlayerMoney; + SignalPair mOnPlayerScore; + SignalPair mOnPlayerWantedLevel; + SignalPair mOnPlayerImmunity; + SignalPair mOnPlayerAlpha; + SignalPair mOnVehicleColor; + SignalPair mOnVehicleHealth; + SignalPair mOnVehiclePosition; + SignalPair mOnVehicleRotation; + SignalPair mOnVehicleOption; + SignalPair mOnVehicleWorld; + SignalPair mOnVehicleImmunity; + SignalPair mOnVehiclePartStatus; + SignalPair mOnVehicleTyreStatus; + SignalPair mOnVehicleDamageData; + SignalPair mOnVehicleRadio; + SignalPair mOnVehicleHandlingRule; + SignalPair mOnServerOption; + SignalPair mOnScriptReload; + SignalPair mOnScriptLoaded; }; } // Namespace:: SqMod diff --git a/source/CoreEntity.cpp b/source/CoreEntity.cpp index f9c9bdc8..6c04c82e 100644 --- a/source/CoreEntity.cpp +++ b/source/CoreEntity.cpp @@ -34,7 +34,7 @@ void Core::ImportBlips() m_Blips[i].mPosition.SetVector3Ex(x, y, z); m_Blips[i].mColor.SetRGBA(color); // Attempt to allocate the instance - AllocBlip(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocBlip(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -47,7 +47,7 @@ void Core::ImportCheckpoints() // See if this entity exists on the server and whether was not allocated already if (_Func->CheckEntityExists(vcmpEntityPoolCheckPoint, i) && INVALID_ENTITY(m_Checkpoints[i].mID)) { - AllocCheckpoint(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocCheckpoint(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -55,6 +55,12 @@ void Core::ImportCheckpoints() // ------------------------------------------------------------------------------------------------ void Core::ImportKeybinds() { + /* @NOTE This function is disabled because VC:MP server seems bugged + * and does not return vcmpErrorNoSuchEntity when the keybind does not exist. + * Therefore causing incorrect behavior in the plugin. + */ + return; + // Information about the key-bind entity Uint8 release = 0; Int32 first = -1, second = -1, third = -1; @@ -71,7 +77,7 @@ void Core::ImportKeybinds() m_Keybinds[i].mThird = third; m_Keybinds[i].mRelease = release; // Attempt to allocate the instance - AllocKeybind(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocKeybind(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -84,7 +90,7 @@ void Core::ImportObjects() // See if this entity exists on the server and whether was not allocated already if (_Func->CheckEntityExists(vcmpEntityPoolObject, i) && INVALID_ENTITY(m_Objects[i].mID)) { - AllocObject(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocObject(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -97,7 +103,7 @@ void Core::ImportPickups() // See if this entity exists on the server and whether was not allocated already if (_Func->CheckEntityExists(vcmpEntityPoolPickup, i) && (INVALID_ENTITY(m_Pickups[i].mID))) { - AllocPickup(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocPickup(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -110,7 +116,7 @@ void Core::ImportPlayers() // See if this entity exists on the server and whether was not allocated already if (_Func->IsPlayerConnected(i) && (INVALID_ENTITY(m_Players[i].mID))) { - ConnectPlayer(i, SQMOD_CREATE_IMPORT, NullObject()); + ConnectPlayer(i, SQMOD_CREATE_IMPORT, NullLightObj()); } } } @@ -123,13 +129,13 @@ void Core::ImportVehicles() // See if this entity exists on the server and whether was not allocated already if (_Func->CheckEntityExists(vcmpEntityPoolVehicle, i) && INVALID_ENTITY(m_Vehicles[i].mID)) { - AllocVehicle(i, false, SQMOD_CREATE_IMPORT, NullObject()); + AllocVehicle(i, false, SQMOD_CREATE_IMPORT, NullLightObj()); } } } // -------------------------------------------------------------------------------------------- -Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & payload) +Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) @@ -144,13 +150,17 @@ Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & pa return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CBlip(id); + DeleteGuard< CBlip > dg(new CBlip(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a blip instance for: %d", id); } @@ -165,6 +175,8 @@ Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & pa { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitBlipCreated(id, header, payload); // Return the allocated instance @@ -172,7 +184,7 @@ Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, Object & pa } // -------------------------------------------------------------------------------------------- -Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, Object & payload) +Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) @@ -187,13 +199,17 @@ Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CCheckpoint(id); + DeleteGuard< CCheckpoint > dg(new CCheckpoint(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a checkpoint instance for: %d", id); } @@ -208,6 +224,8 @@ Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitCheckpointCreated(id, header, payload); // Return the allocated instance @@ -215,7 +233,7 @@ Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, } // -------------------------------------------------------------------------------------------- -Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Object & payload) +Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) @@ -230,13 +248,17 @@ Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Objec return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CKeybind(id); + DeleteGuard< CKeybind > dg(new CKeybind(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a keybind instance for: %d", id); } @@ -251,6 +273,8 @@ Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Objec { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitKeybindCreated(id, header, payload); // Return the allocated instance @@ -258,7 +282,7 @@ Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, Objec } // -------------------------------------------------------------------------------------------- -Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, Object & payload) +Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) @@ -273,13 +297,17 @@ Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, Object return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CObject(id); + DeleteGuard< CObject > dg(new CObject(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a object instance for: %d", id); } @@ -294,6 +322,8 @@ Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, Object { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitObjectCreated(id, header, payload); // Return the allocated instance @@ -301,7 +331,7 @@ Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, Object } // -------------------------------------------------------------------------------------------- -Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object & payload) +Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) @@ -316,13 +346,17 @@ Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CPickup(id); + DeleteGuard< CPickup > dg(new CPickup(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a pickup instance for: %d", id); } @@ -337,6 +371,8 @@ Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitPickupCreated(id, header, payload); // Return the allocated instance @@ -344,7 +380,7 @@ Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, Object } // -------------------------------------------------------------------------------------------- -Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Object & payload) +Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) @@ -359,13 +395,17 @@ Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Objec return inst; // Return the existing instance } // Instantiate the entity manager - inst.mInst = new CVehicle(id); + DeleteGuard< CVehicle > dg(new CVehicle(id)); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); + // Store the manager instance itself + inst.mInst = dg.Get(); + // The instance is now managed by the script + dg.Release(); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); // Now we can throw the error STHROWF("Unable to create a vehicle instance for: %d", id); } @@ -380,6 +420,8 @@ Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Objec { inst.mFlags ^= ENF_OWNED; } + // Initialize the instance events + inst.InitEvents(); // Let the script callbacks know about this entity EmitVehicleCreated(id, header, payload); // Return the allocated instance @@ -387,7 +429,7 @@ Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, Objec } // -------------------------------------------------------------------------------------------- -void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) @@ -404,7 +446,7 @@ void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload) } // -------------------------------------------------------------------------------------------- -void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) @@ -421,7 +463,7 @@ void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payl } // -------------------------------------------------------------------------------------------- -void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) @@ -438,7 +480,7 @@ void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload } // -------------------------------------------------------------------------------------------- -void Core::DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocObject(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) @@ -455,7 +497,7 @@ void Core::DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload) } // -------------------------------------------------------------------------------------------- -void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) @@ -472,7 +514,7 @@ void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload) } // -------------------------------------------------------------------------------------------- -void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload) +void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) @@ -489,9 +531,9 @@ void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload } // -------------------------------------------------------------------------------------------- -Object & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, +LightObj & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint32 color, Int32 sprid, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { // Request the server to create this entity const Int32 id = _Func->CreateCoordBlip(index, world, x, y, z, scale, color, sprid); @@ -517,9 +559,9 @@ Object & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z } // -------------------------------------------------------------------------------------------- -Object & Core::NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, +LightObj & Core::NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { // Request the server to create this entity const Int32 id = _Func->CreateCheckPoint(player, world, sphere, x, y, z, r, g, b, a, radius); @@ -549,8 +591,8 @@ Object & Core::NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, } // -------------------------------------------------------------------------------------------- -Object & Core::NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, - Int32 header, Object & payload) +LightObj & Core::NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative, + Int32 header, LightObj & payload) { // Should we obtain a new keybind slot automatically? if (slot < 0) @@ -581,8 +623,8 @@ Object & Core::NewKeybind(Int32 slot, bool release, Int32 primary, Int32 seconda } // -------------------------------------------------------------------------------------------- -Object & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha, - Int32 header, Object & payload) +LightObj & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha, + Int32 header, LightObj & payload) { // Request the server to create this entity const Int32 id = _Func->CreateObject(model, world, x, y, z, alpha); @@ -608,9 +650,9 @@ Object & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 } // -------------------------------------------------------------------------------------------- -Object & Core::NewPickup(Int32 model, Int32 world, Int32 quantity, +LightObj & Core::NewPickup(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { // Request the server to create this entity const Int32 id = _Func->CreatePickup(model, world, quantity, x, y, z, alpha, automatic); @@ -636,9 +678,9 @@ Object & Core::NewPickup(Int32 model, Int32 world, Int32 quantity, } // -------------------------------------------------------------------------------------------- -Object & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, +LightObj & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, Int32 primary, Int32 secondary, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { // Request the server to create this entity @@ -669,7 +711,7 @@ Object & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float3 } // -------------------------------------------------------------------------------------------- -bool Core::DelBlip(Int32 id, Int32 header, Object & payload) +bool Core::DelBlip(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocBlip(id, true, header, payload); @@ -678,7 +720,7 @@ bool Core::DelBlip(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -bool Core::DelCheckpoint(Int32 id, Int32 header, Object & payload) +bool Core::DelCheckpoint(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocCheckpoint(id, true, header, payload); @@ -687,7 +729,7 @@ bool Core::DelCheckpoint(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -bool Core::DelKeybind(Int32 id, Int32 header, Object & payload) +bool Core::DelKeybind(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocKeybind(id, true, header, payload); @@ -696,7 +738,7 @@ bool Core::DelKeybind(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -bool Core::DelObject(Int32 id, Int32 header, Object & payload) +bool Core::DelObject(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocObject(id, true, header, payload); @@ -705,7 +747,7 @@ bool Core::DelObject(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -bool Core::DelPickup(Int32 id, Int32 header, Object & payload) +bool Core::DelPickup(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocPickup(id, true, header, payload); @@ -714,7 +756,7 @@ bool Core::DelPickup(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -bool Core::DelVehicle(Int32 id, Int32 header, Object & payload) +bool Core::DelVehicle(Int32 id, Int32 header, LightObj & payload) { // Attempt to destroy and deallocate the specified entity instance DeallocVehicle(id, true, header, payload); @@ -723,7 +765,7 @@ bool Core::DelVehicle(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload) +void Core::ConnectPlayer(Int32 id, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) @@ -740,11 +782,11 @@ void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload) // Instantiate the entity manager inst.mInst = new CPlayer(id); // Create the script object - inst.mObj = Object(inst.mInst, m_VM); + inst.mObj = LightObj(inst.mInst, m_VM); // Make sure that both the instance and script object could be created if (!inst.mInst || inst.mObj.IsNull()) { - ResetInst(inst); + inst.ResetInstance(); STHROWF("Unable to create a player instance for: %d", id); } // Assign the specified entity identifier @@ -761,7 +803,7 @@ void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void Core::DisconnectPlayer(Int32 id, Int32 header, Object & payload) +void Core::DisconnectPlayer(Int32 id, Int32 header, LightObj & payload) { // Make sure that the specified entity identifier is valid if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) diff --git a/source/CoreEvents.cpp b/source/CoreEvents.cpp index 02ea0161..6d1039b0 100644 --- a/source/CoreEvents.cpp +++ b/source/CoreEvents.cpp @@ -1,6 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Core.hpp" -#include "Base/Shared.hpp" +#include "Signal.hpp" #include "Base/Buffer.hpp" #include "Library/Utils/Buffer.hpp" @@ -8,181 +8,181 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -void Core::EmitCustomEvent(Int32 group, Int32 header, Object & payload) +void Core::EmitCustomEvent(Int32 group, Int32 header, LightObj & payload) { - Emit(mOnCustomEvent, group, header, payload); + (*mOnCustomEvent.first)(group, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitBlipCreated(Int32 blip, Int32 header, Object & payload) +void Core::EmitBlipCreated(Int32 blip, Int32 header, LightObj & payload) { - Emit(mOnBlipCreated, m_Blips.at(blip).mObj, header, payload); + (*mOnBlipCreated.first)(m_Blips.at(blip).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitCheckpointCreated(Int32 checkpoint, Int32 header, Object & payload) +void Core::EmitCheckpointCreated(Int32 checkpoint, Int32 header, LightObj & payload) { - Emit(mOnCheckpointCreated, m_Checkpoints.at(checkpoint).mObj, header, payload); + (*mOnCheckpointCreated.first)(m_Checkpoints.at(checkpoint).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitKeybindCreated(Int32 keybind, Int32 header, Object & payload) +void Core::EmitKeybindCreated(Int32 keybind, Int32 header, LightObj & payload) { - Emit(mOnKeybindCreated, m_Keybinds.at(keybind).mObj, header, payload); + (*mOnKeybindCreated.first)(m_Keybinds.at(keybind).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitObjectCreated(Int32 object, Int32 header, Object & payload) +void Core::EmitObjectCreated(Int32 object, Int32 header, LightObj & payload) { - Emit(mOnObjectCreated, m_Objects.at(object).mObj, header, payload); + (*mOnObjectCreated.first)(m_Objects.at(object).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPickupCreated(Int32 pickup, Int32 header, Object & payload) +void Core::EmitPickupCreated(Int32 pickup, Int32 header, LightObj & payload) { - Emit(mOnPickupCreated, m_Pickups.at(pickup).mObj, header, payload); + (*mOnPickupCreated.first)(m_Pickups.at(pickup).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPlayerCreated(Int32 player, Int32 header, Object & payload) +void Core::EmitPlayerCreated(Int32 player, Int32 header, LightObj & payload) { - Emit(mOnPlayerCreated, m_Players.at(player).mObj, header, payload); + (*mOnPlayerCreated.first)(m_Players.at(player).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitVehicleCreated(Int32 vehicle, Int32 header, Object & payload) +void Core::EmitVehicleCreated(Int32 vehicle, Int32 header, LightObj & payload) { - Emit(mOnVehicleCreated, m_Vehicles.at(vehicle).mObj, header, payload); + (*mOnVehicleCreated.first)(m_Vehicles.at(vehicle).mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitBlipDestroyed(Int32 blip, Int32 header, Object & payload) +void Core::EmitBlipDestroyed(Int32 blip, Int32 header, LightObj & payload) { BlipInst & _blip = m_Blips.at(blip); - Emit(_blip.mOnDestroyed, header, payload); - Emit(mOnBlipDestroyed, _blip.mObj, header, payload); + (*_blip.mOnDestroyed.first)(header, payload); + (*mOnBlipDestroyed.first)(_blip.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitCheckpointDestroyed(Int32 checkpoint, Int32 header, Object & payload) +void Core::EmitCheckpointDestroyed(Int32 checkpoint, Int32 header, LightObj & payload) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnDestroyed, header, payload); - Emit(mOnCheckpointDestroyed, _checkpoint.mObj, header, payload); + (*_checkpoint.mOnDestroyed.first)(header, payload); + (*mOnCheckpointDestroyed.first)(_checkpoint.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitKeybindDestroyed(Int32 keybind, Int32 header, Object & payload) +void Core::EmitKeybindDestroyed(Int32 keybind, Int32 header, LightObj & payload) { KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnDestroyed, header, payload); - Emit(mOnKeybindDestroyed, _keybind.mObj, header, payload); + (*_keybind.mOnDestroyed.first)(header, payload); + (*mOnKeybindDestroyed.first)(_keybind.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitObjectDestroyed(Int32 object, Int32 header, Object & payload) +void Core::EmitObjectDestroyed(Int32 object, Int32 header, LightObj & payload) { ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnDestroyed, header, payload); - Emit(mOnObjectDestroyed, _object.mObj, header, payload); + (*_object.mOnDestroyed.first)(header, payload); + (*mOnObjectDestroyed.first)(_object.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPickupDestroyed(Int32 pickup, Int32 header, Object & payload) +void Core::EmitPickupDestroyed(Int32 pickup, Int32 header, LightObj & payload) { PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnDestroyed, header, payload); - Emit(mOnPickupDestroyed, _pickup.mObj, header, payload); + (*_pickup.mOnDestroyed.first)(header, payload); + (*mOnPickupDestroyed.first)(_pickup.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPlayerDestroyed(Int32 player, Int32 header, Object & payload) +void Core::EmitPlayerDestroyed(Int32 player, Int32 header, LightObj & payload) { PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnDestroyed, header, payload); - Emit(mOnPlayerDestroyed, _player.mObj, header, payload); + (*_player.mOnDestroyed.first)(header, payload); + (*mOnPlayerDestroyed.first)(_player.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitVehicleDestroyed(Int32 vehicle, Int32 header, Object & payload) +void Core::EmitVehicleDestroyed(Int32 vehicle, Int32 header, LightObj & payload) { VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnDestroyed, header, payload); - Emit(mOnVehicleDestroyed, _vehicle.mObj, header, payload); + (*_vehicle.mOnDestroyed.first)(header, payload); + (*mOnVehicleDestroyed.first)(_vehicle.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitBlipCustom(Int32 blip, Int32 header, Object & payload) +void Core::EmitBlipCustom(Int32 blip, Int32 header, LightObj & payload) { BlipInst & _blip = m_Blips.at(blip); - Emit(_blip.mOnCustom, header, payload); - Emit(mOnBlipCustom, _blip.mObj, header, payload); + (*_blip.mOnCustom.first)(header, payload); + (*mOnBlipCustom.first)(_blip.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitCheckpointCustom(Int32 checkpoint, Int32 header, Object & payload) +void Core::EmitCheckpointCustom(Int32 checkpoint, Int32 header, LightObj & payload) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint); - Emit(_checkpoint.mOnCustom, header, payload); - Emit(mOnCheckpointCustom, _checkpoint.mObj, header, payload); + (*_checkpoint.mOnCustom.first)(header, payload); + (*mOnCheckpointCustom.first)(_checkpoint.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitKeybindCustom(Int32 keybind, Int32 header, Object & payload) +void Core::EmitKeybindCustom(Int32 keybind, Int32 header, LightObj & payload) { KeybindInst & _keybind = m_Keybinds.at(keybind); - Emit(_keybind.mOnCustom, header, payload); - Emit(mOnKeybindCustom, _keybind.mObj, header, payload); + (*_keybind.mOnCustom.first)(header, payload); + (*mOnKeybindCustom.first)(_keybind.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitObjectCustom(Int32 object, Int32 header, Object & payload) +void Core::EmitObjectCustom(Int32 object, Int32 header, LightObj & payload) { ObjectInst & _object = m_Objects.at(object); - Emit(_object.mOnCustom, header, payload); - Emit(mOnObjectCustom, _object.mObj, header, payload); + (*_object.mOnCustom.first)(header, payload); + (*mOnObjectCustom.first)(_object.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPickupCustom(Int32 pickup, Int32 header, Object & payload) +void Core::EmitPickupCustom(Int32 pickup, Int32 header, LightObj & payload) { PickupInst & _pickup = m_Pickups.at(pickup); - Emit(_pickup.mOnCustom, header, payload); - Emit(mOnPickupCustom, _pickup.mObj, header, payload); + (*_pickup.mOnCustom.first)(header, payload); + (*mOnPickupCustom.first)(_pickup.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitPlayerCustom(Int32 player, Int32 header, Object & payload) +void Core::EmitPlayerCustom(Int32 player, Int32 header, LightObj & payload) { PlayerInst & _player = m_Players.at(player); - Emit(_player.mOnCustom, header, payload); - Emit(mOnPlayerCustom, _player.mObj, header, payload); + (*_player.mOnCustom.first)(header, payload); + (*mOnPlayerCustom.first)(_player.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitVehicleCustom(Int32 vehicle, Int32 header, Object & payload) +void Core::EmitVehicleCustom(Int32 vehicle, Int32 header, LightObj & payload) { VehicleInst & _vehicle = m_Vehicles.at(vehicle); - Emit(_vehicle.mOnCustom, header, payload); - Emit(mOnVehicleCustom, _vehicle.mObj, header, payload); + (*_vehicle.mOnCustom.first)(header, payload); + (*mOnVehicleCustom.first)(_vehicle.mObj, header, payload); } // ------------------------------------------------------------------------------------------------ void Core::EmitServerStartup() { - Emit(mOnServerStartup); + (*mOnServerStartup.first)(); } // ------------------------------------------------------------------------------------------------ void Core::EmitServerShutdown() { - Emit(mOnServerShutdown); + (*mOnServerShutdown.first)(); } // ------------------------------------------------------------------------------------------------ void Core::EmitServerFrame(Float32 elapsed_time) { - Emit(mOnServerFrame, elapsed_time); + (*mOnServerFrame.first)(elapsed_time); } // ------------------------------------------------------------------------------------------------ @@ -200,11 +200,15 @@ void Core::EmitIncomingConnection(CStr player_name, size_t name_buffer_size, CCS // Attempt to forward the event to the script callback try { - Emit(mOnIncomingConnection, player_name, name_buffer_size, user_password, ip_address); + (*mOnIncomingConnection.first)(player_name, name_buffer_size, user_password, ip_address); } catch (...) { - // We catch the exception so we can release the assigned buffer + // Release any stored buffer information + m_IncomingNameBuffer = nullptr; + m_IncomingNameCapacity = 0; + // We catched the exception so we can release the assigned buffer + throw; // re-throw it } // Release any stored buffer information m_IncomingNameBuffer = nullptr; @@ -215,32 +219,32 @@ void Core::EmitIncomingConnection(CStr player_name, size_t name_buffer_size, CCS void Core::EmitPlayerRequestClass(Int32 player_id, Int32 offset) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnRequestClass, offset); - Emit(mOnPlayerRequestClass, _player.mObj, offset); + (*_player.mOnRequestClass.first)(offset); + (*mOnPlayerRequestClass.first)(_player.mObj, offset); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerRequestSpawn(Int32 player_id) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnRequestSpawn); - Emit(mOnPlayerRequestSpawn, _player.mObj); + (*_player.mOnRequestSpawn.first)(); + (*mOnPlayerRequestSpawn.first)(_player.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerSpawn(Int32 player_id) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnSpawn); - Emit(mOnPlayerSpawn, _player.mObj); + (*_player.mOnSpawn.first)(); + (*mOnPlayerSpawn.first)(_player.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerWasted(Int32 player_id, Int32 reason) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnWasted, reason); - Emit(mOnPlayerWasted, _player.mObj, reason); + (*_player.mOnWasted.first)(reason); + (*mOnPlayerWasted.first)(_player.mObj, reason); } // ------------------------------------------------------------------------------------------------ @@ -248,8 +252,8 @@ void Core::EmitPlayerKilled(Int32 player_id, Int32 killer_id, Int32 reason, vcmp { PlayerInst & _player = m_Players.at(player_id); PlayerInst & _killer = m_Players.at(killer_id); - Emit(_player.mOnKilled, _killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); - Emit(mOnPlayerKilled, _player.mObj, _killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); + (*_player.mOnKilled.first)(_killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); + (*mOnPlayerKilled.first)(_player.mObj, _killer.mObj, reason, static_cast< Int32 >(body_part), team_kill); } // ------------------------------------------------------------------------------------------------ @@ -257,9 +261,9 @@ void Core::EmitPlayerEmbarking(Int32 player_id, Int32 vehicle_id, Int32 slot_ind { PlayerInst & _player = m_Players.at(player_id); VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_player.mOnEmbarking, _vehicle.mObj, slot_index); - Emit(_vehicle.mOnEmbarking, _player.mObj, slot_index); - Emit(mOnPlayerEmbarking, _player.mObj, _vehicle.mObj, slot_index); + (*_player.mOnEmbarking.first)(_vehicle.mObj, slot_index); + (*_vehicle.mOnEmbarking.first)(_player.mObj, slot_index); + (*mOnPlayerEmbarking.first)(_player.mObj, _vehicle.mObj, slot_index); } // ------------------------------------------------------------------------------------------------ @@ -267,9 +271,9 @@ void Core::EmitPlayerEmbarked(Int32 player_id, Int32 vehicle_id, Int32 slot_inde { PlayerInst & _player = m_Players.at(player_id); VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_player.mOnEmbarked, _vehicle.mObj, slot_index); - Emit(_vehicle.mOnEmbarked, _player.mObj, slot_index); - Emit(mOnPlayerEmbarked, _player.mObj, _vehicle.mObj, slot_index); + (*_player.mOnEmbarked.first)(_vehicle.mObj, slot_index); + (*_vehicle.mOnEmbarked.first)(_player.mObj, slot_index); + (*mOnPlayerEmbarked.first)(_player.mObj, _vehicle.mObj, slot_index); } // ------------------------------------------------------------------------------------------------ @@ -277,273 +281,273 @@ void Core::EmitPlayerDisembark(Int32 player_id, Int32 vehicle_id) { PlayerInst & _player = m_Players.at(player_id); VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_player.mOnDisembark, _vehicle.mObj); - Emit(_vehicle.mOnDisembark, _player.mObj); - Emit(mOnPlayerDisembark, _player.mObj, _vehicle.mObj); + (*_player.mOnDisembark.first)(_vehicle.mObj); + (*_vehicle.mOnDisembark.first)(_player.mObj); + (*mOnPlayerDisembark.first)(_player.mObj, _vehicle.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerRename(Int32 player_id, CCStr old_name, CCStr new_name) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnRename, old_name, new_name); - Emit(mOnPlayerRename, _player.mObj, old_name, new_name); + (*_player.mOnRename.first)(old_name, new_name); + (*mOnPlayerRename.first)(_player.mObj, old_name, new_name); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerState(Int32 player_id, Int32 old_state, Int32 new_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnState, old_state, new_state); - Emit(mOnPlayerState, _player.mObj, old_state, new_state); + (*_player.mOnState.first)(old_state, new_state); + (*mOnPlayerState.first)(_player.mObj, old_state, new_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateNone(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateNone, old_state); - Emit(mOnStateNone, _player.mObj, old_state); + (*_player.mOnStateNone.first)(old_state); + (*mOnStateNone.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateNormal(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateNormal, old_state); - Emit(mOnStateNormal, _player.mObj, old_state); + (*_player.mOnStateNormal.first)(old_state); + (*mOnStateNormal.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateAim(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateAim, old_state); - Emit(mOnStateAim, _player.mObj, old_state); + (*_player.mOnStateAim.first)(old_state); + (*mOnStateAim.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateDriver(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateDriver, old_state); - Emit(mOnStateDriver, _player.mObj, old_state); + (*_player.mOnStateDriver.first)(old_state); + (*mOnStateDriver.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStatePassenger(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStatePassenger, old_state); - Emit(mOnStatePassenger, _player.mObj, old_state); + (*_player.mOnStatePassenger.first)(old_state); + (*mOnStatePassenger.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateEnterDriver(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateEnterDriver, old_state); - Emit(mOnStateEnterDriver, _player.mObj, old_state); + (*_player.mOnStateEnterDriver.first)(old_state); + (*mOnStateEnterDriver.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateEnterPassenger(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateEnterPassenger, old_state); - Emit(mOnStateEnterPassenger, _player.mObj, old_state); + (*_player.mOnStateEnterPassenger.first)(old_state); + (*mOnStateEnterPassenger.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateExit(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateExit, old_state); - Emit(mOnStateExit, _player.mObj, old_state); + (*_player.mOnStateExit.first)(old_state); + (*mOnStateExit.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitStateUnspawned(Int32 player_id, Int32 old_state) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStateUnspawned, old_state); - Emit(mOnStateUnspawned, _player.mObj, old_state); + (*_player.mOnStateUnspawned.first)(old_state); + (*mOnStateUnspawned.first)(_player.mObj, old_state); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerAction(Int32 player_id, Int32 old_action, Int32 new_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnAction, old_action, new_action); - Emit(mOnPlayerAction, _player.mObj, old_action, new_action); + (*_player.mOnAction.first)(old_action, new_action); + (*mOnPlayerAction.first)(_player.mObj, old_action, new_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionNone(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionNone, old_action); - Emit(mOnActionNone, _player.mObj, old_action); + (*_player.mOnActionNone.first)(old_action); + (*mOnActionNone.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionNormal(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionNormal, old_action); - Emit(mOnActionNormal, _player.mObj, old_action); + (*_player.mOnActionNormal.first)(old_action); + (*mOnActionNormal.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionAiming(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionAiming, old_action); - Emit(mOnActionAiming, _player.mObj, old_action); + (*_player.mOnActionAiming.first)(old_action); + (*mOnActionAiming.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionShooting(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionShooting, old_action); - Emit(mOnActionShooting, _player.mObj, old_action); + (*_player.mOnActionShooting.first)(old_action); + (*mOnActionShooting.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionJumping(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionJumping, old_action); - Emit(mOnActionJumping, _player.mObj, old_action); + (*_player.mOnActionJumping.first)(old_action); + (*mOnActionJumping.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionLieDown(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionLieDown, old_action); - Emit(mOnActionLieDown, _player.mObj, old_action); + (*_player.mOnActionLieDown.first)(old_action); + (*mOnActionLieDown.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionGettingUp(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionGettingUp, old_action); - Emit(mOnActionGettingUp, _player.mObj, old_action); + (*_player.mOnActionGettingUp.first)(old_action); + (*mOnActionGettingUp.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionJumpVehicle(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionJumpVehicle, old_action); - Emit(mOnActionJumpVehicle, _player.mObj, old_action); + (*_player.mOnActionJumpVehicle.first)(old_action); + (*mOnActionJumpVehicle.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionDriving(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionDriving, old_action); - Emit(mOnActionDriving, _player.mObj, old_action); + (*_player.mOnActionDriving.first)(old_action); + (*mOnActionDriving.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionDying(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionDying, old_action); - Emit(mOnActionDying, _player.mObj, old_action); + (*_player.mOnActionDying.first)(old_action); + (*mOnActionDying.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionWasted(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionWasted, old_action); - Emit(mOnActionWasted, _player.mObj, old_action); + (*_player.mOnActionWasted.first)(old_action); + (*mOnActionWasted.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionEmbarking(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionEmbarking, old_action); - Emit(mOnActionEmbarking, _player.mObj, old_action); + (*_player.mOnActionEmbarking.first)(old_action); + (*mOnActionEmbarking.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitActionDisembarking(Int32 player_id, Int32 old_action) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnActionDisembarking, old_action); - Emit(mOnActionDisembarking, _player.mObj, old_action); + (*_player.mOnActionDisembarking.first)(old_action); + (*mOnActionDisembarking.first)(_player.mObj, old_action); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerBurning(Int32 player_id, bool is_on_fire) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnBurning, is_on_fire); - Emit(mOnPlayerBurning, _player.mObj, is_on_fire); + (*_player.mOnBurning.first)(is_on_fire); + (*mOnPlayerBurning.first)(_player.mObj, is_on_fire); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerCrouching(Int32 player_id, bool is_crouching) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnCrouching, is_crouching); - Emit(mOnPlayerCrouching, _player.mObj, is_crouching); + (*_player.mOnCrouching.first)(is_crouching); + (*mOnPlayerCrouching.first)(_player.mObj, is_crouching); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerGameKeys(Int32 player_id, Uint32 old_keys, Uint32 new_keys) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnGameKeys, old_keys, new_keys); - Emit(mOnPlayerGameKeys, _player.mObj, old_keys, new_keys); + (*_player.mOnGameKeys.first)(old_keys, new_keys); + (*mOnPlayerGameKeys.first)(_player.mObj, old_keys, new_keys); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerStartTyping(Int32 player_id) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStartTyping); - Emit(mOnPlayerStartTyping, _player.mObj); + (*_player.mOnStartTyping.first)(); + (*mOnPlayerStartTyping.first)(_player.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerStopTyping(Int32 player_id) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnStopTyping); - Emit(mOnPlayerStopTyping, _player.mObj); + (*_player.mOnStopTyping.first)(); + (*mOnPlayerStopTyping.first)(_player.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerAway(Int32 player_id, bool is_away) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnAway, is_away); - Emit(mOnPlayerAway, _player.mObj, is_away); + (*_player.mOnAway.first)(is_away); + (*mOnPlayerAway.first)(_player.mObj, is_away); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerMessage(Int32 player_id, CCStr message) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnMessage, message); - Emit(mOnPlayerMessage, _player.mObj, message); + (*_player.mOnMessage.first)(message); + (*mOnPlayerMessage.first)(_player.mObj, message); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerCommand(Int32 player_id, CCStr message) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnCommand, message); - Emit(mOnPlayerCommand, _player.mObj, message); + (*_player.mOnCommand.first)(message); + (*mOnPlayerCommand.first)(_player.mObj, message); } // ------------------------------------------------------------------------------------------------ @@ -551,8 +555,8 @@ void Core::EmitPlayerPrivateMessage(Int32 player_id, Int32 target_player_id, CCS { PlayerInst & _player = m_Players.at(player_id); PlayerInst & _receiver = m_Players.at(target_player_id); - Emit(_player.mOnMessage,_receiver.mObj, message); - Emit(mOnPlayerPrivateMessage, _player.mObj, _receiver.mObj, message); + (*_player.mOnMessage.first)(_receiver.mObj, message); + (*mOnPlayerPrivateMessage.first)(_player.mObj, _receiver.mObj, message); } // ------------------------------------------------------------------------------------------------ @@ -560,9 +564,9 @@ void Core::EmitPlayerKeyPress(Int32 player_id, Int32 bind_id) { PlayerInst & _player = m_Players.at(player_id); KeybindInst & _keybind = m_Keybinds.at(bind_id); - Emit(_player.mOnKeyPress, _keybind.mObj); - Emit(_keybind.mOnKeyPress, _player.mObj); - Emit(mOnPlayerKeyPress, _player.mObj, _keybind.mObj); + (*_player.mOnKeyPress.first)(_keybind.mObj); + (*_keybind.mOnKeyPress.first)(_player.mObj); + (*mOnPlayerKeyPress.first)(_player.mObj, _keybind.mObj); } // ------------------------------------------------------------------------------------------------ @@ -570,9 +574,9 @@ void Core::EmitPlayerKeyRelease(Int32 player_id, Int32 bind_id) { PlayerInst & _player = m_Players.at(player_id); KeybindInst & _keybind = m_Keybinds.at(bind_id); - Emit(_keybind.mOnKeyRelease, _player.mObj); - Emit(_player.mOnKeyRelease, _keybind.mObj); - Emit(mOnPlayerKeyRelease, _player.mObj, _keybind.mObj); + (*_keybind.mOnKeyRelease.first)(_player.mObj); + (*_player.mOnKeyRelease.first)(_keybind.mObj); + (*mOnPlayerKeyRelease.first)(_player.mObj, _keybind.mObj); } // ------------------------------------------------------------------------------------------------ @@ -580,32 +584,32 @@ void Core::EmitPlayerSpectate(Int32 player_id, Int32 target_player_id) { PlayerInst & _player = m_Players.at(player_id); PlayerInst & _target = m_Players.at(target_player_id); - Emit(_player.mOnSpectate, _target.mObj); - Emit(mOnPlayerSpectate, _player.mObj, _target.mObj); + (*_player.mOnSpectate.first)(_target.mObj); + (*mOnPlayerSpectate.first)(_player.mObj, _target.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerCrashreport(Int32 player_id, CCStr report) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnCrashreport, report); - Emit(mOnPlayerCrashreport, _player.mObj, report); + (*_player.mOnCrashreport.first)(report); + (*mOnPlayerCrashreport.first)(_player.mObj, report); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleExplode(Int32 vehicle_id) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnExplode); - Emit(mOnVehicleExplode, _vehicle.mObj); + (*_vehicle.mOnExplode.first)(); + (*mOnVehicleExplode.first)(_vehicle.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleRespawn(Int32 vehicle_id) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnRespawn); - Emit(mOnVehicleRespawn, _vehicle.mObj); + (*_vehicle.mOnRespawn.first)(); + (*mOnVehicleRespawn.first)(_vehicle.mObj); } // ------------------------------------------------------------------------------------------------ @@ -613,9 +617,9 @@ void Core::EmitObjectShot(Int32 object_id, Int32 player_id, Int32 weapon_id) { ObjectInst & _object = m_Objects.at(object_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_object.mOnShot, _player.mObj, weapon_id); - Emit(_player.mOnObjectShot, _object.mObj, weapon_id); - Emit(mOnObjectShot, _player.mObj, _object.mObj, weapon_id); + (*_object.mOnShot.first)(_player.mObj, weapon_id); + (*_player.mOnObjectShot.first)(_object.mObj, weapon_id); + (*mOnObjectShot.first)(_player.mObj, _object.mObj, weapon_id); } // ------------------------------------------------------------------------------------------------ @@ -623,9 +627,9 @@ void Core::EmitObjectTouched(Int32 object_id, Int32 player_id) { ObjectInst & _object = m_Objects.at(object_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_object.mOnTouched, _player.mObj); - Emit(_player.mOnObjectTouched, _object.mObj); - Emit(mOnObjectTouched, _player.mObj, _object.mObj); + (*_object.mOnTouched.first)(_player.mObj); + (*_player.mOnObjectTouched.first)(_object.mObj); + (*mOnObjectTouched.first)(_player.mObj, _object.mObj); } // ------------------------------------------------------------------------------------------------ @@ -633,9 +637,9 @@ void Core::EmitPickupClaimed(Int32 pickup_id, Int32 player_id) { PickupInst & _pickup = m_Pickups.at(pickup_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_pickup.mOnClaimed, _player.mObj); - Emit(_player.mOnPickupClaimed, _pickup.mObj); - Emit(mOnPickupClaimed, _player.mObj, _pickup.mObj); + (*_pickup.mOnClaimed.first)(_player.mObj); + (*_player.mOnPickupClaimed.first)(_pickup.mObj); + (*mOnPickupClaimed.first)(_player.mObj, _pickup.mObj); } // ------------------------------------------------------------------------------------------------ @@ -643,17 +647,17 @@ void Core::EmitPickupCollected(Int32 pickup_id, Int32 player_id) { PickupInst & _pickup = m_Pickups.at(pickup_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_pickup.mOnCollected, _player.mObj); - Emit(_player.mOnPickupCollected, _pickup.mObj); - Emit(mOnPickupCollected, _player.mObj, _pickup.mObj); + (*_pickup.mOnCollected.first)(_player.mObj); + (*_player.mOnPickupCollected.first)(_pickup.mObj); + (*mOnPickupCollected.first)(_player.mObj, _pickup.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitPickupRespawn(Int32 pickup_id) { PickupInst & _pickup = m_Pickups.at(pickup_id); - Emit(_pickup.mOnRespawn); - Emit(mOnPickupRespawn, _pickup.mObj); + (*_pickup.mOnRespawn.first)(); + (*mOnPickupRespawn.first)(_pickup.mObj); } // ------------------------------------------------------------------------------------------------ @@ -661,9 +665,9 @@ void Core::EmitCheckpointEntered(Int32 checkpoint_id, Int32 player_id) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_checkpoint.mOnEntered, _player.mObj); - Emit(_player.mOnCheckpointEntered, _checkpoint.mObj); - Emit(mOnCheckpointEntered, _player.mObj, _checkpoint.mObj); + (*_checkpoint.mOnEntered.first)(_player.mObj); + (*_player.mOnCheckpointEntered.first)(_checkpoint.mObj); + (*mOnCheckpointEntered.first)(_player.mObj, _checkpoint.mObj); } // ------------------------------------------------------------------------------------------------ @@ -671,303 +675,303 @@ void Core::EmitCheckpointExited(Int32 checkpoint_id, Int32 player_id) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); PlayerInst & _player = m_Players.at(player_id); - Emit(_checkpoint.mOnExited, _player.mObj); - Emit(_player.mOnCheckpointExited, _checkpoint.mObj); - Emit(mOnCheckpointExited, _player.mObj, _checkpoint.mObj); + (*_checkpoint.mOnExited.first)(_player.mObj); + (*_player.mOnCheckpointExited.first)(_checkpoint.mObj); + (*mOnCheckpointExited.first)(_player.mObj, _checkpoint.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitCheckpointWorld(Int32 checkpoint_id, Int32 old_world, Int32 new_world) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); - Emit(_checkpoint.mOnWorld, old_world, new_world); - Emit(mOnCheckpointWorld, _checkpoint.mObj, old_world, new_world); + (*_checkpoint.mOnWorld.first)(old_world, new_world); + (*mOnCheckpointWorld.first)(_checkpoint.mObj, old_world, new_world); } // ------------------------------------------------------------------------------------------------ void Core::EmitCheckpointRadius(Int32 checkpoint_id, Float32 old_radius, Float32 new_radius) { CheckpointInst & _checkpoint = m_Checkpoints.at(checkpoint_id); - Emit(_checkpoint.mOnRadius, old_radius, new_radius); - Emit(mOnCheckpointRadius, _checkpoint.mObj, old_radius, new_radius); + (*_checkpoint.mOnRadius.first)(old_radius, new_radius); + (*mOnCheckpointRadius.first)(_checkpoint.mObj, old_radius, new_radius); } // ------------------------------------------------------------------------------------------------ void Core::EmitObjectWorld(Int32 object_id, Int32 old_world, Int32 new_world) { ObjectInst & _object = m_Objects.at(object_id); - Emit(_object.mOnWorld, old_world, new_world); - Emit(mOnObjectWorld, _object.mObj, old_world, new_world); + (*_object.mOnWorld.first)(old_world, new_world); + (*mOnObjectWorld.first)(_object.mObj, old_world, new_world); } // ------------------------------------------------------------------------------------------------ void Core::EmitObjectAlpha(Int32 object_id, Int32 old_alpha, Int32 new_alpha, Int32 time) { ObjectInst & _object = m_Objects.at(object_id); - Emit(_object.mOnAlpha, old_alpha, new_alpha, time); - Emit(mOnObjectAlpha, _object.mObj, old_alpha, new_alpha, time); + (*_object.mOnAlpha.first)(old_alpha, new_alpha, time); + (*mOnObjectAlpha.first)(_object.mObj, old_alpha, new_alpha, time); } // ------------------------------------------------------------------------------------------------ void Core::EmitPickupWorld(Int32 pickup_id, Int32 old_world, Int32 new_world) { PickupInst & _pickup = m_Pickups.at(pickup_id); - Emit(_pickup.mOnWorld, old_world, new_world); - Emit(mOnPickupWorld, _pickup.mObj, old_world, new_world); + (*_pickup.mOnWorld.first)(old_world, new_world); + (*mOnPickupWorld.first)(_pickup.mObj, old_world, new_world); } // ------------------------------------------------------------------------------------------------ void Core::EmitPickupAlpha(Int32 pickup_id, Int32 old_alpha, Int32 new_alpha) { PickupInst & _pickup = m_Pickups.at(pickup_id); - Emit(_pickup.mOnAlpha, old_alpha, new_alpha); - Emit(mOnPickupAlpha, _pickup.mObj, old_alpha, new_alpha); + (*_pickup.mOnAlpha.first)(old_alpha, new_alpha); + (*mOnPickupAlpha.first)(_pickup.mObj, old_alpha, new_alpha); } // ------------------------------------------------------------------------------------------------ void Core::EmitPickupAutomatic(Int32 pickup_id, bool old_status, bool new_status) { PickupInst & _pickup = m_Pickups.at(pickup_id); - Emit(_pickup.mOnAutomatic, old_status, new_status); - Emit(mOnPickupAutomatic, _pickup.mObj, old_status, new_status); + (*_pickup.mOnAutomatic.first)(old_status, new_status); + (*mOnPickupAutomatic.first)(_pickup.mObj, old_status, new_status); } // ------------------------------------------------------------------------------------------------ void Core::EmitPickupAutoTimer(Int32 pickup_id, Int32 old_timer, Int32 new_timer) { PickupInst & _pickup = m_Pickups.at(pickup_id); - Emit(_pickup.mOnAutoTimer, old_timer, new_timer); - Emit(mOnPickupAutoTimer, _pickup.mObj, old_timer, new_timer); + (*_pickup.mOnAutoTimer.first)(old_timer, new_timer); + (*mOnPickupAutoTimer.first)(_pickup.mObj, old_timer, new_timer); } // ------------------------------------------------------------------------------------------------ void Core::EmitObjectReport(Int32 object_id, bool old_status, bool new_status, bool touched) { ObjectInst & _object = m_Objects.at(object_id); - Emit(_object.mOnReport, old_status, new_status, touched); - Emit(mOnObjectReport, _object.mObj, old_status, new_status, touched); + (*_object.mOnReport.first)(old_status, new_status, touched); + (*mOnObjectReport.first)(_object.mObj, old_status, new_status, touched); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerHealth(Int32 player_id, Float32 old_health, Float32 new_health) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnHealth, old_health, new_health); - Emit(mOnPlayerHealth, _player.mObj, old_health, new_health); + (*_player.mOnHealth.first)(old_health, new_health); + (*mOnPlayerHealth.first)(_player.mObj, old_health, new_health); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerArmour(Int32 player_id, Float32 old_armour, Float32 new_armour) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnArmour, old_armour, new_armour); - Emit(mOnPlayerArmour, _player.mObj, old_armour, new_armour); + (*_player.mOnArmour.first)(old_armour, new_armour); + (*mOnPlayerArmour.first)(_player.mObj, old_armour, new_armour); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerWeapon(Int32 player_id, Int32 old_weapon, Int32 new_weapon) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnWeapon, old_weapon, new_weapon); - Emit(mOnPlayerWeapon, _player.mObj, old_weapon, new_weapon); + (*_player.mOnWeapon.first)(old_weapon, new_weapon); + (*mOnPlayerWeapon.first)(_player.mObj, old_weapon, new_weapon); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerHeading(Int32 player_id, Float32 old_heading, Float32 new_heading) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnHeading, old_heading, new_heading); - Emit(mOnPlayerHeading, _player.mObj, old_heading, new_heading); + (*_player.mOnHeading.first)(old_heading, new_heading); + (*mOnPlayerHeading.first)(_player.mObj, old_heading, new_heading); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerPosition(Int32 player_id) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnPosition, _player.mTrackPositionHeader, _player.mTrackPositionPayload); - Emit(mOnPlayerPosition, _player.mObj, _player.mTrackPositionHeader, _player.mTrackPositionPayload); + (*_player.mOnPosition.first)(_player.mTrackPositionHeader, _player.mTrackPositionPayload); + (*mOnPlayerPosition.first)(_player.mObj, _player.mTrackPositionHeader, _player.mTrackPositionPayload); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerOption(Int32 player_id, Int32 option_id, bool value, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnOption, option_id, value, header, payload); - Emit(mOnPlayerOption, _player.mObj, option_id, value, header, payload); + (*_player.mOnOption.first)(option_id, value, header, payload); + (*mOnPlayerOption.first)(_player.mObj, option_id, value, header, payload); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerAdmin(Int32 player_id, bool old_status, bool new_status) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnAdmin, old_status, new_status); - Emit(mOnPlayerAdmin, _player.mObj, old_status, new_status); + (*_player.mOnAdmin.first)(old_status, new_status); + (*mOnPlayerAdmin.first)(_player.mObj, old_status, new_status); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerWorld(Int32 player_id, Int32 old_world, Int32 new_world, bool secondary) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnWorld, old_world, new_world, secondary); - Emit(mOnPlayerWorld, _player.mObj, old_world, new_world, secondary); + (*_player.mOnWorld.first)(old_world, new_world, secondary); + (*mOnPlayerWorld.first)(_player.mObj, old_world, new_world, secondary); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerTeam(Int32 player_id, Int32 old_team, Int32 new_team) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnTeam, old_team, new_team); - Emit(mOnPlayerTeam, _player.mObj, old_team, new_team); + (*_player.mOnTeam.first)(old_team, new_team); + (*mOnPlayerTeam.first)(_player.mObj, old_team, new_team); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerSkin(Int32 player_id, Int32 old_skin, Int32 new_skin) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnSkin, old_skin, new_skin); - Emit(mOnPlayerSkin, _player.mObj, old_skin, new_skin); + (*_player.mOnSkin.first)(old_skin, new_skin); + (*mOnPlayerSkin.first)(_player.mObj, old_skin, new_skin); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerMoney(Int32 player_id, Int32 old_money, Int32 new_money) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnMoney, old_money, new_money); - Emit(mOnPlayerMoney, _player.mObj, old_money, new_money); + (*_player.mOnMoney.first)(old_money, new_money); + (*mOnPlayerMoney.first)(_player.mObj, old_money, new_money); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerScore(Int32 player_id, Int32 old_score, Int32 new_score) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnScore, old_score, new_score); - Emit(mOnPlayerScore, _player.mObj, old_score, new_score); + (*_player.mOnScore.first)(old_score, new_score); + (*mOnPlayerScore.first)(_player.mObj, old_score, new_score); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerWantedLevel(Int32 player_id, Int32 old_level, Int32 new_level) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnWantedLevel, old_level, new_level); - Emit(mOnPlayerWantedLevel, _player.mObj, old_level, new_level); + (*_player.mOnWantedLevel.first)(old_level, new_level); + (*mOnPlayerWantedLevel.first)(_player.mObj, old_level, new_level); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerImmunity(Int32 player_id, Int32 old_immunity, Int32 new_immunity) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnImmunity, old_immunity, new_immunity); - Emit(mOnPlayerImmunity, _player.mObj, old_immunity, new_immunity); + (*_player.mOnImmunity.first)(old_immunity, new_immunity); + (*mOnPlayerImmunity.first)(_player.mObj, old_immunity, new_immunity); } // ------------------------------------------------------------------------------------------------ void Core::EmitPlayerAlpha(Int32 player_id, Int32 old_alpha, Int32 new_alpha, Int32 fade) { PlayerInst & _player = m_Players.at(player_id); - Emit(_player.mOnAlpha, old_alpha, new_alpha, fade); - Emit(mOnPlayerAlpha, _player.mObj, old_alpha, new_alpha, fade); + (*_player.mOnAlpha.first)(old_alpha, new_alpha, fade); + (*mOnPlayerAlpha.first)(_player.mObj, old_alpha, new_alpha, fade); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleColor(Int32 vehicle_id, Int32 changed) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnColor, changed); - Emit(mOnVehicleColor, _vehicle.mObj, changed); + (*_vehicle.mOnColor.first)(changed); + (*mOnVehicleColor.first)(_vehicle.mObj, changed); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleHealth(Int32 vehicle_id, Float32 old_health, Float32 new_health) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnHealth, old_health, new_health); - Emit(mOnVehicleHealth, _vehicle.mObj, old_health, new_health); + (*_vehicle.mOnHealth.first)(old_health, new_health); + (*mOnVehicleHealth.first)(_vehicle.mObj, old_health, new_health); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehiclePosition(Int32 vehicle_id) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnPosition); - Emit(mOnVehiclePosition, _vehicle.mObj); + (*_vehicle.mOnPosition.first)(); + (*mOnVehiclePosition.first)(_vehicle.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleRotation(Int32 vehicle_id) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnRotation); - Emit(mOnVehicleRotation, _vehicle.mObj); + (*_vehicle.mOnRotation.first)(); + (*mOnVehicleRotation.first)(_vehicle.mObj); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleOption(Int32 vehicle_id, Int32 option_id, bool value, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnOption, option_id, value, header, payload); - Emit(mOnVehicleOption, _vehicle.mObj, option_id, value, header, payload); + (*_vehicle.mOnOption.first)(option_id, value, header, payload); + (*mOnVehicleOption.first)(_vehicle.mObj, option_id, value, header, payload); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleWorld(Int32 vehicle_id, Int32 old_world, Int32 new_world) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnWorld, old_world, new_world); - Emit(mOnVehicleWorld, _vehicle.mObj, old_world, new_world); + (*_vehicle.mOnWorld.first)(old_world, new_world); + (*mOnVehicleWorld.first)(_vehicle.mObj, old_world, new_world); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleImmunity(Int32 vehicle_id, Int32 old_immunity, Int32 new_immunity) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnImmunity, old_immunity, new_immunity); - Emit(mOnVehicleImmunity, _vehicle.mObj, old_immunity, new_immunity); + (*_vehicle.mOnImmunity.first)(old_immunity, new_immunity); + (*mOnVehicleImmunity.first)(_vehicle.mObj, old_immunity, new_immunity); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehiclePartStatus(Int32 vehicle_id, Int32 part, Int32 old_status, Int32 new_status) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnPartStatus, part, old_status, new_status); - Emit(mOnVehiclePartStatus, _vehicle.mObj, part, old_status, new_status); + (*_vehicle.mOnPartStatus.first)(part, old_status, new_status); + (*mOnVehiclePartStatus.first)(_vehicle.mObj, part, old_status, new_status); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleTyreStatus(Int32 vehicle_id, Int32 tyre, Int32 old_status, Int32 new_status) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnTyreStatus, tyre, old_status, new_status); - Emit(mOnVehicleTyreStatus, _vehicle.mObj, tyre, old_status, new_status); + (*_vehicle.mOnTyreStatus.first)(tyre, old_status, new_status); + (*mOnVehicleTyreStatus.first)(_vehicle.mObj, tyre, old_status, new_status); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleDamageData(Int32 vehicle_id, Uint32 old_data, Uint32 new_data) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnDamageData, old_data, new_data); - Emit(mOnVehicleDamageData, _vehicle.mObj, old_data, new_data); + (*_vehicle.mOnDamageData.first)(old_data, new_data); + (*mOnVehicleDamageData.first)(_vehicle.mObj, old_data, new_data); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleRadio(Int32 vehicle_id, Int32 old_radio, Int32 new_radio) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnRadio, old_radio, new_radio); - Emit(mOnVehicleRadio, _vehicle.mObj, old_radio, new_radio); + (*_vehicle.mOnRadio.first)(old_radio, new_radio); + (*mOnVehicleRadio.first)(_vehicle.mObj, old_radio, new_radio); } // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleHandlingRule(Int32 vehicle_id, Int32 rule, Float32 old_data, Float32 new_data) { VehicleInst & _vehicle = m_Vehicles.at(vehicle_id); - Emit(_vehicle.mOnHandlingRule, rule, old_data, new_data); - Emit(mOnVehicleHandlingRule, _vehicle.mObj, rule, old_data, new_data); + (*mOnVehicleHandlingRule.first)(_vehicle.mObj, rule, old_data, new_data); + (*_vehicle.mOnHandlingRule.first)(rule, old_data, new_data); } // ------------------------------------------------------------------------------------------------ -void Core::EmitServerOption(Int32 option, bool value, Int32 header, Object & payload) +void Core::EmitServerOption(Int32 option, bool value, Int32 header, LightObj & payload) { if (m_CircularLocks & CCL_EMIT_SERVER_OPTION) { @@ -976,19 +980,19 @@ void Core::EmitServerOption(Int32 option, bool value, Int32 header, Object & pay // Prevent further calls to this event BitGuardU32 bg(m_CircularLocks, CCL_EMIT_SERVER_OPTION); // Now forward the event call - Emit(mOnServerOption, option, value, header, payload); + (*mOnServerOption.first)(option, value, header, payload); } // ------------------------------------------------------------------------------------------------ -void Core::EmitScriptReload(Int32 header, Object & payload) +void Core::EmitScriptReload(Int32 header, LightObj & payload) { - Emit(mOnScriptReload, header, payload); + (*mOnScriptReload.first)(header, payload); } // ------------------------------------------------------------------------------------------------ void Core::EmitScriptLoaded() { - Emit(mOnScriptLoaded); + (*mOnScriptLoaded.first)(); } // ------------------------------------------------------------------------------------------------ @@ -1001,36 +1005,36 @@ void Core::EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_d // Do we even have this vehicle that we're trying to delete? if (is_deleted && VALID_ENTITY(m_Vehicles[entity_id].mID)) { - DeallocVehicle(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + DeallocVehicle(entity_id, false, SQMOD_DESTROY_POOL, NullLightObj()); } // Do we already have this vehicle that we're trying to create? else if (INVALID_ENTITY(m_Vehicles[entity_id].mID)) { - AllocVehicle(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + AllocVehicle(entity_id, false, SQMOD_CREATE_POOL, NullLightObj()); } break; case vcmpEntityPoolObject: // Do we even have this object that we're trying to delete? if (is_deleted && VALID_ENTITY(m_Objects[entity_id].mID)) { - DeallocObject(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + DeallocObject(entity_id, false, SQMOD_DESTROY_POOL, NullLightObj()); } // Do we already have this object that we're trying to create? else if (INVALID_ENTITY(m_Objects[entity_id].mID)) { - AllocObject(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + AllocObject(entity_id, false, SQMOD_CREATE_POOL, NullLightObj()); } break; case vcmpEntityPoolPickup: // Do we even have this pickup that we're trying to delete? if (is_deleted && VALID_ENTITY(m_Pickups[entity_id].mID)) { - DeallocPickup(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + DeallocPickup(entity_id, false, SQMOD_DESTROY_POOL, NullLightObj()); } // Do we already have this pickup that we're trying to create? else if (INVALID_ENTITY(m_Pickups[entity_id].mID)) { - AllocPickup(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + AllocPickup(entity_id, false, SQMOD_CREATE_POOL, NullLightObj()); } break; case vcmpEntityPoolRadio: @@ -1040,19 +1044,19 @@ void Core::EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_d // Do we even have this checkpoint that we're trying to delete? if (is_deleted && VALID_ENTITY(m_Checkpoints[entity_id].mID)) { - DeallocCheckpoint(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + DeallocCheckpoint(entity_id, false, SQMOD_DESTROY_POOL, NullLightObj()); } // Do we already have this checkpoint that we're trying to create? else if (INVALID_ENTITY(m_Checkpoints[entity_id].mID)) { - AllocCheckpoint(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + AllocCheckpoint(entity_id, false, SQMOD_CREATE_POOL, NullLightObj()); } break; case vcmpEntityPoolBlip: // Do we even have this blip that we're trying to delete? if (is_deleted && VALID_ENTITY(m_Blips[entity_id].mID)) { - DeallocBlip(entity_id, false, SQMOD_DESTROY_POOL, NullObject()); + DeallocBlip(entity_id, false, SQMOD_DESTROY_POOL, NullLightObj()); } // Do we already have this blip that we're trying to create? else if (INVALID_ENTITY(m_Blips[entity_id].mID)) @@ -1082,14 +1086,14 @@ void Core::EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_d inst.mColor.SetRGBA(color); inst.mPosition.SetVector3Ex(x, y, z); // Now we can try to allocate the instance after we have all the information - AllocBlip(entity_id, false, SQMOD_CREATE_POOL, NullObject()); + AllocBlip(entity_id, false, SQMOD_CREATE_POOL, NullLightObj()); } break; default: LogErr("Unknown change in the entity pool of type: %d", entity_type); } // Finally, forward the event to the script - Emit(mOnEntityPool, static_cast< Int32 >(entity_type), entity_id, is_deleted); + (*mOnEntityPool.first)(static_cast< Int32 >(entity_type), entity_id, is_deleted); } // ------------------------------------------------------------------------------------------------ @@ -1178,8 +1182,8 @@ void Core::EmitPlayerUpdate(Int32 player_id, vcmpPlayerUpdate update_type) } // Finally, forward the call to the update callback - Emit(inst.mOnUpdate, static_cast< Int32 >(update_type)); - Emit(mOnPlayerUpdate, inst.mObj, static_cast< Int32 >(update_type)); + (*inst.mOnUpdate.first)(static_cast< Int32 >(update_type)); + (*mOnPlayerUpdate.first)(inst.mObj, static_cast< Int32 >(update_type)); } // ------------------------------------------------------------------------------------------------ @@ -1264,8 +1268,8 @@ void Core::EmitVehicleUpdate(Int32 vehicle_id, vcmpVehicleUpdate update_type) default: { // Finally, forward the call to the update callback - Emit(inst.mOnUpdate, static_cast< Int32 >(update_type)); - Emit(mOnVehicleUpdate, inst.mObj, static_cast< Int32 >(update_type)); + (*inst.mOnUpdate.first)(static_cast< Int32 >(update_type)); + (*mOnVehicleUpdate.first)(inst.mObj, static_cast< Int32 >(update_type)); } } } @@ -1275,7 +1279,7 @@ void Core::EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t si { PlayerInst & _player = m_Players.at(player_id); // Don't even bother if there's no one listening - if (_player.mOnClientScriptData.IsNull() && mOnClientScriptData.IsNull()) + if (_player.mOnClientScriptData.first->IsEmpty() && mOnClientScriptData.first->IsEmpty()) { return; } @@ -1284,7 +1288,7 @@ void Core::EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t si // Replicate the data to the allocated buffer b.Write(0, reinterpret_cast< Buffer::ConstPtr >(data), size); // Prepare an object for the obtained buffer - Object o; + LightObj o; // Attempt to create the requested buffer try { @@ -1297,7 +1301,7 @@ void Core::EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t si // The script took over the instance now ad.Release(); // Get the object from the stack and store it - o = Var< Object >(DefaultVM::Get(), -1).value; + o = Var< LightObj >(DefaultVM::Get(), -1).value; } catch (const std::exception & e) { @@ -1309,8 +1313,8 @@ void Core::EmitClientScriptData(Int32 player_id, const uint8_t * data, size_t si STHROWF("Unable to transform script data into buffer"); } // Forward the event call - Emit(_player.mOnClientScriptData, o, size); - Emit(mOnClientScriptData, _player.mObj, o, size); + (*_player.mOnClientScriptData.first)(o, size); + (*mOnClientScriptData.first)(_player.mObj, o, size); } } // Namespace:: SqMod diff --git a/source/CoreFuncs.cpp b/source/CoreFuncs.cpp index 8b65c146..0a7d1a94 100644 --- a/source/CoreFuncs.cpp +++ b/source/CoreFuncs.cpp @@ -42,51 +42,12 @@ static SQInteger SqLoadScript(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -static void SqBindPreLoad(Object & env, Function & func) +static SQInteger SqGetEvents(HSQUIRRELVM vm) { - Core::Get().BindPreLoad(env, func, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindPostLoad(Object & env, Function & func) -{ - Core::Get().BindPostLoad(env, func, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindUnload(Object & env, Function & func) -{ - Core::Get().BindUnload(env, func, NullObject()); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindPreLoadEx(Object & env, Function & func, Object & payload) -{ - Core::Get().BindPreLoad(env, func, payload); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindPostLoadEx(Object & env, Function & func, Object & payload) -{ - Core::Get().BindPostLoad(env, func, payload); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindUnloadEx(Object & env, Function & func, Object & payload) -{ - Core::Get().BindUnload(env, func, payload); -} - -// ------------------------------------------------------------------------------------------------ -static void SqBindEvent(Int32 id, Object & env, Function & func) -{ - Core::Get().BindEvent(id, env, func); -} - -// ------------------------------------------------------------------------------------------------ -static void SqCustomEvent(Int32 group, Int32 header, Object & payload) -{ - Core::Get().EmitCustomEvent(group, header, payload); + // Push the events table object on the stack + sq_pushobject(vm, Core::Get().GetEvents().mObj); + // Specify that we're returning a value + return 1; } // ------------------------------------------------------------------------------------------------ @@ -102,7 +63,7 @@ static void SqSetReloadStatus(bool toggle) } // ------------------------------------------------------------------------------------------------ -static void SqReloadBecause(Int32 header, Object & payload) +static void SqReloadBecause(Int32 header, LightObj & payload) { // Assign the reload info Core::Get().SetReloadInfo(header, payload); @@ -111,7 +72,7 @@ static void SqReloadBecause(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static void SqSetReloadInfo(Int32 header, Object & payload) +static void SqSetReloadInfo(Int32 header, LightObj & payload) { Core::Get().SetReloadInfo(header, payload); } @@ -123,7 +84,7 @@ static Int32 SqGetReloadHeader() } // ------------------------------------------------------------------------------------------------ -static Object & SqGetReloadPayload() +static LightObj & SqGetReloadPayload() { return Core::Get().GetReloadPayload(); } @@ -159,7 +120,7 @@ static void SetOption(CSStr name, CSStr value) } // ------------------------------------------------------------------------------------------------ -static Object & GetBlip(Int32 id) +static LightObj & GetBlip(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) @@ -171,7 +132,7 @@ static Object & GetBlip(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetCheckpoint(Int32 id) +static LightObj & GetCheckpoint(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) @@ -183,7 +144,7 @@ static Object & GetCheckpoint(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetKeybind(Int32 id) +static LightObj & GetKeybind(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) @@ -195,7 +156,7 @@ static Object & GetKeybind(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetObject(Int32 id) +static LightObj & GetObject(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) @@ -207,7 +168,7 @@ static Object & GetObject(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetPickup(Int32 id) +static LightObj & GetPickup(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) @@ -219,7 +180,7 @@ static Object & GetPickup(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetPlayer(Int32 id) +static LightObj & GetPlayer(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) @@ -231,7 +192,7 @@ static Object & GetPlayer(Int32 id) } // ------------------------------------------------------------------------------------------------ -static Object & GetVehicle(Int32 id) +static LightObj & GetVehicle(Int32 id) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) @@ -243,7 +204,7 @@ static Object & GetVehicle(Int32 id) } // ------------------------------------------------------------------------------------------------ -static bool DelBlip(Int32 id, Int32 header, Object & payload) +static bool DelBlip(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) @@ -255,7 +216,7 @@ static bool DelBlip(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static bool DelCheckpoint(Int32 id, Int32 header, Object & payload) +static bool DelCheckpoint(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) @@ -267,7 +228,7 @@ static bool DelCheckpoint(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static bool DelKeybind(Int32 id, Int32 header, Object & payload) +static bool DelKeybind(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) @@ -279,7 +240,7 @@ static bool DelKeybind(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static bool DelObject(Int32 id, Int32 header, Object & payload) +static bool DelObject(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) @@ -291,7 +252,7 @@ static bool DelObject(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static bool DelPickup(Int32 id, Int32 header, Object & payload) +static bool DelPickup(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) @@ -303,7 +264,7 @@ static bool DelPickup(Int32 id, Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -static bool DelVehicle(Int32 id, Int32 header, Object & payload) +static bool DelVehicle(Int32 id, Int32 header, LightObj & payload) { // Validate the identifier first if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) @@ -319,14 +280,6 @@ void Register_Core(HSQUIRRELVM vm) { RootTable(vm) .Bind(_SC("SqCore"), Table(vm) - .Func(_SC("Bind"), &SqBindEvent) - .Func(_SC("BindPreLoad"), &SqBindPreLoad) - .Func(_SC("BindPostLoad"), &SqBindPostLoad) - .Func(_SC("BindUnload"), &SqBindUnload) - .Func(_SC("BindPreLoadEx"), &SqBindPreLoadEx) - .Func(_SC("BindPostLoadEx"), &SqBindPostLoadEx) - .Func(_SC("BindUnloadEx"), &SqBindUnloadEx) - .Func(_SC("CustomEvent"), &SqCustomEvent) .Func(_SC("Reload"), &SqSetReloadStatus) .Func(_SC("Reloading"), &SqGetReloadStatus) .Func(_SC("ReloadBecause"), &SqReloadBecause) @@ -352,6 +305,7 @@ void Register_Core(HSQUIRRELVM vm) .Func(_SC("DestroyPickup"), &DelPickup) .Func(_SC("DestroyVehicle"), &DelVehicle) .SquirrelFunc(_SC("LoadScript"), &SqLoadScript) + .SquirrelFunc(_SC("On"), &SqGetEvents) ); } diff --git a/source/CoreInst.cpp b/source/CoreInst.cpp new file mode 100644 index 00000000..e230a885 --- /dev/null +++ b/source/CoreInst.cpp @@ -0,0 +1,787 @@ +// ------------------------------------------------------------------------------------------------ +#include "Core.hpp" +#include "Signal.hpp" +#include "Logger.hpp" + +// ------------------------------------------------------------------------------------------------ +#include "Entity/Blip.hpp" +#include "Entity/Checkpoint.hpp" +#include "Entity/Keybind.hpp" +#include "Entity/Object.hpp" +#include "Entity/Pickup.hpp" +#include "Entity/Player.hpp" +#include "Entity/Vehicle.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// -------------------------------------------------------------------------------------------- +#define SQMOD_CATCH_EVENT_EXCEPTION(action) /* +*/ catch (const Sqrat::Exception & e) /* +*/ { /* +*/ LogErr("Squirrel exception caught " action); /* +*/ Logger::Get().Debug("%s", e.what()); /* +*/ } /* +*/ + +// ------------------------------------------------------------------------------------------------ +extern void CleanupTasks(Int32 id, Int32 type); + +// ------------------------------------------------------------------------------------------------ +void Core::BlipInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitBlipDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying blip") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_BLIP); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->DestroyCoordBlip(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::CheckpointInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitCheckpointDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying checkpoint") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_CHECKPOINT); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->DeleteCheckPoint(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::KeybindInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitKeybindDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying keybind") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_KEYBIND); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->RemoveKeyBind(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ObjectInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitObjectDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying object") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_OBJECT); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->DeleteObject(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PickupInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitPickupDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying pickup") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_PICKUP); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->DeletePickup(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PlayerInst::Destroy(bool /*destroy*/, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitPlayerDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying player") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + // Release the used memory buffer + mInst->m_Buffer.ResetAll(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_PLAYER); + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::VehicleInst::Destroy(bool destroy, Int32 header, LightObj & payload) +{ + // Should we notify that this entity is being cleaned up? + if (VALID_ENTITY(mID)) + { + // Don't leave exceptions to prevent us from releasing this instance + try + { + Core::Get().EmitVehicleDestroyed(mID, header, payload); + } + SQMOD_CATCH_EVENT_EXCEPTION("while destroying vehicle") + } + // Is there a manager instance associated with this entity? + if (mInst) + { + // Prevent further use of this entity + mInst->m_ID = -1; + // Release user data to avoid dangling or circular references + mInst->m_Data.Release(); + } + // Prevent further use of the manager instance + mInst = nullptr; + // Release the script object, if any + mObj.Release(); + // Release tasks, if any + CleanupTasks(mID, ENT_VEHICLE); + // Are we supposed to clean up this entity? (only at reload) + if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED)) + { + // Block the entity pool changes notification from triggering the destroy event + const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED)); + // Now attempt to destroy this entity from the server + _Func->DeleteVehicle(mID); + } + // Reset the instance to it's initial state + ResetInstance(); + // Don't release the callbacks abruptly + DropEvents(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::BlipInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; + mWorld = -1; + mScale = -1; + mSprID = -1; + mPosition.Clear(); + mColor.Clear(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::CheckpointInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::KeybindInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; + mFirst = -1; + mSecond = -1; + mThird = -1; + mRelease = -1; +} + +// ------------------------------------------------------------------------------------------------ +void Core::ObjectInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::PickupInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; +} + +// ------------------------------------------------------------------------------------------------ +void Core::PlayerInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; + mTrackPosition = 0; + mTrackHeading = 0; + mTrackPositionHeader = 0; + mTrackPositionPayload.Release(); + mKickBanHeader = 0; + mKickBanPayload.Release(); + mLastWeapon = -1; + mLastHealth = 0.0; + mLastArmour = 0.0; + mLastHeading = 0.0; + mLastPosition.Clear(); + mAuthority = 0; +} + +// ------------------------------------------------------------------------------------------------ +void Core::VehicleInst::ResetInstance() +{ + mID = -1; + mFlags = ENF_DEFAULT; + mTrackPosition = 0; + mTrackRotation = 0; + mLastPrimaryColor = -1; + mLastSecondaryColor = -1; + mLastHealth = 0.0; + mLastPosition.Clear(); + mLastRotation.Clear(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::BlipInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 4); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::BlipInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::CheckpointInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 8); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnEntered, mEvents, "Entered"); + InitSignalPair(mOnExited, mEvents, "Exited"); + InitSignalPair(mOnWorld, mEvents, "World"); + InitSignalPair(mOnRadius, mEvents, "Radius"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::CheckpointInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnEntered); + ResetSignalPair(mOnExited); + ResetSignalPair(mOnWorld); + ResetSignalPair(mOnRadius); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::KeybindInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 8); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnKeyPress, mEvents, "KeyPress"); + InitSignalPair(mOnKeyRelease, mEvents, "KeyRelease"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::KeybindInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnKeyPress); + ResetSignalPair(mOnKeyRelease); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ObjectInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 12); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnShot, mEvents, "Shot"); + InitSignalPair(mOnTouched, mEvents, "Touched"); + InitSignalPair(mOnWorld, mEvents, "World"); + InitSignalPair(mOnAlpha, mEvents, "Alpha"); + InitSignalPair(mOnReport, mEvents, "Report"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::ObjectInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnShot); + ResetSignalPair(mOnTouched); + ResetSignalPair(mOnWorld); + ResetSignalPair(mOnAlpha); + ResetSignalPair(mOnReport); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PickupInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 16); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnRespawn, mEvents, "Respawn"); + InitSignalPair(mOnClaimed, mEvents, "Claimed"); + InitSignalPair(mOnCollected, mEvents, "Collected"); + InitSignalPair(mOnWorld, mEvents, "World"); + InitSignalPair(mOnAlpha, mEvents, "Alpha"); + InitSignalPair(mOnAutomatic, mEvents, "Automatic"); + InitSignalPair(mOnAutoTimer, mEvents, "AutoTimer"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PickupInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnRespawn); + ResetSignalPair(mOnClaimed); + ResetSignalPair(mOnCollected); + ResetSignalPair(mOnWorld); + ResetSignalPair(mOnAlpha); + ResetSignalPair(mOnAutomatic); + ResetSignalPair(mOnAutoTimer); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PlayerInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 86); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnRequestClass, mEvents, "RequestClass"); + InitSignalPair(mOnRequestSpawn, mEvents, "RequestSpawn"); + InitSignalPair(mOnSpawn, mEvents, "Spawn"); + InitSignalPair(mOnWasted, mEvents, "Wasted"); + InitSignalPair(mOnKilled, mEvents, "Killed"); + InitSignalPair(mOnEmbarking, mEvents, "Embarking"); + InitSignalPair(mOnEmbarked, mEvents, "Embarked"); + InitSignalPair(mOnDisembark, mEvents, "Disembark"); + InitSignalPair(mOnRename, mEvents, "Rename"); + InitSignalPair(mOnState, mEvents, "State"); + InitSignalPair(mOnStateNone, mEvents, "StateNone"); + InitSignalPair(mOnStateNormal, mEvents, "StateNormal"); + InitSignalPair(mOnStateAim, mEvents, "StateAim"); + InitSignalPair(mOnStateDriver, mEvents, "StateDriver"); + InitSignalPair(mOnStatePassenger, mEvents, "StatePassenger"); + InitSignalPair(mOnStateEnterDriver, mEvents, "StateEnterDriver"); + InitSignalPair(mOnStateEnterPassenger, mEvents, "StateEnterPassenger"); + InitSignalPair(mOnStateExit, mEvents, "StateExit"); + InitSignalPair(mOnStateUnspawned, mEvents, "StateUnspawned"); + InitSignalPair(mOnAction, mEvents, "Action"); + InitSignalPair(mOnActionNone, mEvents, "ActionNone"); + InitSignalPair(mOnActionNormal, mEvents, "ActionNormal"); + InitSignalPair(mOnActionAiming, mEvents, "ActionAiming"); + InitSignalPair(mOnActionShooting, mEvents, "ActionShooting"); + InitSignalPair(mOnActionJumping, mEvents, "ActionJumping"); + InitSignalPair(mOnActionLieDown, mEvents, "ActionLieDown"); + InitSignalPair(mOnActionGettingUp, mEvents, "ActionGettingUp"); + InitSignalPair(mOnActionJumpVehicle, mEvents, "ActionJumpVehicle"); + InitSignalPair(mOnActionDriving, mEvents, "ActionDriving"); + InitSignalPair(mOnActionDying, mEvents, "ActionDying"); + InitSignalPair(mOnActionWasted, mEvents, "ActionWasted"); + InitSignalPair(mOnActionEmbarking, mEvents, "ActionEmbarking"); + InitSignalPair(mOnActionDisembarking, mEvents, "ActionDisembarking"); + InitSignalPair(mOnBurning, mEvents, "Burning"); + InitSignalPair(mOnCrouching, mEvents, "Crouching"); + InitSignalPair(mOnGameKeys, mEvents, "GameKeys"); + InitSignalPair(mOnStartTyping, mEvents, "StartTyping"); + InitSignalPair(mOnStopTyping, mEvents, "StopTyping"); + InitSignalPair(mOnAway, mEvents, "Away"); + InitSignalPair(mOnMessage, mEvents, "Message"); + InitSignalPair(mOnCommand, mEvents, "Command"); + InitSignalPair(mOnPrivateMessage, mEvents, "PrivateMessage"); + InitSignalPair(mOnKeyPress, mEvents, "KeyPress"); + InitSignalPair(mOnKeyRelease, mEvents, "KeyRelease"); + InitSignalPair(mOnSpectate, mEvents, "Spectate"); + InitSignalPair(mOnCrashreport, mEvents, "Crashreport"); + InitSignalPair(mOnObjectShot, mEvents, "ObjectShot"); + InitSignalPair(mOnObjectTouched, mEvents, "ObjectTouched"); + InitSignalPair(mOnPickupClaimed, mEvents, "PickupClaimed"); + InitSignalPair(mOnPickupCollected, mEvents, "PickupCollected"); + InitSignalPair(mOnCheckpointEntered, mEvents, "CheckpointEntered"); + InitSignalPair(mOnCheckpointExited, mEvents, "CheckpointExited"); + InitSignalPair(mOnClientScriptData, mEvents, "ClientScriptData"); + InitSignalPair(mOnUpdate, mEvents, "Update"); + InitSignalPair(mOnHealth, mEvents, "Health"); + InitSignalPair(mOnArmour, mEvents, "Armour"); + InitSignalPair(mOnWeapon, mEvents, "Weapon"); + InitSignalPair(mOnHeading, mEvents, "Heading"); + InitSignalPair(mOnPosition, mEvents, "Position"); + InitSignalPair(mOnOption, mEvents, "Option"); + InitSignalPair(mOnAdmin, mEvents, "Admin"); + InitSignalPair(mOnWorld, mEvents, "World"); + InitSignalPair(mOnTeam, mEvents, "Team"); + InitSignalPair(mOnSkin, mEvents, "Skin"); + InitSignalPair(mOnMoney, mEvents, "Money"); + InitSignalPair(mOnScore, mEvents, "Score"); + InitSignalPair(mOnWantedLevel, mEvents, "WantedLevel"); + InitSignalPair(mOnImmunity, mEvents, "Immunity"); + InitSignalPair(mOnAlpha, mEvents, "Alpha"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::PlayerInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnRequestClass); + ResetSignalPair(mOnRequestSpawn); + ResetSignalPair(mOnSpawn); + ResetSignalPair(mOnWasted); + ResetSignalPair(mOnKilled); + ResetSignalPair(mOnEmbarking); + ResetSignalPair(mOnEmbarked); + ResetSignalPair(mOnDisembark); + ResetSignalPair(mOnRename); + ResetSignalPair(mOnState); + ResetSignalPair(mOnStateNone); + ResetSignalPair(mOnStateNormal); + ResetSignalPair(mOnStateAim); + ResetSignalPair(mOnStateDriver); + ResetSignalPair(mOnStatePassenger); + ResetSignalPair(mOnStateEnterDriver); + ResetSignalPair(mOnStateEnterPassenger); + ResetSignalPair(mOnStateExit); + ResetSignalPair(mOnStateUnspawned); + ResetSignalPair(mOnAction); + ResetSignalPair(mOnActionNone); + ResetSignalPair(mOnActionNormal); + ResetSignalPair(mOnActionAiming); + ResetSignalPair(mOnActionShooting); + ResetSignalPair(mOnActionJumping); + ResetSignalPair(mOnActionLieDown); + ResetSignalPair(mOnActionGettingUp); + ResetSignalPair(mOnActionJumpVehicle); + ResetSignalPair(mOnActionDriving); + ResetSignalPair(mOnActionDying); + ResetSignalPair(mOnActionWasted); + ResetSignalPair(mOnActionEmbarking); + ResetSignalPair(mOnActionDisembarking); + ResetSignalPair(mOnBurning); + ResetSignalPair(mOnCrouching); + ResetSignalPair(mOnGameKeys); + ResetSignalPair(mOnStartTyping); + ResetSignalPair(mOnStopTyping); + ResetSignalPair(mOnAway); + ResetSignalPair(mOnMessage); + ResetSignalPair(mOnCommand); + ResetSignalPair(mOnPrivateMessage); + ResetSignalPair(mOnKeyPress); + ResetSignalPair(mOnKeyRelease); + ResetSignalPair(mOnSpectate); + ResetSignalPair(mOnCrashreport); + ResetSignalPair(mOnObjectShot); + ResetSignalPair(mOnObjectTouched); + ResetSignalPair(mOnPickupClaimed); + ResetSignalPair(mOnPickupCollected); + ResetSignalPair(mOnCheckpointEntered); + ResetSignalPair(mOnCheckpointExited); + ResetSignalPair(mOnClientScriptData); + ResetSignalPair(mOnUpdate); + ResetSignalPair(mOnHealth); + ResetSignalPair(mOnArmour); + ResetSignalPair(mOnWeapon); + ResetSignalPair(mOnHeading); + ResetSignalPair(mOnPosition); + ResetSignalPair(mOnOption); + ResetSignalPair(mOnAdmin); + ResetSignalPair(mOnWorld); + ResetSignalPair(mOnTeam); + ResetSignalPair(mOnSkin); + ResetSignalPair(mOnMoney); + ResetSignalPair(mOnScore); + ResetSignalPair(mOnWantedLevel); + ResetSignalPair(mOnImmunity); + ResetSignalPair(mOnAlpha); + mEvents.Release(); +} + +// ------------------------------------------------------------------------------------------------ +void Core::VehicleInst::InitEvents() +{ + // Ignore the call if already initialized + if (!mEvents.IsNull()) + { + return; + } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 32); + // Grab the table object from the stack + mEvents = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); + InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnEmbarking, mEvents, "Embarking"); + InitSignalPair(mOnEmbarked, mEvents, "Embarked"); + InitSignalPair(mOnDisembark, mEvents, "Disembark"); + InitSignalPair(mOnExplode, mEvents, "Explode"); + InitSignalPair(mOnRespawn, mEvents, "Respawn"); + InitSignalPair(mOnUpdate, mEvents, "Update"); + InitSignalPair(mOnColor, mEvents, "Color"); + InitSignalPair(mOnHealth, mEvents, "Health"); + InitSignalPair(mOnPosition, mEvents, "Position"); + InitSignalPair(mOnRotation, mEvents, "Rotation"); + InitSignalPair(mOnOption, mEvents, "Option"); + InitSignalPair(mOnWorld, mEvents, "World"); + InitSignalPair(mOnImmunity, mEvents, "Immunity"); + InitSignalPair(mOnPartStatus, mEvents, "PartStatus"); + InitSignalPair(mOnTyreStatus, mEvents, "TyreStatus"); + InitSignalPair(mOnDamageData, mEvents, "DamageData"); + InitSignalPair(mOnRadio, mEvents, "Radio"); + InitSignalPair(mOnHandlingRule, mEvents, "HandlingRule"); +} + +// ------------------------------------------------------------------------------------------------ +void Core::VehicleInst::DropEvents() +{ + ResetSignalPair(mOnDestroyed); + ResetSignalPair(mOnCustom); + ResetSignalPair(mOnEmbarking); + ResetSignalPair(mOnEmbarked); + ResetSignalPair(mOnDisembark); + ResetSignalPair(mOnExplode); + ResetSignalPair(mOnRespawn); + ResetSignalPair(mOnUpdate); + ResetSignalPair(mOnColor); + ResetSignalPair(mOnHealth); + ResetSignalPair(mOnPosition); + ResetSignalPair(mOnRotation); + ResetSignalPair(mOnOption); + ResetSignalPair(mOnWorld); + ResetSignalPair(mOnImmunity); + ResetSignalPair(mOnPartStatus); + ResetSignalPair(mOnTyreStatus); + ResetSignalPair(mOnDamageData); + ResetSignalPair(mOnRadio); + ResetSignalPair(mOnHandlingRule); + mEvents.Release(); +} + +} // Namespace:: SqMod diff --git a/source/CoreUtils.cpp b/source/CoreUtils.cpp index 0dbdb78d..6aba8887 100644 --- a/source/CoreUtils.cpp +++ b/source/CoreUtils.cpp @@ -42,691 +42,272 @@ void Core::ClearContainer(EntityType type) } // ------------------------------------------------------------------------------------------------ -void Core::ResetInst(BlipInst & inst) +void Core::InitEvents() { - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mWorld = -1; - inst.mScale = -1; - inst.mSprID = -1; - inst.mPosition.Clear(); - inst.mColor.Clear(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(CheckpointInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(KeybindInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mFirst = -1; - inst.mSecond = -1; - inst.mThird = -1; - inst.mRelease = -1; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(ObjectInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(PickupInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(PlayerInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mTrackPosition = 0; - inst.mTrackHeading = 0; - inst.mTrackPositionHeader = 0; - inst.mTrackPositionPayload.Release(); - inst.mKickBanHeader = 0; - inst.mKickBanPayload.Release(); - inst.mLastWeapon = -1; - inst.mLastHealth = 0.0; - inst.mLastArmour = 0.0; - inst.mLastHeading = 0.0; - inst.mLastPosition.Clear(); - inst.mAuthority = 0; -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetInst(VehicleInst & inst) -{ - inst.mID = -1; - inst.mFlags = ENF_DEFAULT; - inst.mTrackPosition = 0; - inst.mTrackRotation = 0; - inst.mLastPrimaryColor = -1; - inst.mLastSecondaryColor = -1; - inst.mLastHealth = 0.0; - inst.mLastPosition.Clear(); - inst.mLastRotation.Clear(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(BlipInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(CheckpointInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnEntered.ReleaseGently(); - inst.mOnExited.ReleaseGently(); - inst.mOnWorld.ReleaseGently(); - inst.mOnRadius.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(KeybindInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnKeyPress.ReleaseGently(); - inst.mOnKeyRelease.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(ObjectInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnShot.ReleaseGently(); - inst.mOnTouched.ReleaseGently(); - inst.mOnWorld.ReleaseGently(); - inst.mOnAlpha.ReleaseGently(); - inst.mOnReport.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(PickupInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnRespawn.ReleaseGently(); - inst.mOnClaimed.ReleaseGently(); - inst.mOnCollected.ReleaseGently(); - inst.mOnWorld.ReleaseGently(); - inst.mOnAlpha.ReleaseGently(); - inst.mOnAutomatic.ReleaseGently(); - inst.mOnAutoTimer.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(PlayerInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnRequestClass.ReleaseGently(); - inst.mOnRequestSpawn.ReleaseGently(); - inst.mOnSpawn.ReleaseGently(); - inst.mOnWasted.ReleaseGently(); - inst.mOnKilled.ReleaseGently(); - inst.mOnEmbarking.ReleaseGently(); - inst.mOnEmbarked.ReleaseGently(); - inst.mOnDisembark.ReleaseGently(); - inst.mOnRename.ReleaseGently(); - inst.mOnState.ReleaseGently(); - inst.mOnStateNone.ReleaseGently(); - inst.mOnStateNormal.ReleaseGently(); - inst.mOnStateAim.ReleaseGently(); - inst.mOnStateDriver.ReleaseGently(); - inst.mOnStatePassenger.ReleaseGently(); - inst.mOnStateEnterDriver.ReleaseGently(); - inst.mOnStateEnterPassenger.ReleaseGently(); - inst.mOnStateExit.ReleaseGently(); - inst.mOnStateUnspawned.ReleaseGently(); - inst.mOnAction.ReleaseGently(); - inst.mOnActionNone.ReleaseGently(); - inst.mOnActionNormal.ReleaseGently(); - inst.mOnActionAiming.ReleaseGently(); - inst.mOnActionShooting.ReleaseGently(); - inst.mOnActionJumping.ReleaseGently(); - inst.mOnActionLieDown.ReleaseGently(); - inst.mOnActionGettingUp.ReleaseGently(); - inst.mOnActionJumpVehicle.ReleaseGently(); - inst.mOnActionDriving.ReleaseGently(); - inst.mOnActionDying.ReleaseGently(); - inst.mOnActionWasted.ReleaseGently(); - inst.mOnActionEmbarking.ReleaseGently(); - inst.mOnActionDisembarking.ReleaseGently(); - inst.mOnBurning.ReleaseGently(); - inst.mOnCrouching.ReleaseGently(); - inst.mOnGameKeys.ReleaseGently(); - inst.mOnStartTyping.ReleaseGently(); - inst.mOnStopTyping.ReleaseGently(); - inst.mOnAway.ReleaseGently(); - inst.mOnMessage.ReleaseGently(); - inst.mOnCommand.ReleaseGently(); - inst.mOnPrivateMessage.ReleaseGently(); - inst.mOnKeyPress.ReleaseGently(); - inst.mOnKeyRelease.ReleaseGently(); - inst.mOnSpectate.ReleaseGently(); - inst.mOnCrashreport.ReleaseGently(); - inst.mOnObjectShot.ReleaseGently(); - inst.mOnObjectTouched.ReleaseGently(); - inst.mOnPickupClaimed.ReleaseGently(); - inst.mOnPickupCollected.ReleaseGently(); - inst.mOnCheckpointEntered.ReleaseGently(); - inst.mOnCheckpointExited.ReleaseGently(); - inst.mOnClientScriptData.ReleaseGently(); - inst.mOnUpdate.ReleaseGently(); - inst.mOnHealth.ReleaseGently(); - inst.mOnArmour.ReleaseGently(); - inst.mOnWeapon.ReleaseGently(); - inst.mOnHeading.ReleaseGently(); - inst.mOnPosition.ReleaseGently(); - inst.mOnOption.ReleaseGently(); - inst.mOnAdmin.ReleaseGently(); - inst.mOnWorld.ReleaseGently(); - inst.mOnTeam.ReleaseGently(); - inst.mOnSkin.ReleaseGently(); - inst.mOnMoney.ReleaseGently(); - inst.mOnScore.ReleaseGently(); - inst.mOnWantedLevel.ReleaseGently(); - inst.mOnImmunity.ReleaseGently(); - inst.mOnAlpha.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc(VehicleInst & inst) -{ - inst.mOnDestroyed.ReleaseGently(); - inst.mOnCustom.ReleaseGently(); - inst.mOnEmbarking.ReleaseGently(); - inst.mOnEmbarked.ReleaseGently(); - inst.mOnDisembark.ReleaseGently(); - inst.mOnExplode.ReleaseGently(); - inst.mOnRespawn.ReleaseGently(); - inst.mOnUpdate.ReleaseGently(); - inst.mOnColor.ReleaseGently(); - inst.mOnHealth.ReleaseGently(); - inst.mOnPosition.ReleaseGently(); - inst.mOnRotation.ReleaseGently(); - inst.mOnOption.ReleaseGently(); - inst.mOnWorld.ReleaseGently(); - inst.mOnImmunity.ReleaseGently(); - inst.mOnPartStatus.ReleaseGently(); - inst.mOnTyreStatus.ReleaseGently(); - inst.mOnDamageData.ReleaseGently(); - inst.mOnRadio.ReleaseGently(); - inst.mOnHandlingRule.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -void Core::ResetFunc() -{ - Core::Get().mOnCustomEvent.ReleaseGently(); - Core::Get().mOnBlipCreated.ReleaseGently(); - Core::Get().mOnCheckpointCreated.ReleaseGently(); - Core::Get().mOnKeybindCreated.ReleaseGently(); - Core::Get().mOnObjectCreated.ReleaseGently(); - Core::Get().mOnPickupCreated.ReleaseGently(); - Core::Get().mOnPlayerCreated.ReleaseGently(); - Core::Get().mOnVehicleCreated.ReleaseGently(); - Core::Get().mOnBlipDestroyed.ReleaseGently(); - Core::Get().mOnCheckpointDestroyed.ReleaseGently(); - Core::Get().mOnKeybindDestroyed.ReleaseGently(); - Core::Get().mOnObjectDestroyed.ReleaseGently(); - Core::Get().mOnPickupDestroyed.ReleaseGently(); - Core::Get().mOnPlayerDestroyed.ReleaseGently(); - Core::Get().mOnVehicleDestroyed.ReleaseGently(); - Core::Get().mOnBlipCustom.ReleaseGently(); - Core::Get().mOnCheckpointCustom.ReleaseGently(); - Core::Get().mOnKeybindCustom.ReleaseGently(); - Core::Get().mOnObjectCustom.ReleaseGently(); - Core::Get().mOnPickupCustom.ReleaseGently(); - Core::Get().mOnPlayerCustom.ReleaseGently(); - Core::Get().mOnVehicleCustom.ReleaseGently(); - Core::Get().mOnServerStartup.ReleaseGently(); - Core::Get().mOnServerShutdown.ReleaseGently(); - Core::Get().mOnServerFrame.ReleaseGently(); - Core::Get().mOnIncomingConnection.ReleaseGently(); - Core::Get().mOnPlayerRequestClass.ReleaseGently(); - Core::Get().mOnPlayerRequestSpawn.ReleaseGently(); - Core::Get().mOnPlayerSpawn.ReleaseGently(); - Core::Get().mOnPlayerWasted.ReleaseGently(); - Core::Get().mOnPlayerKilled.ReleaseGently(); - Core::Get().mOnPlayerEmbarking.ReleaseGently(); - Core::Get().mOnPlayerEmbarked.ReleaseGently(); - Core::Get().mOnPlayerDisembark.ReleaseGently(); - Core::Get().mOnPlayerRename.ReleaseGently(); - Core::Get().mOnPlayerState.ReleaseGently(); - Core::Get().mOnStateNone.ReleaseGently(); - Core::Get().mOnStateNormal.ReleaseGently(); - Core::Get().mOnStateAim.ReleaseGently(); - Core::Get().mOnStateDriver.ReleaseGently(); - Core::Get().mOnStatePassenger.ReleaseGently(); - Core::Get().mOnStateEnterDriver.ReleaseGently(); - Core::Get().mOnStateEnterPassenger.ReleaseGently(); - Core::Get().mOnStateExit.ReleaseGently(); - Core::Get().mOnStateUnspawned.ReleaseGently(); - Core::Get().mOnPlayerAction.ReleaseGently(); - Core::Get().mOnActionNone.ReleaseGently(); - Core::Get().mOnActionNormal.ReleaseGently(); - Core::Get().mOnActionAiming.ReleaseGently(); - Core::Get().mOnActionShooting.ReleaseGently(); - Core::Get().mOnActionJumping.ReleaseGently(); - Core::Get().mOnActionLieDown.ReleaseGently(); - Core::Get().mOnActionGettingUp.ReleaseGently(); - Core::Get().mOnActionJumpVehicle.ReleaseGently(); - Core::Get().mOnActionDriving.ReleaseGently(); - Core::Get().mOnActionDying.ReleaseGently(); - Core::Get().mOnActionWasted.ReleaseGently(); - Core::Get().mOnActionEmbarking.ReleaseGently(); - Core::Get().mOnActionDisembarking.ReleaseGently(); - Core::Get().mOnPlayerBurning.ReleaseGently(); - Core::Get().mOnPlayerCrouching.ReleaseGently(); - Core::Get().mOnPlayerGameKeys.ReleaseGently(); - Core::Get().mOnPlayerStartTyping.ReleaseGently(); - Core::Get().mOnPlayerStopTyping.ReleaseGently(); - Core::Get().mOnPlayerAway.ReleaseGently(); - Core::Get().mOnPlayerMessage.ReleaseGently(); - Core::Get().mOnPlayerCommand.ReleaseGently(); - Core::Get().mOnPlayerPrivateMessage.ReleaseGently(); - Core::Get().mOnPlayerKeyPress.ReleaseGently(); - Core::Get().mOnPlayerKeyRelease.ReleaseGently(); - Core::Get().mOnPlayerSpectate.ReleaseGently(); - Core::Get().mOnPlayerCrashreport.ReleaseGently(); - Core::Get().mOnVehicleExplode.ReleaseGently(); - Core::Get().mOnVehicleRespawn.ReleaseGently(); - Core::Get().mOnObjectShot.ReleaseGently(); - Core::Get().mOnObjectTouched.ReleaseGently(); - Core::Get().mOnObjectWorld.ReleaseGently(); - Core::Get().mOnObjectAlpha.ReleaseGently(); - Core::Get().mOnObjectReport.ReleaseGently(); - Core::Get().mOnPickupClaimed.ReleaseGently(); - Core::Get().mOnPickupCollected.ReleaseGently(); - Core::Get().mOnPickupRespawn.ReleaseGently(); - Core::Get().mOnPickupWorld.ReleaseGently(); - Core::Get().mOnPickupAlpha.ReleaseGently(); - Core::Get().mOnPickupAutomatic.ReleaseGently(); - Core::Get().mOnPickupAutoTimer.ReleaseGently(); - Core::Get().mOnCheckpointEntered.ReleaseGently(); - Core::Get().mOnCheckpointExited.ReleaseGently(); - Core::Get().mOnCheckpointWorld.ReleaseGently(); - Core::Get().mOnCheckpointRadius.ReleaseGently(); - Core::Get().mOnEntityPool.ReleaseGently(); - Core::Get().mOnClientScriptData.ReleaseGently(); - Core::Get().mOnPlayerUpdate.ReleaseGently(); - Core::Get().mOnVehicleUpdate.ReleaseGently(); - Core::Get().mOnPlayerHealth.ReleaseGently(); - Core::Get().mOnPlayerArmour.ReleaseGently(); - Core::Get().mOnPlayerWeapon.ReleaseGently(); - Core::Get().mOnPlayerHeading.ReleaseGently(); - Core::Get().mOnPlayerPosition.ReleaseGently(); - Core::Get().mOnPlayerOption.ReleaseGently(); - Core::Get().mOnPlayerAdmin.ReleaseGently(); - Core::Get().mOnPlayerWorld.ReleaseGently(); - Core::Get().mOnPlayerTeam.ReleaseGently(); - Core::Get().mOnPlayerSkin.ReleaseGently(); - Core::Get().mOnPlayerMoney.ReleaseGently(); - Core::Get().mOnPlayerScore.ReleaseGently(); - Core::Get().mOnPlayerWantedLevel.ReleaseGently(); - Core::Get().mOnPlayerImmunity.ReleaseGently(); - Core::Get().mOnPlayerAlpha.ReleaseGently(); - Core::Get().mOnVehicleColor.ReleaseGently(); - Core::Get().mOnVehicleHealth.ReleaseGently(); - Core::Get().mOnVehiclePosition.ReleaseGently(); - Core::Get().mOnVehicleRotation.ReleaseGently(); - Core::Get().mOnVehicleOption.ReleaseGently(); - Core::Get().mOnVehicleWorld.ReleaseGently(); - Core::Get().mOnVehicleImmunity.ReleaseGently(); - Core::Get().mOnVehiclePartStatus.ReleaseGently(); - Core::Get().mOnVehicleTyreStatus.ReleaseGently(); - Core::Get().mOnVehicleDamageData.ReleaseGently(); - Core::Get().mOnVehicleRadio.ReleaseGently(); - Core::Get().mOnVehicleHandlingRule.ReleaseGently(); - Core::Get().mOnServerOption.ReleaseGently(); - Core::Get().mOnScriptReload.ReleaseGently(); - Core::Get().mOnScriptLoaded.ReleaseGently(); -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetEvent(Int32 evid) -{ - switch (evid) + // Ignore the call if already initialized + if (!m_Events.IsNull()) { - case EVT_CUSTOMEVENT: return mOnCustomEvent; - case EVT_BLIPCREATED: return mOnBlipCreated; - case EVT_CHECKPOINTCREATED: return mOnCheckpointCreated; - case EVT_KEYBINDCREATED: return mOnKeybindCreated; - case EVT_OBJECTCREATED: return mOnObjectCreated; - case EVT_PICKUPCREATED: return mOnPickupCreated; - case EVT_PLAYERCREATED: return mOnPlayerCreated; - case EVT_VEHICLECREATED: return mOnVehicleCreated; - case EVT_BLIPDESTROYED: return mOnBlipDestroyed; - case EVT_CHECKPOINTDESTROYED: return mOnCheckpointDestroyed; - case EVT_KEYBINDDESTROYED: return mOnKeybindDestroyed; - case EVT_OBJECTDESTROYED: return mOnObjectDestroyed; - case EVT_PICKUPDESTROYED: return mOnPickupDestroyed; - case EVT_PLAYERDESTROYED: return mOnPlayerDestroyed; - case EVT_VEHICLEDESTROYED: return mOnVehicleDestroyed; - case EVT_BLIPCUSTOM: return mOnBlipCustom; - case EVT_CHECKPOINTCUSTOM: return mOnCheckpointCustom; - case EVT_KEYBINDCUSTOM: return mOnKeybindCustom; - case EVT_OBJECTCUSTOM: return mOnObjectCustom; - case EVT_PICKUPCUSTOM: return mOnPickupCustom; - case EVT_PLAYERCUSTOM: return mOnPlayerCustom; - case EVT_VEHICLECUSTOM: return mOnVehicleCustom; - case EVT_SERVERSTARTUP: return mOnServerStartup; - case EVT_SERVERSHUTDOWN: return mOnServerShutdown; - case EVT_SERVERFRAME: return mOnServerFrame; - case EVT_INCOMINGCONNECTION: return mOnIncomingConnection; - case EVT_PLAYERREQUESTCLASS: return mOnPlayerRequestClass; - case EVT_PLAYERREQUESTSPAWN: return mOnPlayerRequestSpawn; - case EVT_PLAYERSPAWN: return mOnPlayerSpawn; - case EVT_PLAYERWASTED: return mOnPlayerWasted; - case EVT_PLAYERKILLED: return mOnPlayerKilled; - case EVT_PLAYEREMBARKING: return mOnPlayerEmbarking; - case EVT_PLAYEREMBARKED: return mOnPlayerEmbarked; - case EVT_PLAYERDISEMBARK: return mOnPlayerDisembark; - case EVT_PLAYERRENAME: return mOnPlayerRename; - case EVT_PLAYERSTATE: return mOnPlayerState; - case EVT_STATENONE: return mOnStateNone; - case EVT_STATENORMAL: return mOnStateNormal; - case EVT_STATEAIM: return mOnStateAim; - case EVT_STATEDRIVER: return mOnStateDriver; - case EVT_STATEPASSENGER: return mOnStatePassenger; - case EVT_STATEENTERDRIVER: return mOnStateEnterDriver; - case EVT_STATEENTERPASSENGER: return mOnStateEnterPassenger; - case EVT_STATEEXIT: return mOnStateExit; - case EVT_STATEUNSPAWNED: return mOnStateUnspawned; - case EVT_PLAYERACTION: return mOnPlayerAction; - case EVT_ACTIONNONE: return mOnActionNone; - case EVT_ACTIONNORMAL: return mOnActionNormal; - case EVT_ACTIONAIMING: return mOnActionAiming; - case EVT_ACTIONSHOOTING: return mOnActionShooting; - case EVT_ACTIONJUMPING: return mOnActionJumping; - case EVT_ACTIONLIEDOWN: return mOnActionLieDown; - case EVT_ACTIONGETTINGUP: return mOnActionGettingUp; - case EVT_ACTIONJUMPVEHICLE: return mOnActionJumpVehicle; - case EVT_ACTIONDRIVING: return mOnActionDriving; - case EVT_ACTIONDYING: return mOnActionDying; - case EVT_ACTIONWASTED: return mOnActionWasted; - case EVT_ACTIONEMBARKING: return mOnActionEmbarking; - case EVT_ACTIONDISEMBARKING: return mOnActionDisembarking; - case EVT_PLAYERBURNING: return mOnPlayerBurning; - case EVT_PLAYERCROUCHING: return mOnPlayerCrouching; - case EVT_PLAYERGAMEKEYS: return mOnPlayerGameKeys; - case EVT_PLAYERSTARTTYPING: return mOnPlayerStartTyping; - case EVT_PLAYERSTOPTYPING: return mOnPlayerStopTyping; - case EVT_PLAYERAWAY: return mOnPlayerAway; - case EVT_PLAYERMESSAGE: return mOnPlayerMessage; - case EVT_PLAYERCOMMAND: return mOnPlayerCommand; - case EVT_PLAYERPRIVATEMESSAGE: return mOnPlayerPrivateMessage; - case EVT_PLAYERKEYPRESS: return mOnPlayerKeyPress; - case EVT_PLAYERKEYRELEASE: return mOnPlayerKeyRelease; - case EVT_PLAYERSPECTATE: return mOnPlayerSpectate; - case EVT_PLAYERCRASHREPORT: return mOnPlayerCrashreport; - case EVT_VEHICLEEXPLODE: return mOnVehicleExplode; - case EVT_VEHICLERESPAWN: return mOnVehicleRespawn; - case EVT_OBJECTSHOT: return mOnObjectShot; - case EVT_OBJECTTOUCHED: return mOnObjectTouched; - case EVT_OBJECTWORLD: return mOnObjectWorld; - case EVT_OBJECTALPHA: return mOnObjectAlpha; - case EVT_OBJECTREPORT: return mOnObjectReport; - case EVT_PICKUPCLAIMED: return mOnPickupClaimed; - case EVT_PICKUPCOLLECTED: return mOnPickupCollected; - case EVT_PICKUPRESPAWN: return mOnPickupRespawn; - case EVT_PICKUPWORLD: return mOnPickupWorld; - case EVT_PICKUPALPHA: return mOnPickupAlpha; - case EVT_PICKUPAUTOMATIC: return mOnPickupAutomatic; - case EVT_PICKUPAUTOTIMER: return mOnPickupAutoTimer; - case EVT_CHECKPOINTENTERED: return mOnCheckpointEntered; - case EVT_CHECKPOINTEXITED: return mOnCheckpointExited; - case EVT_CHECKPOINTWORLD: return mOnCheckpointWorld; - case EVT_CHECKPOINTRADIUS: return mOnCheckpointRadius; - case EVT_ENTITYPOOL: return mOnEntityPool; - case EVT_CLIENTSCRIPTDATA: return mOnClientScriptData; - case EVT_PLAYERUPDATE: return mOnPlayerUpdate; - case EVT_VEHICLEUPDATE: return mOnVehicleUpdate; - case EVT_PLAYERHEALTH: return mOnPlayerHealth; - case EVT_PLAYERARMOUR: return mOnPlayerArmour; - case EVT_PLAYERWEAPON: return mOnPlayerWeapon; - case EVT_PLAYERHEADING: return mOnPlayerHeading; - case EVT_PLAYERPOSITION: return mOnPlayerPosition; - case EVT_PLAYEROPTION: return mOnPlayerOption; - case EVT_PLAYERADMIN: return mOnPlayerAdmin; - case EVT_PLAYERWORLD: return mOnPlayerWorld; - case EVT_PLAYERTEAM: return mOnPlayerTeam; - case EVT_PLAYERSKIN: return mOnPlayerSkin; - case EVT_PLAYERMONEY: return mOnPlayerMoney; - case EVT_PLAYERSCORE: return mOnPlayerScore; - case EVT_PLAYERWANTEDLEVEL: return mOnPlayerWantedLevel; - case EVT_PLAYERIMMUNITY: return mOnPlayerImmunity; - case EVT_PLAYERALPHA: return mOnPlayerAlpha; - case EVT_VEHICLECOLOR: return mOnVehicleColor; - case EVT_VEHICLEHEALTH: return mOnVehicleHealth; - case EVT_VEHICLEPOSITION: return mOnVehiclePosition; - case EVT_VEHICLEROTATION: return mOnVehicleRotation; - case EVT_VEHICLEOPTION: return mOnVehicleOption; - case EVT_VEHICLEWORLD: return mOnVehicleWorld; - case EVT_VEHICLEIMMUNITY: return mOnVehicleImmunity; - case EVT_VEHICLEPARTSTATUS: return mOnVehiclePartStatus; - case EVT_VEHICLETYRESTATUS: return mOnVehicleTyreStatus; - case EVT_VEHICLEDAMAGEDATA: return mOnVehicleDamageData; - case EVT_VEHICLERADIO: return mOnVehicleRadio; - case EVT_VEHICLEHANDLINGRULE: return mOnVehicleHandlingRule; - case EVT_SERVEROPTION: return mOnServerOption; - case EVT_SCRIPTRELOAD: return mOnScriptReload; - case EVT_SCRIPTLOADED: return mOnScriptLoaded; - default: return NullFunction(); + return; } + // Create a new table on the stack + sq_newtableex(DefaultVM::Get(), 128); + // Grab the table object from the stack + m_Events = LightObj(-1, DefaultVM::Get()); + // Pop the table object from the stack + sq_pop(DefaultVM::Get(), 1); + // Proceed to initializing the events + InitSignalPair(mOnCustomEvent, m_Events, "CustomEvent"); + InitSignalPair(mOnBlipCreated, m_Events, "BlipCreated"); + InitSignalPair(mOnCheckpointCreated, m_Events, "CheckpointCreated"); + InitSignalPair(mOnKeybindCreated, m_Events, "KeybindCreated"); + InitSignalPair(mOnObjectCreated, m_Events, "ObjectCreated"); + InitSignalPair(mOnPickupCreated, m_Events, "PickupCreated"); + InitSignalPair(mOnPlayerCreated, m_Events, "PlayerCreated"); + InitSignalPair(mOnVehicleCreated, m_Events, "VehicleCreated"); + InitSignalPair(mOnBlipDestroyed, m_Events, "BlipDestroyed"); + InitSignalPair(mOnCheckpointDestroyed, m_Events, "CheckpointDestroyed"); + InitSignalPair(mOnKeybindDestroyed, m_Events, "KeybindDestroyed"); + InitSignalPair(mOnObjectDestroyed, m_Events, "ObjectDestroyed"); + InitSignalPair(mOnPickupDestroyed, m_Events, "PickupDestroyed"); + InitSignalPair(mOnPlayerDestroyed, m_Events, "PlayerDestroyed"); + InitSignalPair(mOnVehicleDestroyed, m_Events, "VehicleDestroyed"); + InitSignalPair(mOnBlipCustom, m_Events, "BlipCustom"); + InitSignalPair(mOnCheckpointCustom, m_Events, "CheckpointCustom"); + InitSignalPair(mOnKeybindCustom, m_Events, "KeybindCustom"); + InitSignalPair(mOnObjectCustom, m_Events, "ObjectCustom"); + InitSignalPair(mOnPickupCustom, m_Events, "PickupCustom"); + InitSignalPair(mOnPlayerCustom, m_Events, "PlayerCustom"); + InitSignalPair(mOnVehicleCustom, m_Events, "VehicleCustom"); + InitSignalPair(mOnServerStartup, m_Events, "ServerStartup"); + InitSignalPair(mOnServerShutdown, m_Events, "ServerShutdown"); + InitSignalPair(mOnServerFrame, m_Events, "ServerFrame"); + InitSignalPair(mOnIncomingConnection, m_Events, "IncomingConnection"); + InitSignalPair(mOnPlayerRequestClass, m_Events, "PlayerRequestClass"); + InitSignalPair(mOnPlayerRequestSpawn, m_Events, "PlayerRequestSpawn"); + InitSignalPair(mOnPlayerSpawn, m_Events, "PlayerSpawn"); + InitSignalPair(mOnPlayerWasted, m_Events, "PlayerWasted"); + InitSignalPair(mOnPlayerKilled, m_Events, "PlayerKilled"); + InitSignalPair(mOnPlayerEmbarking, m_Events, "PlayerEmbarking"); + InitSignalPair(mOnPlayerEmbarked, m_Events, "PlayerEmbarked"); + InitSignalPair(mOnPlayerDisembark, m_Events, "PlayerDisembark"); + InitSignalPair(mOnPlayerRename, m_Events, "PlayerRename"); + InitSignalPair(mOnPlayerState, m_Events, "PlayerState"); + InitSignalPair(mOnStateNone, m_Events, "StateNone"); + InitSignalPair(mOnStateNormal, m_Events, "StateNormal"); + InitSignalPair(mOnStateAim, m_Events, "StateAim"); + InitSignalPair(mOnStateDriver, m_Events, "StateDriver"); + InitSignalPair(mOnStatePassenger, m_Events, "StatePassenger"); + InitSignalPair(mOnStateEnterDriver, m_Events, "StateEnterDriver"); + InitSignalPair(mOnStateEnterPassenger, m_Events, "StateEnterPassenger"); + InitSignalPair(mOnStateExit, m_Events, "StateExit"); + InitSignalPair(mOnStateUnspawned, m_Events, "StateUnspawned"); + InitSignalPair(mOnPlayerAction, m_Events, "PlayerAction"); + InitSignalPair(mOnActionNone, m_Events, "ActionNone"); + InitSignalPair(mOnActionNormal, m_Events, "ActionNormal"); + InitSignalPair(mOnActionAiming, m_Events, "ActionAiming"); + InitSignalPair(mOnActionShooting, m_Events, "ActionShooting"); + InitSignalPair(mOnActionJumping, m_Events, "ActionJumping"); + InitSignalPair(mOnActionLieDown, m_Events, "ActionLieDown"); + InitSignalPair(mOnActionGettingUp, m_Events, "ActionGettingUp"); + InitSignalPair(mOnActionJumpVehicle, m_Events, "ActionJumpVehicle"); + InitSignalPair(mOnActionDriving, m_Events, "ActionDriving"); + InitSignalPair(mOnActionDying, m_Events, "ActionDying"); + InitSignalPair(mOnActionWasted, m_Events, "ActionWasted"); + InitSignalPair(mOnActionEmbarking, m_Events, "ActionEmbarking"); + InitSignalPair(mOnActionDisembarking, m_Events, "ActionDisembarking"); + InitSignalPair(mOnPlayerBurning, m_Events, "PlayerBurning"); + InitSignalPair(mOnPlayerCrouching, m_Events, "PlayerCrouching"); + InitSignalPair(mOnPlayerGameKeys, m_Events, "PlayerGameKeys"); + InitSignalPair(mOnPlayerStartTyping, m_Events, "PlayerStartTyping"); + InitSignalPair(mOnPlayerStopTyping, m_Events, "PlayerStopTyping"); + InitSignalPair(mOnPlayerAway, m_Events, "PlayerAway"); + InitSignalPair(mOnPlayerMessage, m_Events, "PlayerMessage"); + InitSignalPair(mOnPlayerCommand, m_Events, "PlayerCommand"); + InitSignalPair(mOnPlayerPrivateMessage, m_Events, "PlayerPrivateMessage"); + InitSignalPair(mOnPlayerKeyPress, m_Events, "PlayerKeyPress"); + InitSignalPair(mOnPlayerKeyRelease, m_Events, "PlayerKeyRelease"); + InitSignalPair(mOnPlayerSpectate, m_Events, "PlayerSpectate"); + InitSignalPair(mOnPlayerCrashreport, m_Events, "PlayerCrashreport"); + InitSignalPair(mOnVehicleExplode, m_Events, "VehicleExplode"); + InitSignalPair(mOnVehicleRespawn, m_Events, "VehicleRespawn"); + InitSignalPair(mOnObjectShot, m_Events, "ObjectShot"); + InitSignalPair(mOnObjectTouched, m_Events, "ObjectTouched"); + InitSignalPair(mOnObjectWorld, m_Events, "ObjectWorld"); + InitSignalPair(mOnObjectAlpha, m_Events, "ObjectAlpha"); + InitSignalPair(mOnObjectReport, m_Events, "ObjectReport"); + InitSignalPair(mOnPickupClaimed, m_Events, "PickupClaimed"); + InitSignalPair(mOnPickupCollected, m_Events, "PickupCollected"); + InitSignalPair(mOnPickupRespawn, m_Events, "PickupRespawn"); + InitSignalPair(mOnPickupWorld, m_Events, "PickupWorld"); + InitSignalPair(mOnPickupAlpha, m_Events, "PickupAlpha"); + InitSignalPair(mOnPickupAutomatic, m_Events, "PickupAutomatic"); + InitSignalPair(mOnPickupAutoTimer, m_Events, "PickupAutoTimer"); + InitSignalPair(mOnCheckpointEntered, m_Events, "CheckpointEntered"); + InitSignalPair(mOnCheckpointExited, m_Events, "CheckpointExited"); + InitSignalPair(mOnCheckpointWorld, m_Events, "CheckpointWorld"); + InitSignalPair(mOnCheckpointRadius, m_Events, "CheckpointRadius"); + InitSignalPair(mOnEntityPool, m_Events, "EntityPool"); + InitSignalPair(mOnClientScriptData, m_Events, "ClientScriptData"); + InitSignalPair(mOnPlayerUpdate, m_Events, "PlayerUpdate"); + InitSignalPair(mOnVehicleUpdate, m_Events, "VehicleUpdate"); + InitSignalPair(mOnPlayerHealth, m_Events, "PlayerHealth"); + InitSignalPair(mOnPlayerArmour, m_Events, "PlayerArmour"); + InitSignalPair(mOnPlayerWeapon, m_Events, "PlayerWeapon"); + InitSignalPair(mOnPlayerHeading, m_Events, "PlayerHeading"); + InitSignalPair(mOnPlayerPosition, m_Events, "PlayerPosition"); + InitSignalPair(mOnPlayerOption, m_Events, "PlayerOption"); + InitSignalPair(mOnPlayerAdmin, m_Events, "PlayerAdmin"); + InitSignalPair(mOnPlayerWorld, m_Events, "PlayerWorld"); + InitSignalPair(mOnPlayerTeam, m_Events, "PlayerTeam"); + InitSignalPair(mOnPlayerSkin, m_Events, "PlayerSkin"); + InitSignalPair(mOnPlayerMoney, m_Events, "PlayerMoney"); + InitSignalPair(mOnPlayerScore, m_Events, "PlayerScore"); + InitSignalPair(mOnPlayerWantedLevel, m_Events, "PlayerWantedLevel"); + InitSignalPair(mOnPlayerImmunity, m_Events, "PlayerImmunity"); + InitSignalPair(mOnPlayerAlpha, m_Events, "PlayerAlpha"); + InitSignalPair(mOnVehicleColor, m_Events, "VehicleColor"); + InitSignalPair(mOnVehicleHealth, m_Events, "VehicleHealth"); + InitSignalPair(mOnVehiclePosition, m_Events, "VehiclePosition"); + InitSignalPair(mOnVehicleRotation, m_Events, "VehicleRotation"); + InitSignalPair(mOnVehicleOption, m_Events, "VehicleOption"); + InitSignalPair(mOnVehicleWorld, m_Events, "VehicleWorld"); + InitSignalPair(mOnVehicleImmunity, m_Events, "VehicleImmunity"); + InitSignalPair(mOnVehiclePartStatus, m_Events, "VehiclePartStatus"); + InitSignalPair(mOnVehicleTyreStatus, m_Events, "VehicleTyreStatus"); + InitSignalPair(mOnVehicleDamageData, m_Events, "VehicleDamageData"); + InitSignalPair(mOnVehicleRadio, m_Events, "VehicleRadio"); + InitSignalPair(mOnVehicleHandlingRule, m_Events, "VehicleHandlingRule"); + InitSignalPair(mOnServerOption, m_Events, "ServerOption"); + InitSignalPair(mOnScriptReload, m_Events, "ScriptReload"); + InitSignalPair(mOnScriptLoaded, m_Events, "ScriptLoaded"); } - // ------------------------------------------------------------------------------------------------ -Function & Core::GetBlipEvent(Int32 id, Int32 evid) +void Core::DropEvents() { - BlipInst & inst = m_Blips.at(id); - - switch (evid) - { - case EVT_BLIPDESTROYED: return inst.mOnDestroyed; - case EVT_BLIPCUSTOM: return inst.mOnCustom; - default: return NullFunction(); - } -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetCheckpointEvent(Int32 id, Int32 evid) -{ - CheckpointInst & inst = m_Checkpoints.at(id); - - switch (evid) - { - case EVT_CHECKPOINTDESTROYED: return inst.mOnDestroyed; - case EVT_CHECKPOINTCUSTOM: return inst.mOnCustom; - case EVT_CHECKPOINTENTERED: return inst.mOnEntered; - case EVT_CHECKPOINTEXITED: return inst.mOnExited; - case EVT_CHECKPOINTWORLD: return inst.mOnWorld; - case EVT_CHECKPOINTRADIUS: return inst.mOnRadius; - default: return NullFunction(); - } -} - - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetKeybindEvent(Int32 id, Int32 evid) -{ - KeybindInst & inst = m_Keybinds.at(id); - - switch (evid) - { - case EVT_KEYBINDDESTROYED: return inst.mOnDestroyed; - case EVT_KEYBINDCUSTOM: return inst.mOnCustom; - case EVT_PLAYERKEYPRESS: return inst.mOnKeyPress; - case EVT_PLAYERKEYRELEASE: return inst.mOnKeyRelease; - default: return NullFunction(); - } -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetObjectEvent(Int32 id, Int32 evid) -{ - ObjectInst & inst = m_Objects.at(id); - - switch (evid) - { - case EVT_OBJECTDESTROYED: return inst.mOnDestroyed; - case EVT_OBJECTCUSTOM: return inst.mOnCustom; - case EVT_OBJECTSHOT: return inst.mOnShot; - case EVT_OBJECTTOUCHED: return inst.mOnTouched; - case EVT_OBJECTWORLD: return inst.mOnWorld; - case EVT_OBJECTALPHA: return inst.mOnAlpha; - case EVT_OBJECTREPORT: return inst.mOnReport; - default: return NullFunction(); - } -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetPickupEvent(Int32 id, Int32 evid) -{ - PickupInst & inst = m_Pickups.at(id); - - switch (evid) - { - case EVT_PICKUPDESTROYED: return inst.mOnDestroyed; - case EVT_PICKUPCUSTOM: return inst.mOnCustom; - case EVT_PICKUPRESPAWN: return inst.mOnRespawn; - case EVT_PICKUPCLAIMED: return inst.mOnClaimed; - case EVT_PICKUPCOLLECTED: return inst.mOnCollected; - case EVT_PICKUPWORLD: return inst.mOnWorld; - case EVT_PICKUPALPHA: return inst.mOnAlpha; - case EVT_PICKUPAUTOMATIC: return inst.mOnAutomatic; - case EVT_PICKUPAUTOTIMER: return inst.mOnAutoTimer; - default: return NullFunction(); - } -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetPlayerEvent(Int32 id, Int32 evid) -{ - PlayerInst & inst = m_Players.at(id); - - switch (evid) - { - case EVT_PLAYERDESTROYED: return inst.mOnDestroyed; - case EVT_PLAYERCUSTOM: return inst.mOnCustom; - case EVT_PLAYERREQUESTCLASS: return inst.mOnRequestClass; - case EVT_PLAYERREQUESTSPAWN: return inst.mOnRequestSpawn; - case EVT_PLAYERSPAWN: return inst.mOnSpawn; - case EVT_PLAYERWASTED: return inst.mOnWasted; - case EVT_PLAYERKILLED: return inst.mOnKilled; - case EVT_PLAYEREMBARKING: return inst.mOnEmbarking; - case EVT_PLAYEREMBARKED: return inst.mOnEmbarked; - case EVT_PLAYERDISEMBARK: return inst.mOnDisembark; - case EVT_PLAYERRENAME: return inst.mOnRename; - case EVT_PLAYERSTATE: return inst.mOnState; - case EVT_STATENONE: return inst.mOnStateNone; - case EVT_STATENORMAL: return inst.mOnStateNormal; - case EVT_STATEAIM: return inst.mOnStateAim; - case EVT_STATEDRIVER: return inst.mOnStateDriver; - case EVT_STATEPASSENGER: return inst.mOnStatePassenger; - case EVT_STATEENTERDRIVER: return inst.mOnStateEnterDriver; - case EVT_STATEENTERPASSENGER: return inst.mOnStateEnterPassenger; - case EVT_STATEEXIT: return inst.mOnStateExit; - case EVT_STATEUNSPAWNED: return inst.mOnStateUnspawned; - case EVT_PLAYERACTION: return inst.mOnAction; - case EVT_ACTIONNONE: return inst.mOnActionNone; - case EVT_ACTIONNORMAL: return inst.mOnActionNormal; - case EVT_ACTIONAIMING: return inst.mOnActionAiming; - case EVT_ACTIONSHOOTING: return inst.mOnActionShooting; - case EVT_ACTIONJUMPING: return inst.mOnActionJumping; - case EVT_ACTIONLIEDOWN: return inst.mOnActionLieDown; - case EVT_ACTIONGETTINGUP: return inst.mOnActionGettingUp; - case EVT_ACTIONJUMPVEHICLE: return inst.mOnActionJumpVehicle; - case EVT_ACTIONDRIVING: return inst.mOnActionDriving; - case EVT_ACTIONDYING: return inst.mOnActionDying; - case EVT_ACTIONWASTED: return inst.mOnActionWasted; - case EVT_ACTIONEMBARKING: return inst.mOnActionEmbarking; - case EVT_ACTIONDISEMBARKING: return inst.mOnActionDisembarking; - case EVT_PLAYERBURNING: return inst.mOnBurning; - case EVT_PLAYERCROUCHING: return inst.mOnCrouching; - case EVT_PLAYERGAMEKEYS: return inst.mOnGameKeys; - case EVT_PLAYERSTARTTYPING: return inst.mOnStartTyping; - case EVT_PLAYERSTOPTYPING: return inst.mOnStopTyping; - case EVT_PLAYERAWAY: return inst.mOnAway; - case EVT_PLAYERMESSAGE: return inst.mOnMessage; - case EVT_PLAYERCOMMAND: return inst.mOnCommand; - case EVT_PLAYERPRIVATEMESSAGE: return inst.mOnPrivateMessage; - case EVT_PLAYERKEYPRESS: return inst.mOnKeyPress; - case EVT_PLAYERKEYRELEASE: return inst.mOnKeyRelease; - case EVT_PLAYERSPECTATE: return inst.mOnSpectate; - case EVT_PLAYERCRASHREPORT: return inst.mOnCrashreport; - case EVT_OBJECTSHOT: return inst.mOnObjectShot; - case EVT_OBJECTTOUCHED: return inst.mOnObjectTouched; - case EVT_PICKUPCLAIMED: return inst.mOnPickupClaimed; - case EVT_PICKUPCOLLECTED: return inst.mOnPickupCollected; - case EVT_CHECKPOINTENTERED: return inst.mOnCheckpointEntered; - case EVT_CHECKPOINTEXITED: return inst.mOnCheckpointExited; - case EVT_CLIENTSCRIPTDATA: return inst.mOnClientScriptData; - case EVT_PLAYERUPDATE: return inst.mOnUpdate; - case EVT_PLAYERHEALTH: return inst.mOnHealth; - case EVT_PLAYERARMOUR: return inst.mOnArmour; - case EVT_PLAYERWEAPON: return inst.mOnWeapon; - case EVT_PLAYERHEADING: return inst.mOnHeading; - case EVT_PLAYERPOSITION: return inst.mOnPosition; - case EVT_PLAYEROPTION: return inst.mOnOption; - case EVT_PLAYERADMIN: return inst.mOnAdmin; - case EVT_PLAYERWORLD: return inst.mOnWorld; - case EVT_PLAYERTEAM: return inst.mOnTeam; - case EVT_PLAYERSKIN: return inst.mOnSkin; - case EVT_PLAYERMONEY: return inst.mOnMoney; - case EVT_PLAYERSCORE: return inst.mOnScore; - case EVT_PLAYERWANTEDLEVEL: return inst.mOnWantedLevel; - case EVT_PLAYERIMMUNITY: return inst.mOnImmunity; - case EVT_PLAYERALPHA: return inst.mOnAlpha; - default: return NullFunction(); - } -} - -// ------------------------------------------------------------------------------------------------ -Function & Core::GetVehicleEvent(Int32 id, Int32 evid) -{ - VehicleInst & inst = m_Vehicles.at(id); - - switch (evid) - { - case EVT_PLAYEREMBARKING: return inst.mOnEmbarking; - case EVT_PLAYEREMBARKED: return inst.mOnEmbarked; - case EVT_PLAYERDISEMBARK: return inst.mOnDisembark; - case EVT_VEHICLEEXPLODE: return inst.mOnExplode; - case EVT_VEHICLERESPAWN: return inst.mOnRespawn; - case EVT_VEHICLEUPDATE: return inst.mOnUpdate; - case EVT_VEHICLECOLOR: return inst.mOnColor; - case EVT_VEHICLEHEALTH: return inst.mOnHealth; - case EVT_VEHICLEPOSITION: return inst.mOnPosition; - case EVT_VEHICLEROTATION: return inst.mOnRotation; - case EVT_VEHICLEOPTION: return inst.mOnOption; - case EVT_VEHICLEWORLD: return inst.mOnWorld; - case EVT_VEHICLEIMMUNITY: return inst.mOnImmunity; - case EVT_VEHICLEPARTSTATUS: return inst.mOnPartStatus; - case EVT_VEHICLETYRESTATUS: return inst.mOnTyreStatus; - case EVT_VEHICLEDAMAGEDATA: return inst.mOnDamageData; - case EVT_VEHICLERADIO: return inst.mOnRadio; - case EVT_VEHICLEHANDLINGRULE: return inst.mOnHandlingRule; - default: return NullFunction(); - } + ResetSignalPair(mOnCustomEvent); + ResetSignalPair(mOnBlipCreated); + ResetSignalPair(mOnCheckpointCreated); + ResetSignalPair(mOnKeybindCreated); + ResetSignalPair(mOnObjectCreated); + ResetSignalPair(mOnPickupCreated); + ResetSignalPair(mOnPlayerCreated); + ResetSignalPair(mOnVehicleCreated); + ResetSignalPair(mOnBlipDestroyed); + ResetSignalPair(mOnCheckpointDestroyed); + ResetSignalPair(mOnKeybindDestroyed); + ResetSignalPair(mOnObjectDestroyed); + ResetSignalPair(mOnPickupDestroyed); + ResetSignalPair(mOnPlayerDestroyed); + ResetSignalPair(mOnVehicleDestroyed); + ResetSignalPair(mOnBlipCustom); + ResetSignalPair(mOnCheckpointCustom); + ResetSignalPair(mOnKeybindCustom); + ResetSignalPair(mOnObjectCustom); + ResetSignalPair(mOnPickupCustom); + ResetSignalPair(mOnPlayerCustom); + ResetSignalPair(mOnVehicleCustom); + ResetSignalPair(mOnServerStartup); + ResetSignalPair(mOnServerShutdown); + ResetSignalPair(mOnServerFrame); + ResetSignalPair(mOnIncomingConnection); + ResetSignalPair(mOnPlayerRequestClass); + ResetSignalPair(mOnPlayerRequestSpawn); + ResetSignalPair(mOnPlayerSpawn); + ResetSignalPair(mOnPlayerWasted); + ResetSignalPair(mOnPlayerKilled); + ResetSignalPair(mOnPlayerEmbarking); + ResetSignalPair(mOnPlayerEmbarked); + ResetSignalPair(mOnPlayerDisembark); + ResetSignalPair(mOnPlayerRename); + ResetSignalPair(mOnPlayerState); + ResetSignalPair(mOnStateNone); + ResetSignalPair(mOnStateNormal); + ResetSignalPair(mOnStateAim); + ResetSignalPair(mOnStateDriver); + ResetSignalPair(mOnStatePassenger); + ResetSignalPair(mOnStateEnterDriver); + ResetSignalPair(mOnStateEnterPassenger); + ResetSignalPair(mOnStateExit); + ResetSignalPair(mOnStateUnspawned); + ResetSignalPair(mOnPlayerAction); + ResetSignalPair(mOnActionNone); + ResetSignalPair(mOnActionNormal); + ResetSignalPair(mOnActionAiming); + ResetSignalPair(mOnActionShooting); + ResetSignalPair(mOnActionJumping); + ResetSignalPair(mOnActionLieDown); + ResetSignalPair(mOnActionGettingUp); + ResetSignalPair(mOnActionJumpVehicle); + ResetSignalPair(mOnActionDriving); + ResetSignalPair(mOnActionDying); + ResetSignalPair(mOnActionWasted); + ResetSignalPair(mOnActionEmbarking); + ResetSignalPair(mOnActionDisembarking); + ResetSignalPair(mOnPlayerBurning); + ResetSignalPair(mOnPlayerCrouching); + ResetSignalPair(mOnPlayerGameKeys); + ResetSignalPair(mOnPlayerStartTyping); + ResetSignalPair(mOnPlayerStopTyping); + ResetSignalPair(mOnPlayerAway); + ResetSignalPair(mOnPlayerMessage); + ResetSignalPair(mOnPlayerCommand); + ResetSignalPair(mOnPlayerPrivateMessage); + ResetSignalPair(mOnPlayerKeyPress); + ResetSignalPair(mOnPlayerKeyRelease); + ResetSignalPair(mOnPlayerSpectate); + ResetSignalPair(mOnPlayerCrashreport); + ResetSignalPair(mOnVehicleExplode); + ResetSignalPair(mOnVehicleRespawn); + ResetSignalPair(mOnObjectShot); + ResetSignalPair(mOnObjectTouched); + ResetSignalPair(mOnObjectWorld); + ResetSignalPair(mOnObjectAlpha); + ResetSignalPair(mOnObjectReport); + ResetSignalPair(mOnPickupClaimed); + ResetSignalPair(mOnPickupCollected); + ResetSignalPair(mOnPickupRespawn); + ResetSignalPair(mOnPickupWorld); + ResetSignalPair(mOnPickupAlpha); + ResetSignalPair(mOnPickupAutomatic); + ResetSignalPair(mOnPickupAutoTimer); + ResetSignalPair(mOnCheckpointEntered); + ResetSignalPair(mOnCheckpointExited); + ResetSignalPair(mOnCheckpointWorld); + ResetSignalPair(mOnCheckpointRadius); + ResetSignalPair(mOnEntityPool); + ResetSignalPair(mOnClientScriptData); + ResetSignalPair(mOnPlayerUpdate); + ResetSignalPair(mOnVehicleUpdate); + ResetSignalPair(mOnPlayerHealth); + ResetSignalPair(mOnPlayerArmour); + ResetSignalPair(mOnPlayerWeapon); + ResetSignalPair(mOnPlayerHeading); + ResetSignalPair(mOnPlayerPosition); + ResetSignalPair(mOnPlayerOption); + ResetSignalPair(mOnPlayerAdmin); + ResetSignalPair(mOnPlayerWorld); + ResetSignalPair(mOnPlayerTeam); + ResetSignalPair(mOnPlayerSkin); + ResetSignalPair(mOnPlayerMoney); + ResetSignalPair(mOnPlayerScore); + ResetSignalPair(mOnPlayerWantedLevel); + ResetSignalPair(mOnPlayerImmunity); + ResetSignalPair(mOnPlayerAlpha); + ResetSignalPair(mOnVehicleColor); + ResetSignalPair(mOnVehicleHealth); + ResetSignalPair(mOnVehiclePosition); + ResetSignalPair(mOnVehicleRotation); + ResetSignalPair(mOnVehicleOption); + ResetSignalPair(mOnVehicleWorld); + ResetSignalPair(mOnVehicleImmunity); + ResetSignalPair(mOnVehiclePartStatus); + ResetSignalPair(mOnVehicleTyreStatus); + ResetSignalPair(mOnVehicleDamageData); + ResetSignalPair(mOnVehicleRadio); + ResetSignalPair(mOnVehicleHandlingRule); + ResetSignalPair(mOnServerOption); + ResetSignalPair(mOnScriptReload); + ResetSignalPair(mOnScriptLoaded); } } // Namespace:: SqMod diff --git a/source/Entity/Blip.cpp b/source/Entity/Blip.cpp index 8dcb3e80..80efa948 100644 --- a/source/Entity/Blip.cpp +++ b/source/Entity/Blip.cpp @@ -20,7 +20,7 @@ SQInteger CBlip::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CBlip::GetNull() +LightObj & CBlip::GetNull() { return Core::Get().GetNullBlip(); } @@ -72,7 +72,7 @@ CBlip & CBlip::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CBlip::GetData() +LightObj & CBlip::GetData() { // Validate the managed identifier Validate(); @@ -81,7 +81,7 @@ Object & CBlip::GetData() } // ------------------------------------------------------------------------------------------------ -void CBlip::SetData(Object & data) +void CBlip::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -90,7 +90,7 @@ void CBlip::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CBlip::Destroy(Int32 header, Object & payload) +bool CBlip::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -99,31 +99,16 @@ bool CBlip::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CBlip::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CBlip::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetBlipEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetBlip(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CBlip::CustomEvent(Int32 header, Object & payload) const +void CBlip::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -240,62 +225,62 @@ Int32 CBlip::GetColorA() const } // ------------------------------------------------------------------------------------------------ -static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, +static LightObj & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid) { return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, +static LightObj & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, +static LightObj & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid) { return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, +static LightObj & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, +static LightObj & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid) { return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, - Int32 sprid, Int32 header, Object & payload) +static LightObj & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, + Int32 sprid, Int32 header, LightObj & payload) { return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, +static LightObj & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color, Int32 sprid) { return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, - const Color4 & color, Int32 sprid, Int32 header, Object & payload) +static LightObj & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale, + const Color4 & color, Int32 sprid, Int32 header, LightObj & payload) { return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid, header, payload); @@ -312,18 +297,18 @@ void Register_CBlip(HSQUIRRELVM vm) // Static Values .SetStaticValue(_SC("MaxID"), CBlip::Max) // Core Properties + .Prop(_SC("On"), &CBlip::GetEvents) .Prop(_SC("ID"), &CBlip::GetID) .Prop(_SC("Tag"), &CBlip::GetTag, &CBlip::SetTag) .Prop(_SC("Data"), &CBlip::GetData, &CBlip::SetData) .Prop(_SC("Active"), &CBlip::IsActive) // Core Methods - .Func(_SC("Bind"), &CBlip::BindEvent) .FmtFunc(_SC("SetTag"), &CBlip::ApplyTag) .Func(_SC("CustomEvent"), &CBlip::CustomEvent) // Core Overloads .Overload< bool (CBlip::*)(void) >(_SC("Destroy"), &CBlip::Destroy) .Overload< bool (CBlip::*)(Int32) >(_SC("Destroy"), &CBlip::Destroy) - .Overload< bool (CBlip::*)(Int32, Object &) >(_SC("Destroy"), &CBlip::Destroy) + .Overload< bool (CBlip::*)(Int32, LightObj &) >(_SC("Destroy"), &CBlip::Destroy) // Properties .Prop(_SC("World"), &CBlip::GetWorld) .Prop(_SC("Scale"), &CBlip::GetScale) @@ -340,21 +325,21 @@ void Register_CBlip(HSQUIRRELVM vm) .Prop(_SC("Blue"), &CBlip::GetColorB) .Prop(_SC("Alpha"), &CBlip::GetColorA) // Static Overloads - .StaticOverload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) > + .StaticOverload< LightObj & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) > (_SC("CreateEx"), &Blip_CreateEx) - .StaticOverload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, LightObj &) > (_SC("CreateEx"), &Blip_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) > (_SC("CreateEx"), &Blip_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, LightObj &) > (_SC("CreateEx"), &Blip_CreateEx) - .StaticOverload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32) > + .StaticOverload< LightObj & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32) > (_SC("Create"), &Blip_Create) - .StaticOverload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, LightObj &) > (_SC("Create"), &Blip_Create) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32) > (_SC("Create"), &Blip_Create) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, LightObj &) > (_SC("Create"), &Blip_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CBlip::SqGetNull) diff --git a/source/Entity/Blip.hpp b/source/Entity/Blip.hpp index 278e276b..8e2e315d 100644 --- a/source/Entity/Blip.hpp +++ b/source/Entity/Blip.hpp @@ -20,17 +20,17 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -93,7 +93,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -129,19 +129,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed blip entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -149,23 +149,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed blip entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Retrieve the world in which the referenced blip entity exists. diff --git a/source/Entity/Checkpoint.cpp b/source/Entity/Checkpoint.cpp index 041358e9..8a8cf5ef 100644 --- a/source/Entity/Checkpoint.cpp +++ b/source/Entity/Checkpoint.cpp @@ -33,7 +33,7 @@ SQInteger CCheckpoint::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CCheckpoint::GetNull() +LightObj & CCheckpoint::GetNull() { return Core::Get().GetNullCheckpoint(); } @@ -85,7 +85,7 @@ CCheckpoint & CCheckpoint::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CCheckpoint::GetData() +LightObj & CCheckpoint::GetData() { // Validate the managed identifier Validate(); @@ -94,7 +94,7 @@ Object & CCheckpoint::GetData() } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::SetData(Object & data) +void CCheckpoint::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -103,7 +103,7 @@ void CCheckpoint::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CCheckpoint::Destroy(Int32 header, Object & payload) +bool CCheckpoint::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -112,31 +112,16 @@ bool CCheckpoint::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CCheckpoint::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetCheckpointEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetCheckpoint(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CCheckpoint::CustomEvent(Int32 header, Object & payload) const +void CCheckpoint::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -302,7 +287,7 @@ void CCheckpoint::SetRadius(Float32 radius) } // ------------------------------------------------------------------------------------------------ -Object & CCheckpoint::GetOwner() const +LightObj & CCheckpoint::GetOwner() const { // Validate the managed identifier Validate(); @@ -488,32 +473,32 @@ void CCheckpoint::SetColorA(Int32 a) const } // ------------------------------------------------------------------------------------------------ -static Object & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, +static LightObj & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius) { return Core::Get().NewCheckpoint(-1, world, sphere, x, y, z, r, g, b, a, radius, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, +static LightObj & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { return Core::Get().NewCheckpoint(-1, world, sphere, x, y, z, r, g, b, a, radius, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos, +static LightObj & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, Float32 radius) { return Core::Get().NewCheckpoint(-1, world, sphere, pos.x, pos.y, pos.z, color.r, color.g, color.b, color.a, radius, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos, - const Color4 & color, Float32 radius, Int32 header, Object & payload) +static LightObj & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos, + const Color4 & color, Float32 radius, Int32 header, LightObj & payload) { return Core::Get().NewCheckpoint(-1, world, sphere, pos.x, pos.y, pos.z, color.r, color.g, color.b, color.a, radius, header, payload); @@ -530,18 +515,18 @@ void Register_CCheckpoint(HSQUIRRELVM vm) // Static Values .SetStaticValue(_SC("MaxID"), CCheckpoint::Max) // Core Properties + .Prop(_SC("On"), &CCheckpoint::GetEvents) .Prop(_SC("ID"), &CCheckpoint::GetID) .Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag) .Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData) .Prop(_SC("Active"), &CCheckpoint::IsActive) // Core Methods - .Func(_SC("Bind"), &CCheckpoint::BindEvent) .FmtFunc(_SC("SetTag"), &CCheckpoint::ApplyTag) .Func(_SC("CustomEvent"), &CCheckpoint::CustomEvent) // Core Overloads .Overload< bool (CCheckpoint::*)(void) >(_SC("Destroy"), &CCheckpoint::Destroy) .Overload< bool (CCheckpoint::*)(Int32) >(_SC("Destroy"), &CCheckpoint::Destroy) - .Overload< bool (CCheckpoint::*)(Int32, Object &) >(_SC("Destroy"), &CCheckpoint::Destroy) + .Overload< bool (CCheckpoint::*)(Int32, LightObj &) >(_SC("Destroy"), &CCheckpoint::Destroy) // Properties .Prop(_SC("Sphere"), &CCheckpoint::IsSphere) .Prop(_SC("World"), &CCheckpoint::GetWorld, &CCheckpoint::SetWorld) @@ -569,13 +554,13 @@ void Register_CCheckpoint(HSQUIRRELVM vm) .Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8, Uint8) const > (_SC("SetColor"), &CCheckpoint::SetColorEx) // Static Overloads - .StaticOverload< Object & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) > + .StaticOverload< LightObj & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) > (_SC("CreateEx"), &Checkpoint_CreateEx) - .StaticOverload< Object & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, LightObj &) > (_SC("CreateEx"), &Checkpoint_CreateEx) - .StaticOverload< Object & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32) > + .StaticOverload< LightObj & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32) > (_SC("Create"), &Checkpoint_Create) - .StaticOverload< Object & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, LightObj &) > (_SC("Create"), &Checkpoint_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CCheckpoint::SqGetNull) diff --git a/source/Entity/Checkpoint.hpp b/source/Entity/Checkpoint.hpp index 1aab4591..0747f099 100644 --- a/source/Entity/Checkpoint.hpp +++ b/source/Entity/Checkpoint.hpp @@ -36,22 +36,22 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Prevent events from triggering themselves. */ - Uint32 m_CircularLocks; + Uint32 m_CircularLocks; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -114,7 +114,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -150,19 +150,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed checkpoint entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -170,23 +170,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed checkpoint entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * See if the managed checkpoint entity is streamed for the specified player. @@ -256,7 +256,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the owner of the managed checkpoint entity. */ - Object & GetOwner() const; + LightObj & GetOwner() const; /* -------------------------------------------------------------------------------------------- * Retrieve the owner identifier of the managed checkpoint entity. diff --git a/source/Entity/Keybind.cpp b/source/Entity/Keybind.cpp index d062cdb1..c01d773c 100644 --- a/source/Entity/Keybind.cpp +++ b/source/Entity/Keybind.cpp @@ -20,7 +20,7 @@ SQInteger CKeybind::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CKeybind::GetNull() +LightObj & CKeybind::GetNull() { return Core::Get().GetNullKeybind(); } @@ -72,7 +72,7 @@ CKeybind & CKeybind::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CKeybind::GetData() +LightObj & CKeybind::GetData() { // Validate the managed identifier Validate(); @@ -81,7 +81,7 @@ Object & CKeybind::GetData() } // ------------------------------------------------------------------------------------------------ -void CKeybind::SetData(Object & data) +void CKeybind::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -90,7 +90,7 @@ void CKeybind::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CKeybind::Destroy(Int32 header, Object & payload) +bool CKeybind::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -99,31 +99,16 @@ bool CKeybind::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CKeybind::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CKeybind::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetKeybindEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetKeybind(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CKeybind::CustomEvent(Int32 header, Object & payload) const +void CKeybind::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -168,28 +153,28 @@ bool CKeybind::IsRelease() const } // ------------------------------------------------------------------------------------------------ -static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, +static LightObj & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative) { return Core::Get().NewKeybind(slot, release, primary, secondary, alternative, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, - Int32 alternative, Int32 header, Object & payload) +static LightObj & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary, + Int32 alternative, Int32 header, LightObj & payload) { return Core::Get().NewKeybind(slot, release, primary, secondary, alternative, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative) +static LightObj & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative) { return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative, - Int32 header, Object & payload) +static LightObj & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative, + Int32 header, LightObj & payload) { return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, header, payload); } @@ -211,18 +196,18 @@ void Register_CKeybind(HSQUIRRELVM vm) // Static Values .SetStaticValue(_SC("MaxID"), CKeybind::Max) // Core Properties + .Prop(_SC("On"), &CKeybind::GetEvents) .Prop(_SC("ID"), &CKeybind::GetID) .Prop(_SC("Tag"), &CKeybind::GetTag, &CKeybind::SetTag) .Prop(_SC("Data"), &CKeybind::GetData, &CKeybind::SetData) .Prop(_SC("Active"), &CKeybind::IsActive) // Core Methods - .Func(_SC("Bind"), &CKeybind::BindEvent) .FmtFunc(_SC("SetTag"), &CKeybind::ApplyTag) .Func(_SC("CustomEvent"), &CKeybind::CustomEvent) // Core Overloads .Overload< bool (CKeybind::*)(void) >(_SC("Destroy"), &CKeybind::Destroy) .Overload< bool (CKeybind::*)(Int32) >(_SC("Destroy"), &CKeybind::Destroy) - .Overload< bool (CKeybind::*)(Int32, Object &) >(_SC("Destroy"), &CKeybind::Destroy) + .Overload< bool (CKeybind::*)(Int32, LightObj &) >(_SC("Destroy"), &CKeybind::Destroy) // Properties .Prop(_SC("First"), &CKeybind::GetFirst) .Prop(_SC("Second"), &CKeybind::GetSecond) @@ -231,13 +216,13 @@ void Register_CKeybind(HSQUIRRELVM vm) // Static Functions .StaticFunc(_SC("UnusedSlot"), &Keybind_UnusedSlot) // Static Overloads - .StaticOverload< Object & (*)(Int32, bool, Int32, Int32, Int32) > + .StaticOverload< LightObj & (*)(Int32, bool, Int32, Int32, Int32) > (_SC("CreateEx"), &Keybind_CreateEx) - .StaticOverload< Object & (*)(Int32, bool, Int32, Int32, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, bool, Int32, Int32, Int32, Int32, LightObj &) > (_SC("CreateEx"), &Keybind_CreateEx) - .StaticOverload< Object & (*)(bool, Int32, Int32, Int32) > + .StaticOverload< LightObj & (*)(bool, Int32, Int32, Int32) > (_SC("Create"), &Keybind_Create) - .StaticOverload< Object & (*)(bool, Int32, Int32, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(bool, Int32, Int32, Int32, Int32, LightObj &) > (_SC("Create"), &Keybind_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CKeybind::SqGetNull) diff --git a/source/Entity/Keybind.hpp b/source/Entity/Keybind.hpp index a8143926..799de2eb 100644 --- a/source/Entity/Keybind.hpp +++ b/source/Entity/Keybind.hpp @@ -20,17 +20,17 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -93,7 +93,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -129,19 +129,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed destroy entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -149,23 +149,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed destroy entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Retrieve the first key code of the managed keybind entity. diff --git a/source/Entity/Object.cpp b/source/Entity/Object.cpp index 40a5bb83..1ad36cb8 100644 --- a/source/Entity/Object.cpp +++ b/source/Entity/Object.cpp @@ -27,7 +27,7 @@ SQInteger CObject::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CObject::GetNull() +LightObj & CObject::GetNull() { return Core::Get().GetNullObject(); } @@ -85,7 +85,7 @@ CObject & CObject::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CObject::GetData() +LightObj & CObject::GetData() { // Validate the managed identifier Validate(); @@ -94,7 +94,7 @@ Object & CObject::GetData() } // ------------------------------------------------------------------------------------------------ -void CObject::SetData(Object & data) +void CObject::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -103,7 +103,7 @@ void CObject::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CObject::Destroy(Int32 header, Object & payload) +bool CObject::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -112,31 +112,16 @@ bool CObject::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CObject::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CObject::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetObjectEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetObject(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CObject::CustomEvent(Int32 header, Object & payload) const +void CObject::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -854,27 +839,27 @@ void CObject::RotateByEulerZ(Float32 z) const } // ------------------------------------------------------------------------------------------------ -static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, +static LightObj & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha) { - return Core::Get().NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullObject()); + return Core::Get().NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, - Int32 alpha, Int32 header, Object & payload) +static LightObj & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, + Int32 alpha, Int32 header, LightObj & payload) { return Core::Get().NewObject(model, world, x, y, z, alpha, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha) +static LightObj & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha) { return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha, - Int32 header, Object & payload) +static LightObj & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha, + Int32 header, LightObj & payload) { return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload); } @@ -897,18 +882,18 @@ void Register_CObject(HSQUIRRELVM vm) .Var(_SC("RotateToEulerDuration"), &CObject::mRotateToEulerDuration) .Var(_SC("RotateByEulerDuration"), &CObject::mRotateByEulerDuration) // Core Properties + .Prop(_SC("On"), &CObject::GetEvents) .Prop(_SC("ID"), &CObject::GetID) .Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag) .Prop(_SC("Data"), &CObject::GetData, &CObject::SetData) .Prop(_SC("Active"), &CObject::IsActive) // Core Methods - .Func(_SC("Bind"), &CObject::BindEvent) .FmtFunc(_SC("SetTag"), &CObject::ApplyTag) .Func(_SC("CustomEvent"), &CObject::CustomEvent) // Core Overloads .Overload< bool (CObject::*)(void) >(_SC("Destroy"), &CObject::Destroy) .Overload< bool (CObject::*)(Int32) >(_SC("Destroy"), &CObject::Destroy) - .Overload< bool (CObject::*)(Int32, Object &) >(_SC("Destroy"), &CObject::Destroy) + .Overload< bool (CObject::*)(Int32, LightObj &) >(_SC("Destroy"), &CObject::Destroy) // Properties .Prop(_SC("Model"), &CObject::GetModel) .Prop(_SC("World"), &CObject::GetWorld, &CObject::SetWorld) @@ -982,13 +967,13 @@ void Register_CObject(HSQUIRRELVM vm) .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("RotateByEuler"), &CObject::RotateByEulerEx) // Static Overloads - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32) > (_SC("CreateEx"), &Object_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Int32, LightObj &) > (_SC("CreateEx"), &Object_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32) > (_SC("Create"), &Object_Create) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, Int32, LightObj &) > (_SC("Create"), &Object_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CObject::SqGetNull) diff --git a/source/Entity/Object.hpp b/source/Entity/Object.hpp index 125731bd..cc3b11c8 100644 --- a/source/Entity/Object.hpp +++ b/source/Entity/Object.hpp @@ -34,22 +34,22 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Prevent events from triggering themselves. */ - Uint32 m_CircularLocks; + Uint32 m_CircularLocks; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -130,7 +130,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -166,19 +166,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed object entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -186,23 +186,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed object entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * See if the managed object entity is streamed for the specified player. diff --git a/source/Entity/Pickup.cpp b/source/Entity/Pickup.cpp index 84b8dc83..9acbe125 100644 --- a/source/Entity/Pickup.cpp +++ b/source/Entity/Pickup.cpp @@ -25,7 +25,7 @@ SQInteger CPickup::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CPickup::GetNull() +LightObj & CPickup::GetNull() { return Core::Get().GetNullPickup(); } @@ -77,7 +77,7 @@ CPickup & CPickup::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CPickup::GetData() +LightObj & CPickup::GetData() { // Validate the managed identifier Validate(); @@ -86,7 +86,7 @@ Object & CPickup::GetData() } // ------------------------------------------------------------------------------------------------ -void CPickup::SetData(Object & data) +void CPickup::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -95,7 +95,7 @@ void CPickup::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CPickup::Destroy(Int32 header, Object & payload) +bool CPickup::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -104,31 +104,16 @@ bool CPickup::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CPickup::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CPickup::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetPickupEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetPickup(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CPickup::CustomEvent(Int32 header, Object & payload) const +void CPickup::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -413,30 +398,30 @@ void CPickup::SetPositionZ(Float32 z) const } // ------------------------------------------------------------------------------------------------ -static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, +static LightObj & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic) { return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, +static LightObj & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity, Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic, - Int32 header, Object & payload) + Int32 header, LightObj & payload) { return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, +static LightObj & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, Int32 alpha, bool automatic) { return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, - Int32 alpha, bool automatic, Int32 header, Object & payload) +static LightObj & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos, + Int32 alpha, bool automatic, Int32 header, LightObj & payload) { return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic, header, payload); @@ -453,18 +438,18 @@ void Register_CPickup(HSQUIRRELVM vm) // Static Values .SetStaticValue(_SC("MaxID"), CPickup::Max) // Core Properties + .Prop(_SC("On"), &CPickup::GetEvents) .Prop(_SC("ID"), &CPickup::GetID) .Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag) .Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData) .Prop(_SC("Active"), &CPickup::IsActive) // Core Methods - .Func(_SC("Bind"), &CPickup::BindEvent) .FmtFunc(_SC("SetTag"), &CPickup::ApplyTag) .Func(_SC("CustomEvent"), &CPickup::CustomEvent) // Core Overloads .Overload< bool (CPickup::*)(void) >(_SC("Destroy"), &CPickup::Destroy) .Overload< bool (CPickup::*)(Int32) >(_SC("Destroy"), &CPickup::Destroy) - .Overload< bool (CPickup::*)(Int32, Object &) >(_SC("Destroy"), &CPickup::Destroy) + .Overload< bool (CPickup::*)(Int32, LightObj &) >(_SC("Destroy"), &CPickup::Destroy) // Properties .Prop(_SC("Model"), &CPickup::GetModel) .Prop(_SC("World"), &CPickup::GetWorld, &CPickup::SetWorld) @@ -485,13 +470,13 @@ void Register_CPickup(HSQUIRRELVM vm) .Func(_SC("SetPos"), &CPickup::SetPositionEx) .Func(_SC("SetPosition"), &CPickup::SetPositionEx) // Static Overloads - .StaticOverload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) > + .StaticOverload< LightObj & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) > (_SC("CreateEx"), &Pickup_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool, Int32, LightObj &) > (_SC("CreateEx"), &Pickup_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool) > + .StaticOverload< LightObj & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool) > (_SC("Create"), &Pickup_Create) - .StaticOverload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool, Int32, LightObj &) > (_SC("Create"), &Pickup_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CPickup::SqGetNull) diff --git a/source/Entity/Pickup.hpp b/source/Entity/Pickup.hpp index 90f38991..c68bc102 100644 --- a/source/Entity/Pickup.hpp +++ b/source/Entity/Pickup.hpp @@ -34,22 +34,22 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Prevent events from triggering themselves. */ - Uint32 m_CircularLocks; + Uint32 m_CircularLocks; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -112,7 +112,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -148,19 +148,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed pickup entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -168,23 +168,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed pickup entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * See if the managed pickup entity is streamed for the specified player. diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp index fde2a900..3d815a6f 100644 --- a/source/Entity/Player.cpp +++ b/source/Entity/Player.cpp @@ -41,7 +41,7 @@ SQInteger CPlayer::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::GetNull() +LightObj & CPlayer::GetNull() { return Core::Get().GetNullPlayer(); } @@ -107,7 +107,7 @@ CPlayer & CPlayer::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::GetData() +LightObj & CPlayer::GetData() { // Validate the managed identifier Validate(); @@ -116,7 +116,7 @@ Object & CPlayer::GetData() } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetData(Object & data) +void CPlayer::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -125,31 +125,16 @@ void CPlayer::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -void CPlayer::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CPlayer::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetPlayerEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetPlayer(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CPlayer::CustomEvent(Int32 header, Object & payload) const +void CPlayer::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -265,13 +250,13 @@ void CPlayer::Kick() const Validate(); // Store the default header and payload Core::Get().GetPlayer(m_ID).mKickBanHeader = vcmpDisconnectReasonKick; - Core::Get().GetPlayer(m_ID).mKickBanPayload = NullObject(); + Core::Get().GetPlayer(m_ID).mKickBanPayload = NullLightObj(); // Perform the requested operation _Func->KickPlayer(m_ID); } // ------------------------------------------------------------------------------------------------ -void CPlayer::KickBecause(Int32 header, Object & payload) const +void CPlayer::KickBecause(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -289,13 +274,13 @@ void CPlayer::Ban() const Validate(); // Store the default header and payload Core::Get().GetPlayer(m_ID).mKickBanHeader = vcmpDisconnectReasonKick; - Core::Get().GetPlayer(m_ID).mKickBanPayload = NullObject(); + Core::Get().GetPlayer(m_ID).mKickBanPayload = NullLightObj(); // Perform the requested operation _Func->BanPlayer(m_ID); } // ------------------------------------------------------------------------------------------------ -void CPlayer::BanBecause(Int32 header, Object & payload) const +void CPlayer::BanBecause(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -379,11 +364,11 @@ Int32 CPlayer::GetOption(Int32 option_id) const // ------------------------------------------------------------------------------------------------ void CPlayer::SetOption(Int32 option_id, bool toggle) { - SetOptionEx(option_id, toggle, 0, NullObject()); + SetOptionEx(option_id, toggle, 0, NullLightObj()); } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +void CPlayer::SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -1099,7 +1084,7 @@ Int32 CPlayer::GetVehicleSlot() const } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::GetVehicle() const +LightObj & CPlayer::GetVehicle() const { // Validate the managed identifier Validate(); @@ -1112,7 +1097,7 @@ Object & CPlayer::GetVehicle() const return Core::Get().GetVehicle(id).mObj; } // Default to a null object - return NullObject(); + return NullLightObj(); } // ------------------------------------------------------------------------------------------------ @@ -1300,7 +1285,7 @@ void CPlayer::SetAnimation(Int32 anim, Int32 group) const } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::StandingOnVehicle() const +LightObj & CPlayer::StandingOnVehicle() const { // Validate the managed identifier Validate(); @@ -1313,11 +1298,11 @@ Object & CPlayer::StandingOnVehicle() const return Core::Get().GetVehicle(id).mObj; } // Default to a null object - return NullObject(); + return NullLightObj(); } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::StandingOnObject() const +LightObj & CPlayer::StandingOnObject() const { // Validate the managed identifier Validate(); @@ -1330,7 +1315,7 @@ Object & CPlayer::StandingOnObject() const return Core::Get().GetObject(id).mObj; } // Default to a null object - return NullObject(); + return NullLightObj(); } // ------------------------------------------------------------------------------------------------ @@ -1343,7 +1328,7 @@ bool CPlayer::IsAway() const } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::GetSpectator() const +LightObj & CPlayer::GetSpectator() const { // Validate the managed identifier Validate(); @@ -1356,7 +1341,7 @@ Object & CPlayer::GetSpectator() const return Core::Get().GetPlayer(id).mObj; } // Default to a null object - return NullObject(); + return NullLightObj(); } // ------------------------------------------------------------------------------------------------ @@ -1392,20 +1377,20 @@ void CPlayer::PlaySound(Int32 sound_id) const } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, +LightObj & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius) const { // Validate the managed identifier Validate(); // Perform the requested operation return Core::Get().NewCheckpoint(m_ID, world, sphere, x, y, z, r, g, b, a, radius, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, +LightObj & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload) const + Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -1415,7 +1400,7 @@ Object & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float3 } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, +LightObj & CPlayer::CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, Float32 radius) const { // Validate the managed identifier @@ -1423,12 +1408,12 @@ Object & CPlayer::CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos // Perform the requested operation return Core::Get().NewCheckpoint(m_ID, world, sphere, pos.x, pos.y, pos.z, color.r, color.g, color.b, color.a, radius, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } // ------------------------------------------------------------------------------------------------ -Object & CPlayer::CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, - Float32 radius, Int32 header, Object & payload) const +LightObj & CPlayer::CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, + Float32 radius, Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -1502,7 +1487,7 @@ void CPlayer::SetTrackPosition(SQInteger num) const } // ------------------------------------------------------------------------------------------------ -void CPlayer::SetTrackPositionEx(SQInteger num, Int32 header, const Object & payload) const +void CPlayer::SetTrackPositionEx(SQInteger num, Int32 header, const LightObj & payload) const { // Validate the managed identifier Validate(); @@ -2315,7 +2300,7 @@ SQInteger CPlayer::AnnounceEx(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -static const Object & Player_FindAuto(Object & by) +static const LightObj & Player_FindAuto(Object & by) { switch (by.GetType()) { @@ -2342,7 +2327,7 @@ static const Object & Player_FindAuto(Object & by) default: STHROWF("Unsupported search identifier"); } // Default to a null object - return NullObject(); + return NullLightObj(); } // ================================================================================================ @@ -2366,12 +2351,12 @@ void Register_CPlayer(HSQUIRRELVM vm) .Var(_SC("AnnouncePostfix"), &CPlayer::mAnnouncePostfix) .Var(_SC("LimitPrefixPostfixMessage"), &CPlayer::mLimitPrefixPostfixMessage) // Core Properties + .Prop(_SC("On"), &CPlayer::GetEvents) .Prop(_SC("ID"), &CPlayer::GetID) .Prop(_SC("Tag"), &CPlayer::GetTag, &CPlayer::SetTag) .Prop(_SC("Data"), &CPlayer::GetData, &CPlayer::SetData) .Prop(_SC("Active"), &CPlayer::IsActive) // Core Methods - .Func(_SC("Bind"), &CPlayer::BindEvent) .FmtFunc(_SC("SetTag"), &CPlayer::ApplyTag) .Func(_SC("CustomEvent"), &CPlayer::CustomEvent) // Properties @@ -2510,13 +2495,13 @@ void Register_CPlayer(HSQUIRRELVM vm) (_SC("SetAnimation"), &CPlayer::SetAnimation) .Overload< void (CPlayer::*)(Int32, Int32) const > (_SC("SetAnimation"), &CPlayer::SetAnimation) - .Overload< Object & (CPlayer::*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) const > + .Overload< LightObj & (CPlayer::*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) const > (_SC("CreateCheckpointEx"), &CPlayer::CreateCheckpointEx) - .Overload< Object & (CPlayer::*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) const > + .Overload< LightObj & (CPlayer::*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, LightObj &) const > (_SC("CreateCheckpointEx"), &CPlayer::CreateCheckpointEx) - .Overload< Object & (CPlayer::*)(Int32, bool, const Vector3 &, const Color4 &, Float32) const > + .Overload< LightObj & (CPlayer::*)(Int32, bool, const Vector3 &, const Color4 &, Float32) const > (_SC("CreateCheckpoint"), &CPlayer::CreateCheckpoint) - .Overload< Object & (CPlayer::*)(Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, Object &) const > + .Overload< LightObj & (CPlayer::*)(Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, LightObj &) const > (_SC("CreateCheckpoint"), &CPlayer::CreateCheckpoint) // Static Functions .StaticFunc(_SC("Find"), &Player_FindAuto) diff --git a/source/Entity/Player.hpp b/source/Entity/Player.hpp index edf6f0fb..e84ac144 100644 --- a/source/Entity/Player.hpp +++ b/source/Entity/Player.hpp @@ -45,27 +45,27 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Buffer used to generate client data. */ - Buffer m_Buffer; + Buffer m_Buffer; /* -------------------------------------------------------------------------------------------- * Prevent events from triggering themselves. */ - Uint32 m_CircularLocks; + Uint32 m_CircularLocks; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -181,7 +181,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -217,22 +217,22 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * See whether the managed player entity is connected. @@ -277,7 +277,7 @@ public: /* -------------------------------------------------------------------------------------------- * Kick the managed player entity from the server. */ - void KickBecause(Int32 header, Object & payload) const; + void KickBecause(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Ban the managed player entity from the server. @@ -287,7 +287,7 @@ public: /* -------------------------------------------------------------------------------------------- * Ban the managed player entity from the server. */ - void BanBecause(Int32 header, Object & payload) const; + void BanBecause(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Retrieve the key of the managed player entity. @@ -322,7 +322,7 @@ public: /* -------------------------------------------------------------------------------------------- * Modify the current option value of the managed player entity. */ - void SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); + void SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Retrieve the world in which the managed player entity exists. @@ -612,7 +612,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle in which the managed player entity is embarked. */ - Object & GetVehicle() const; + LightObj & GetVehicle() const; /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle identifier in which the managed player entity is embarked. @@ -707,12 +707,12 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the vehicle that the managed player entity is standing on. */ - Object & StandingOnVehicle() const; + LightObj & StandingOnVehicle() const; /* -------------------------------------------------------------------------------------------- * Retrieve the object that the managed player entity is standing on. */ - Object & StandingOnObject() const; + LightObj & StandingOnObject() const; /* -------------------------------------------------------------------------------------------- * See whether the managed player entity is away. @@ -722,7 +722,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the player that the managed player entity is spectating. */ - Object & GetSpectator() const; + LightObj & GetSpectator() const; /* -------------------------------------------------------------------------------------------- * Set the managed player entity to spectate the specified player entity. @@ -743,27 +743,27 @@ public: /* -------------------------------------------------------------------------------------------- * Create a checkpoint or sphere for this player. */ - Object & CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, + LightObj & CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius) const; /* -------------------------------------------------------------------------------------------- * Create a checkpoint or sphere for this player. */ - Object & CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, + LightObj & CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius, - Int32 header, Object & payload) const; + Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Create a checkpoint or sphere for this player. */ - Object & CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, + LightObj & CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, Float32 radius) const; /* -------------------------------------------------------------------------------------------- * Create a checkpoint or sphere for this player. */ - Object & CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, - Float32 radius, Int32 header, Object & payload) const; + LightObj & CreateCheckpoint(Int32 world, bool sphere, const Vector3 & pos, const Color4 & color, + Float32 radius, Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Retrieve the authority level of the managed player entity. @@ -798,7 +798,7 @@ public: /* -------------------------------------------------------------------------------------------- * Modify the amount of tracked position changes for the managed player entity. */ - void SetTrackPositionEx(SQInteger num, Int32 header, const Object & payload) const; + void SetTrackPositionEx(SQInteger num, Int32 header, const LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * Retrieve the amount of tracked heading changes for the managed player entity. diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp index cc057c30..3991b388 100644 --- a/source/Entity/Vehicle.cpp +++ b/source/Entity/Vehicle.cpp @@ -29,7 +29,7 @@ SQInteger CVehicle::SqGetNull(HSQUIRRELVM vm) } // ------------------------------------------------------------------------------------------------ -Object & CVehicle::GetNull() +LightObj & CVehicle::GetNull() { return Core::Get().GetNullVehicle(); } @@ -81,7 +81,7 @@ CVehicle & CVehicle::ApplyTag(const StackStrF & tag) } // ------------------------------------------------------------------------------------------------ -Object & CVehicle::GetData() +LightObj & CVehicle::GetData() { // Validate the managed identifier Validate(); @@ -90,7 +90,7 @@ Object & CVehicle::GetData() } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetData(Object & data) +void CVehicle::SetData(LightObj & data) { // Validate the managed identifier Validate(); @@ -99,7 +99,7 @@ void CVehicle::SetData(Object & data) } // ------------------------------------------------------------------------------------------------ -bool CVehicle::Destroy(Int32 header, Object & payload) +bool CVehicle::Destroy(Int32 header, LightObj & payload) { // Validate the managed identifier Validate(); @@ -108,31 +108,16 @@ bool CVehicle::Destroy(Int32 header, Object & payload) } // ------------------------------------------------------------------------------------------------ -void CVehicle::BindEvent(Int32 evid, Object & env, Function & func) const +LightObj & CVehicle::GetEvents() const { // Validate the managed identifier Validate(); - // Obtain the function instance called for this event - Function & event = Core::Get().GetVehicleEvent(m_ID, evid); - // Is the specified callback function null? - if (func.IsNull()) - { - event.ReleaseGently(); // Then release the current callback - } - // Does this function need a custom environment? - else if (env.IsNull()) - { - event = func; - } - // Assign the specified environment and function - else - { - event = Function(env.GetVM(), env, func.GetFunc()); - } + // Return the associated event table + return Core::Get().GetVehicle(m_ID).mEvents; } // ------------------------------------------------------------------------------------------------ -void CVehicle::CustomEvent(Int32 header, Object & payload) const +void CVehicle::CustomEvent(Int32 header, LightObj & payload) const { // Validate the managed identifier Validate(); @@ -184,12 +169,12 @@ void CVehicle::SetOption(Int32 option_id, bool toggle) // Prevent this event from triggering while executed BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION); // Now forward the event call - Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullObject()); + Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullLightObj()); } } // ------------------------------------------------------------------------------------------------ -void CVehicle::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +void CVehicle::SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload) { // Attempt to obtain the current value of the specified option const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); @@ -269,7 +254,7 @@ Int32 CVehicle::GetModel() const } // ------------------------------------------------------------------------------------------------ -Object & CVehicle::GetOccupant(Int32 slot) const +LightObj & CVehicle::GetOccupant(Int32 slot) const { // Validate the managed identifier Validate(); @@ -1725,30 +1710,30 @@ void CVehicle::SetRelativeTurnSpeedZ(Float32 z) const } // ------------------------------------------------------------------------------------------------ -static Object & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, +static LightObj & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, Int32 primary, Int32 secondary) { return Core::Get().NewVehicle(model, world, x, y, z, angle, primary, secondary, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, - Int32 primary, Int32 secondary, Int32 header, Object & payload) +static LightObj & Vehicle_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Float32 angle, + Int32 primary, Int32 secondary, Int32 header, LightObj & payload) { return Core::Get().NewVehicle(model, world, x, y, z, angle, primary, secondary, header, payload); } // ------------------------------------------------------------------------------------------------ -static Object & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, +static LightObj & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, Int32 primary, Int32 secondary) { return Core::Get().NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, - SQMOD_CREATE_DEFAULT, NullObject()); + SQMOD_CREATE_DEFAULT, NullLightObj()); } -static Object & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, - Int32 primary, Int32 secondary, Int32 header, Object & payload) +static LightObj & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Float32 angle, + Int32 primary, Int32 secondary, Int32 header, LightObj & payload) { return Core::Get().NewVehicle(model, world, pos.x, pos.y, pos.z, angle, primary, secondary, header, payload); @@ -1765,18 +1750,18 @@ void Register_CVehicle(HSQUIRRELVM vm) // Static Values .SetStaticValue(_SC("MaxID"), CVehicle::Max) // Core Properties + .Prop(_SC("On"), &CVehicle::GetEvents) .Prop(_SC("ID"), &CVehicle::GetID) .Prop(_SC("Tag"), &CVehicle::GetTag, &CVehicle::SetTag) .Prop(_SC("Data"), &CVehicle::GetData, &CVehicle::SetData) .Prop(_SC("Active"), &CVehicle::IsActive) // Core Methods - .Func(_SC("Bind"), &CVehicle::BindEvent) .FmtFunc(_SC("SetTag"), &CVehicle::ApplyTag) .Func(_SC("CustomEvent"), &CVehicle::CustomEvent) // Core Overloads .Overload< bool (CVehicle::*)(void) >(_SC("Destroy"), &CVehicle::Destroy) .Overload< bool (CVehicle::*)(Int32) >(_SC("Destroy"), &CVehicle::Destroy) - .Overload< bool (CVehicle::*)(Int32, Object &) >(_SC("Destroy"), &CVehicle::Destroy) + .Overload< bool (CVehicle::*)(Int32, LightObj &) >(_SC("Destroy"), &CVehicle::Destroy) // Properties .Prop(_SC("SyncSource"), &CVehicle::GetSyncSource) .Prop(_SC("SyncType"), &CVehicle::GetSyncType) @@ -1918,13 +1903,13 @@ void Register_CVehicle(HSQUIRRELVM vm) .Overload< bool (CVehicle::*)(CPlayer &, Int32, bool, bool) const > (_SC("Embark"), &CVehicle::Embark) // Static Overloads - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Float32, Int32, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Float32, Int32, Int32) > (_SC("CreateEx"), &Vehicle_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Float32, Int32, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Float32, Int32, Int32, Int32, LightObj &) > (_SC("CreateEx"), &Vehicle_CreateEx) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Float32, Int32, Int32) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Float32, Int32, Int32) > (_SC("Create"), &Vehicle_Create) - .StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Float32, Int32, Int32, Int32, Object &) > + .StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Float32, Int32, Int32, Int32, LightObj &) > (_SC("Create"), &Vehicle_Create) // Raw Squirrel Methods .SquirrelFunc(_SC("NullInst"), &CVehicle::SqGetNull) diff --git a/source/Entity/Vehicle.hpp b/source/Entity/Vehicle.hpp index 8919271c..26fc7cd9 100644 --- a/source/Entity/Vehicle.hpp +++ b/source/Entity/Vehicle.hpp @@ -40,22 +40,22 @@ private: /* -------------------------------------------------------------------------------------------- * Identifier of the managed entity. */ - Int32 m_ID; + Int32 m_ID; /* -------------------------------------------------------------------------------------------- * User tag associated with this instance. */ - String m_Tag; + String m_Tag; /* -------------------------------------------------------------------------------------------- * User data associated with this instance. */ - Object m_Data; + LightObj m_Data; /* -------------------------------------------------------------------------------------------- * Prevent events from triggering themselves. */ - Uint32 m_CircularLocks; + Uint32 m_CircularLocks; /* -------------------------------------------------------------------------------------------- * Base constructor. @@ -118,7 +118,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated null entity instance. */ - static Object & GetNull(); + static LightObj & GetNull(); /* -------------------------------------------------------------------------------------------- * Retrieve the identifier of the entity managed by this instance. @@ -154,19 +154,19 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the associated user data. */ - Object & GetData(); + LightObj & GetData(); /* -------------------------------------------------------------------------------------------- * Modify the associated user data. */ - void SetData(Object & data); + void SetData(LightObj & data); /* -------------------------------------------------------------------------------------------- * Destroy the managed vehicle entity. */ bool Destroy() { - return Destroy(0, NullObject()); + return Destroy(0, NullLightObj()); } /* -------------------------------------------------------------------------------------------- @@ -174,23 +174,23 @@ public: */ bool Destroy(Int32 header) { - return Destroy(header, NullObject()); + return Destroy(header, NullLightObj()); } /* -------------------------------------------------------------------------------------------- * Destroy the managed vehicle entity. */ - bool Destroy(Int32 header, Object & payload); + bool Destroy(Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- - * Bind to an event supported by this entity type. + * Retrieve the events table of this entity. */ - void BindEvent(Int32 evid, Object & env, Function & func) const; + LightObj & GetEvents() const; /* -------------------------------------------------------------------------------------------- * Emit a custom event for the managed entity */ - void CustomEvent(Int32 header, Object & payload) const; + void CustomEvent(Int32 header, LightObj & payload) const; /* -------------------------------------------------------------------------------------------- * See if the managed vehicle entity is streamed for the specified player. @@ -210,7 +210,7 @@ public: /* -------------------------------------------------------------------------------------------- * Modify the current option value of the managed vehicle entity. */ - void SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); + void SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload); /* -------------------------------------------------------------------------------------------- * Retrieve the synchronization source of the managed vehicle entity. @@ -240,7 +240,7 @@ public: /* -------------------------------------------------------------------------------------------- * Retrieve the slot occupant from the managed vehicle entity. */ - Object & GetOccupant(Int32 slot) const; + LightObj & GetOccupant(Int32 slot) const; /* -------------------------------------------------------------------------------------------- * Retrieve the slot occupant identifier from the managed vehicle entity. diff --git a/source/Main.cpp b/source/Main.cpp index febc316e..30803760 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -237,7 +237,7 @@ static void OnPlayerConnect(int32_t player_id) // Attempt to forward the event try { - Core::Get().ConnectPlayer(player_id, SQMOD_CREATE_AUTOMATIC, NullObject()); + Core::Get().ConnectPlayer(player_id, SQMOD_CREATE_AUTOMATIC, NullLightObj()); } SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerConnect) // See if a reload was requested @@ -257,7 +257,7 @@ static void OnPlayerDisconnect(int32_t player_id, vcmpDisconnectReason reason) } else { - Core::Get().DisconnectPlayer(player_id, reason, NullObject()); + Core::Get().DisconnectPlayer(player_id, reason, NullLightObj()); } } SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerDisconnect) @@ -875,6 +875,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback // Stop here! return SQMOD_FAILURE; } + // Bind to the server callbacks _Clbk->OnServerInitialise = OnServerInitialise; _Clbk->OnServerShutdown = OnServerShutdown; diff --git a/source/Misc/Functions.cpp b/source/Misc/Functions.cpp index c381a682..96da530c 100644 --- a/source/Misc/Functions.cpp +++ b/source/Misc/Functions.cpp @@ -365,12 +365,12 @@ void SetServerOption(Int32 option_id, bool toggle) } else { - Core::Get().EmitServerOption(option_id, toggle, 0, NullObject()); + Core::Get().EmitServerOption(option_id, toggle, 0, NullLightObj()); } } // ------------------------------------------------------------------------------------------------ -void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload) +void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload) { if (_Func->SetServerOption(static_cast< vcmpServerOption >(option_id), toggle) == vcmpErrorArgumentOutOfBounds) diff --git a/source/Misc/Functions.hpp b/source/Misc/Functions.hpp index 6baf3948..a6c2559b 100644 --- a/source/Misc/Functions.hpp +++ b/source/Misc/Functions.hpp @@ -170,7 +170,7 @@ void SetServerOption(Int32 option_id, bool toggle); /* ------------------------------------------------------------------------------------------------ * Modify a server option. */ -void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload); +void SetServerOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload); /* ------------------------------------------------------------------------------------------------ * Retrieve the world bounds. diff --git a/source/Misc/Register.cpp b/source/Misc/Register.cpp index f80e2ef5..c5c45cf1 100644 --- a/source/Misc/Register.cpp +++ b/source/Misc/Register.cpp @@ -18,7 +18,7 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ -static const Object & FindPlayer(Object & by) +static const LightObj & FindPlayer(Object & by) { switch (by.GetType()) { @@ -45,7 +45,7 @@ static const Object & FindPlayer(Object & by) default: STHROWF("Unsupported search identifier"); } // Default to a null object - return NullObject(); + return NullLightObj(); } // ------------------------------------------------------------------------------------------------ diff --git a/source/Misc/Signal.cpp b/source/Misc/Signal.cpp deleted file mode 100644 index 0344c316..00000000 --- a/source/Misc/Signal.cpp +++ /dev/null @@ -1,973 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -#include "Misc/Signal.hpp" - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -SQMODE_DECL_TYPENAME(Typename, _SC("SqSignalWrapper")) - -// ------------------------------------------------------------------------------------------------ -Signal::SignalContainer Signal::s_Signals; -Signal::FreeSignals Signal::s_FreeSignals; - -// ------------------------------------------------------------------------------------------------ -void Signal::Terminate() -{ - // Terminate named signals - for (const auto & s : s_Signals) - { - // Clear slots - s.second.mPtr->Clear(); - // Release the name - s.second.mPtr->m_Name.clear(); - // Release whatever is in the user data - s.second.mPtr->m_Data.Release(); - } - // Finally clear the container itself - s_Signals.clear(); - // Create a copy so we don't invalidate iterators when destructor removes the instances - FreeSignals fsig(s_FreeSignals); - // Terminate anonymous signals - for (const auto & s : fsig) - { - // Clear slots - s->Clear(); - // Release whatever is in the user data - s->m_Data.Release(); - } - // Finally clear the container itself - s_FreeSignals.clear(); -} - -// ------------------------------------------------------------------------------------------------ -Object Signal::CreateFree() -{ - // Remember the current stack size - const StackGuard sg; - // Create the signal instance - DeleteGuard< Signal > dg(new Signal()); - // Attempt to create the signal instance - ClassType< Signal >::PushInstance(DefaultVM::Get(), dg.Get()); - // This is now managed by the script - dg.Release(); - // Return the created signal - return Var< Object >(DefaultVM::Get(), -1).value; -} - -// ------------------------------------------------------------------------------------------------ -Object Signal::Create(const StackStrF & name) -{ - // Validate the signal name - if (name.mLen <= 0) - { - return CreateFree(); - } - // Create a copy of the name - String sname(name.mPtr, name.mLen); - // Compute the hash of the specified name - const std::size_t hash = std::hash< String >{}(sname); - // See if the signal already exists - for (const auto & e : s_Signals) - { - if (e.first == hash) - { - return e.second.mObj; // Found a match so let's return it - } - } - // Remember the current stack size - const StackGuard sg; - // Create the signal instance - DeleteGuard< Signal > dg(new Signal(std::move(sname))); - // Grab the signal instance pointer - Signal * ptr = dg.Get(); - // Attempt to create the signal instance - ClassType< Signal >::PushInstance(DefaultVM::Get(), ptr); - // This is now managed by the script - dg.Release(); - // Grab a reference to the instance created on the stack - s_Signals.emplace_back(hash, SignalReference(ptr, Var< Object >(DefaultVM::Get(), -1).value)); - // Return the created signal - return s_Signals.back().second.mObj; -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Remove(const StackStrF & name) -{ - // Validate the signal name - if (name.mLen <= 0) - { - STHROWF("Signals without names cannot be removed manually"); - } - // Create a copy of the name - String sname(name.mPtr, name.mLen); - // Compute the hash of the specified name - const std::size_t hash = std::hash< String >{}(sname); - // Iterator to the existing signal, if any - SignalContainer::const_iterator itr = s_Signals.cbegin(); - // Search for a signal with this name - for (; itr != s_Signals.cend(); ++itr) - { - if (itr->first == hash) - { - break; - } - } - // Did we find anything? - if (itr != s_Signals.cend()) - { - // Clear the name - itr->second.mPtr->m_Name.clear(); - // Put it on the free list - s_FreeSignals.push_back(itr->second.mPtr); - // Finally, remove it from the named list - s_Signals.erase(itr); - } -} - -// ------------------------------------------------------------------------------------------------ -Object Signal::Fetch(const StackStrF & name) -{ - // Validate the signal name - if (name.mLen <= 0) - { - STHROWF("Signals without names cannot be retrieved manually"); - } - // Create a copy of the name - String sname(name.mPtr, name.mLen); - // Compute the hash of the specified name - const std::size_t hash = std::hash< String >{}(sname); - // Search for a signal with this name - for (const auto & e : s_Signals) - { - if (e.first == hash) - { - return e.second.mObj; // Found a match so let's return it - } - } - // No such signal exists - STHROWF("Unknown signal named (%s)", sname.c_str()); - // SHOULD NOT REACH THIS POINT! - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -Signal::Signal() - : m_Head(nullptr), m_Data(), m_Name() -{ - s_FreeSignals.push_back(this); -} - -// ------------------------------------------------------------------------------------------------ -Signal::Signal(const CSStr name) - : Signal(String(name ? name : _SC(""))) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Signal::Signal(const String & name) - : Signal(String(name)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -Signal::Signal(String && name) - : m_Head(nullptr), m_Data(), m_Name(std::move(name)) -{ - if (m_Name.empty()) - { - s_FreeSignals.push_back(this); - } -} - -// ------------------------------------------------------------------------------------------------ -Signal::~Signal() -{ - Clear(); - if (m_Name.empty()) - { - s_FreeSignals.erase(std::remove(s_FreeSignals.begin(), s_FreeSignals.end(), this), - s_FreeSignals.end()); - } -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::Count() const -{ - // Don't attempt to count anything if there's no head - if (m_Head == nullptr) - { - return 0; - } - - // Final count - Uint32 count = 0; - // Walk down the chain and count all nodes - for (Slot * node = m_Head; node != nullptr; node = node->mNext) - { - ++count; - } - // Return the count - return count; -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Clear() -{ - // Don't attempt to clear anything if there's no head - if (m_Head == nullptr) - { - return; - } - - // Walk down the chain and delete all nodes - for (Slot * node = m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Delete the node instance - delete node; - } - // Reset the head - m_Head = nullptr; -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Connect(Object & env, Function & func) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - m_Head = new Slot(env, func, nullptr); - // We're done here - return; - } - - const Slot slot{env, func}; - // Don't attempt to search anything if there's only one element - if (m_Head->mNext == nullptr) - { - // Is it already inserted? - if (*m_Head != slot) - { - m_Head = new Slot(env, func, m_Head); - } - // We're done here - return; - } - - // Walk down the chain and find an already matching node - for (Slot * node = m_Head; node != nullptr; node = node->mNext) - { - if (*node == slot) - { - return; // Already connected - } - } - // Connect now - m_Head = new Slot(env, func, m_Head); -} - -// ------------------------------------------------------------------------------------------------ -bool Signal::Connected(Object & env, Function & func) const -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - return false; - } - - const Slot slot{env, func}; - // Walk down the chain and find a matching node - for (Slot * node = m_Head; node != nullptr; node = node->mNext) - { - if (*node == slot) - { - return true; // Found it - } - } - // No such slot exists - return false; -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Disconnect(Object & env, Function & func) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - return; - } - - const Slot slot{env, func}; - // Walk down the chain and remove the matching nodes - for (Slot * node = m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Is this our node? - if (*node == slot) - { - // Is this the head? - if (node == m_Head) - { - m_Head = next; // Move the head to the next one - } - // Detach it from the chain - node->Detach(); - // Delete the node instance - delete node; - } - } -} - -// ------------------------------------------------------------------------------------------------ -void Signal::DisconnectThis(Object & env) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - return; - } - - const SQHash hash = Slot{env, NullFunction()}.mEnvHash; - // Walk down the chain and remove the matching nodes - for (Slot * node = m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Is this our node? - if (node->mEnvHash == hash) - { - // Is this the head? - if (node == m_Head) - { - m_Head = next; // Move the head to the next one - } - // Detach it from the chain - node->Detach(); - // Delete the node instance - delete node; - } - } -} - -// ------------------------------------------------------------------------------------------------ -void Signal::DisconnectFunc(Function & func) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - return; - } - - const SQHash hash = Slot{NullObject(), func}.mFuncHash; - // Walk down the chain and remove the matching nodes - for (Slot * node = m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Is this our node? - if (node->mFuncHash == hash) - { - // Is this the head? - if (node == m_Head) - { - m_Head = next; // Move the head to the next one - } - // Detach it from the chain - node->Detach(); - // Delete the node instance - delete node; - } - } -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Signal::CountThis(Object & env) const -{ - // Don't attempt to count anything if there's no head - if (m_Head == nullptr) - { - return 0; - } - - const SQHash hash = Slot{env, NullFunction()}.mEnvHash; - // Final count - Uint32 count = 0; - // Walk down the chain and count the matching nodes - for (Slot * node = m_Head; node != nullptr; node = node->mNext) - { - // Is this our node? - if (node->mEnvHash == hash) - { - ++count; - } - } - // Return the count - return count; -} - -// ------------------------------------------------------------------------------------------------ -Uint32 Signal::CountFunc(Function & func) const -{ - // Don't attempt to count anything if there's no head - if (m_Head == nullptr) - { - return 0; - } - - const SQHash hash = Slot{NullObject(), func}.mFuncHash; - // Final count - Uint32 count = 0; - // Walk down the chain and count the matching nodes - for (Slot * node = m_Head; node != nullptr; node = node->mNext) - { - // Is this our node? - if (node->mFuncHash == hash) - { - ++count; - } - } - // Return the count - return count; -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Head(Object & env, Function & func) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - m_Head = new Slot(env, func, nullptr); - // We're done here - return; - } - - const Slot slot{env, func}; - // Don't attempt to search anything if there's only one element - if (m_Head->mNext == nullptr) - { - // Is it already inserted? - if (*m_Head != slot) - { - m_Head = new Slot(env, func, m_Head); - } - // We're done here - return; - } - - // Grab the head node - Slot * node = m_Head; - // Walk down the chain and find a matching node - for (; node != nullptr; node = node->mNext) - { - if (*node == slot) - { - break; // Found it - } - } - // Have we found anything? - if (node == nullptr) - { - m_Head = new Slot(env, func, m_Head); // Lead everyone - } - // Is it the head already? - else if (m_Head != node) - { - node->AttachNext(m_Head); - // We're the head now - m_Head = node; - } -} - -// ------------------------------------------------------------------------------------------------ -void Signal::Tail(Object & env, Function & func) -{ - // Don't attempt to search anything if there's no head - if (m_Head == nullptr) - { - m_Head = new Slot(env, func, nullptr); - // We're done here - return; - } - - const Slot slot{env, func}; - // Don't attempt to search anything if there's only one element - if (m_Head->mNext == nullptr) - { - // Is it already inserted? - if (*m_Head != slot) - { - m_Head->mNext = new Slot(env, func, nullptr); - // Link with the head - m_Head->mNext->mPrev = m_Head; - } - // We're done here - return; - } - - // Grab the head node - Slot * node = m_Head, * prev = nullptr; - // Walk down the chain and find a matching node - for (; node != nullptr; prev = node, node = node->mNext) - { - if (*node == slot) - { - break; // Found it - } - } - // Have we found anything? - if (node == nullptr) - { - // Create the slot now - node = new Slot(env, func, nullptr); - } - else - { - // Walk down the chain until the end - while (prev->mNext != nullptr) - { - prev = prev->mNext; - } - // Finally, detach the node from it's current position - node->Detach(); - } - // Knowing 'prev' points to last element - node->AttachPrev(prev); -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::SqEmit(HSQUIRRELVM vm) -{ - const Int32 top = sq_gettop(vm); - // The signal instance - Signal * signal = nullptr; - // Attempt to extract the signal instance - try - { - signal = Var< Signal * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - return sq_throwerror(vm, e.what()); - } - // Do we have a valid signal instance? - if (!signal) - { - return sq_throwerror(vm, "Invalid signal instance"); - } - // Walk down the chain and trigger slots - for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Remember the current stack size - const StackGuard sg(vm); - // Push the callback object - sq_pushobject(vm, node->mFuncRef); - // Is there an explicit environment? - if (sq_isnull(node->mEnvRef)) - { - sq_pushroottable(vm); - } - else - { - sq_pushobject(vm, node->mEnvRef); - } - // Are there any parameters to forward? - if (top > 1) - { - for (SQInteger i = 2; i <= top; ++i) - { - sq_push(vm, i); - } - } - // Make the function call and store the result - const SQRESULT res = sq_call(vm, top, false, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - } - // Specify that we don't return anything - return 0; -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::SqQuery(HSQUIRRELVM vm) -{ - const Int32 top = sq_gettop(vm); - // Do we have the collector environment? - if (top <= 1) - { - return sq_throwerror(vm, "Missing collector environment"); - } - // Do we have the collector function? - else if (top <= 2) - { - return sq_throwerror(vm, "Missing collector callback"); - } - // The signal instance - Signal * signal = nullptr; - // Attempt to extract the signal instance and collector - try - { - signal = Var< Signal * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - return sq_throwerror(vm, e.what()); - } - // Do we have a valid signal instance? - if (!signal) - { - return sq_throwerror(vm, "Invalid signal instance"); - } - // The collector - HSQOBJECT cenv, cfunc; - // Grab the collector environment - SQRESULT res = sq_getstackobj(vm, 2, &cenv); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Was there a valid environment? - else if (sq_isnull(cenv)) - { - // Remember the current stack size - const StackGuard sg(vm); - // Default to the root table - sq_pushroottable(vm); - // Try to grab the collector environment again - SQRESULT res = sq_getstackobj(vm, -1, &cenv); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - } - // Grab the collector function - res = sq_getstackobj(vm, 3, &cfunc); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Some dummy checks to make sure the collector is a callable object - else if (!sq_isfunction(cfunc) && !sq_isclosure(cfunc) && !sq_isnativeclosure(cfunc)) - { - return sq_throwerror(vm, "Invalid collector"); - } - // Walk down the chain and trigger slots - for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Remember the current stack size - const StackGuard sg(vm); - // Push the callback object - sq_pushobject(vm, node->mFuncRef); - // Is there an explicit environment? - if (sq_isnull(node->mEnvRef)) - { - sq_pushroottable(vm); - } - else - { - sq_pushobject(vm, node->mEnvRef); - } - // Are there any parameters to forward? - if (top > 3) - { - for (SQInteger i = 4; i <= top; ++i) - { - sq_push(vm, i); - } - } - // Make the function call and store the result - res = sq_call(vm, top - 2, true, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Push the collector onto the stack - sq_pushobject(vm, cfunc); - sq_pushobject(vm, cenv); - // Push the returned value - sq_push(vm, -3); - // Make the function call and store the result - res = sq_call(vm, 2, false, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - } - // Specify that we don't return anything - return 0; -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::SqConsume(HSQUIRRELVM vm) -{ - const Int32 top = sq_gettop(vm); - // The signal instance - Signal * signal = nullptr; - // Attempt to extract the signal instance - try - { - signal = Var< Signal * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - return sq_throwerror(vm, e.what()); - } - // Do we have a valid signal instance? - if (!signal) - { - return sq_throwerror(vm, "Invalid signal instance"); - } - // Default to not consumed - SQBool ret = SQFalse; - // Walk down the chain and trigger slots - for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Remember the current stack size - const StackGuard sg(vm); - // Push the callback object - sq_pushobject(vm, node->mFuncRef); - // Is there an explicit environment? - if (sq_isnull(node->mEnvRef)) - { - sq_pushroottable(vm); - } - else - { - sq_pushobject(vm, node->mEnvRef); - } - // Are there any parameters to forward? - if (top > 1) - { - for (SQInteger i = 2; i <= top; ++i) - { - sq_push(vm, i); - } - } - // Make the function call and store the result - const SQRESULT res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Is the returned value not null? - else if (sq_gettype(vm, -1) != OT_NULL) - { - // Obtain the returned value - sq_tobool(vm, -1, &ret); - // Should we proceed to the next slot or stop here? - if (ret == SQTrue) - { - break; // The slot consumed the signal - } - } - } - // Forward the returned value to the invoker - sq_pushbool(vm, ret); - // Specify that we returned something - return 1; -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::SqApprove(HSQUIRRELVM vm) -{ - const Int32 top = sq_gettop(vm); - // The signal instance - Signal * signal = nullptr; - // Attempt to extract the signal instance - try - { - signal = Var< Signal * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - return sq_throwerror(vm, e.what()); - } - // Do we have a valid signal instance? - if (!signal) - { - return sq_throwerror(vm, "Invalid signal instance"); - } - // Default to approved - SQBool ret = SQTrue; - // Walk down the chain and trigger slots - for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Remember the current stack size - const StackGuard sg(vm); - // Push the callback object - sq_pushobject(vm, node->mFuncRef); - // Is there an explicit environment? - if (sq_isnull(node->mEnvRef)) - { - sq_pushroottable(vm); - } - else - { - sq_pushobject(vm, node->mEnvRef); - } - // Are there any parameters to forward? - if (top > 1) - { - for (SQInteger i = 2; i <= top; ++i) - { - sq_push(vm, i); - } - } - // Make the function call and store the result - const SQRESULT res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Is the returned value not null? - else if (sq_gettype(vm, -1) != OT_NULL) - { - // Obtain the returned value - sq_tobool(vm, -1, &ret); - // Should we proceed to the next slot or stop here? - if (ret == SQFalse) - { - break; // The slot did not approve the signal - } - } - } - // Forward the returned value to the invoker - sq_pushbool(vm, ret); - // Specify that we returned something - return 1; -} - -// ------------------------------------------------------------------------------------------------ -SQInteger Signal::SqRequest(HSQUIRRELVM vm) -{ - const Int32 top = sq_gettop(vm); - // The signal instance - Signal * signal = nullptr; - // Attempt to extract the signal instance - try - { - signal = Var< Signal * >(vm, 1).value; - } - catch (const Sqrat::Exception & e) - { - return sq_throwerror(vm, e.what()); - } - // Do we have a valid signal instance? - if (!signal) - { - return sq_throwerror(vm, "Invalid signal instance"); - } - // Walk down the chain and trigger slots - for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) - { - // Grab the next node upfront - next = node->mNext; - // Remember the current stack size - const StackGuard sg(vm); - // Push the callback object - sq_pushobject(vm, node->mFuncRef); - // Is there an explicit environment? - if (sq_isnull(node->mEnvRef)) - { - sq_pushroottable(vm); - } - else - { - sq_pushobject(vm, node->mEnvRef); - } - // Are there any parameters to forward? - if (top > 1) - { - for (SQInteger i = 2; i <= top; ++i) - { - sq_push(vm, i); - } - } - // Make the function call and store the result - const SQRESULT res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); - // Validate the result - if (SQ_FAILED(res)) - { - return res; // Propagate the error - } - // Is the returned value not null? - else if (sq_gettype(vm, -1) != OT_NULL) - { - // Push back the returned value - sq_push(vm, -1); - // Specify that we returned something - return 1; - } - } - // Specify that we returned nothing - return 0; -} - -// ================================================================================================ -void Register_Signal(HSQUIRRELVM vm) -{ - RootTable(vm).Bind(Typename::Str, - Class< Signal, NoConstructor< Signal > >(vm, Typename::Str) - // Meta-methods - .SquirrelFunc(_SC("_typename"), &Typename::Fn) - .Func(_SC("_tostring"), &Signal::ToString) - // Core Properties - .Prop(_SC("Data"), &Signal::GetData, &Signal::SetData) - .Prop(_SC("Slots"), &Signal::Count) - // Core Methods - .Func(_SC("Clear"), &Signal::Clear) - .Func(_SC("Connect"), &Signal::Connect) - .Func(_SC("Connected"), &Signal::Connected) - .Func(_SC("Disconnect"), &Signal::Disconnect) - .Func(_SC("EliminateThis"), &Signal::DisconnectThis) - .Func(_SC("EliminateFunc"), &Signal::DisconnectFunc) - .Func(_SC("CountThis"), &Signal::CountThis) - .Func(_SC("CountFunc"), &Signal::CountFunc) - .Func(_SC("Head"), &Signal::Head) - .Func(_SC("Tail"), &Signal::Tail) - // Squirrel Functions - .SquirrelFunc(_SC("Emit"), &Signal::SqEmit) - .SquirrelFunc(_SC("Broadcast"), &Signal::SqEmit) - .SquirrelFunc(_SC("Query"), &Signal::SqQuery) - .SquirrelFunc(_SC("Consume"), &Signal::SqConsume) - .SquirrelFunc(_SC("Approve"), &Signal::SqApprove) - .SquirrelFunc(_SC("Request"), &Signal::SqRequest) - ); - - RootTable(vm) - .FmtFunc(_SC("SqSignal"), &Signal::Fetch) - .FmtFunc(_SC("SqCreateSignal"), &Signal::Create) - .FmtFunc(_SC("SqRemoveSignal"), &Signal::Remove); -} - -/* ------------------------------------------------------------------------------------------------ - * Forward the call to terminate the signals. -*/ -void TerminateSignals() -{ - Signal::Terminate(); -} - -} // Namespace:: SqMod diff --git a/source/Misc/Signal.hpp b/source/Misc/Signal.hpp deleted file mode 100644 index 7ab589b5..00000000 --- a/source/Misc/Signal.hpp +++ /dev/null @@ -1,539 +0,0 @@ -#ifndef _MISC_SIGNAL_HPP_ -#define _MISC_SIGNAL_HPP_ - -// ------------------------------------------------------------------------------------------------ -#include "Base/Shared.hpp" - -// ------------------------------------------------------------------------------------------------ -#include -#include -#include -#include - -// ------------------------------------------------------------------------------------------------ -namespace SqMod { - -// ------------------------------------------------------------------------------------------------ -class Signal; - -/* ------------------------------------------------------------------------------------------------ - * Helper class used to reference and keep track of signal instances. -*/ -struct SignalReference -{ - // -------------------------------------------------------------------------------------------- - Signal * mPtr; // A raw pointer to the signal instance. - Object mObj; // A managed reference to the signal instance. - - /* -------------------------------------------------------------------------------------------- - * Explicit constructor. - */ - SignalReference(Signal * ptr, const Object & ref) - : mPtr(ptr), mObj(ref) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - SignalReference(const SignalReference & o) = default; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - SignalReference(SignalReference && o) = default; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~SignalReference() = default; - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - SignalReference & operator = (const SignalReference & o) = default; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - SignalReference & operator = (SignalReference && o) = default; -}; - -/* ------------------------------------------------------------------------------------------------ - * Utility class for for delivering events to one or more listeners. -*/ -class Signal -{ -private: - - /* -------------------------------------------------------------------------------------------- - * Used to store a script callback and the unique hash associated with it for quick searching. - */ - struct Slot - { - // ---------------------------------------------------------------------------------------- - SQHash mEnvHash; // The hash of the specified environment. - SQHash mFuncHash; // The hash of the specified callback. - HSQOBJECT mEnvRef; // The specified script environment. - HSQOBJECT mFuncRef; // The specified script callback. - - // ---------------------------------------------------------------------------------------- - Slot * mPrev; // Previous slot in the chain. - Slot * mNext; // Next slot in the chain. - - /* ---------------------------------------------------------------------------------------- - * Forwarding constructor. - */ - Slot(Object & env, Function & func) - : Slot(env.GetObject(), func.GetFunc(), nullptr) - { - /* ... */ - } - - /* ---------------------------------------------------------------------------------------- - * Forwarding constructor. - */ - Slot(Object & env, Function & func, Slot * head) - : Slot(env.GetObject(), func.GetFunc(), head) - { - /* ... */ - } - - /* ---------------------------------------------------------------------------------------- - * Base constructor. - */ - Slot(HSQOBJECT & env, HSQOBJECT & func, Slot * head) - : mEnvHash(0) - , mFuncHash(0) - , mEnvRef(env) - , mFuncRef(func) - , mPrev(nullptr) - , mNext(head) - { - HSQUIRRELVM vm = DefaultVM::Get(); - // Remember the current stack size - const StackGuard sg(vm); - // Is there an explicit environment? - if (!sq_isnull(mEnvRef)) - { - // Keep a reference to this environment - sq_addref(vm, &mEnvRef); - // Push the environment on the stack - sq_pushobject(vm, mEnvRef); - // Grab the hash of the environment object - mEnvHash = sq_gethash(vm, -1); - } - // Is there an explicit function? - if (!sq_isnull(mFuncRef)) - { - // Keep a reference to this function - sq_addref(vm, &mFuncRef); - // Push the callback on the stack - sq_pushobject(vm, mFuncRef); - // Grab the hash of the callback object - mFuncHash = sq_gethash(vm, -1); - } - // Was there a previous head? - if (mNext != nullptr) - { - // Steal the slot before the head - mPrev = mNext->mPrev; - // Did that head slot had a slot behind it? - if (mPrev != nullptr) - { - // Tell it we're the next slot now - mPrev->mNext = this; - } - // Tell the previous head that we're behind it now - mNext->mPrev = this; - } - } - - /* ---------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - Slot(const Slot & o) = delete; - - /* ---------------------------------------------------------------------------------------- - * Move constructor. - */ - Slot(Slot && o) - : mEnvHash(o.mEnvHash) - , mFuncHash(o.mFuncHash) - , mEnvRef(o.mEnvRef) - , mFuncRef(o.mFuncRef) - , mPrev(o.mPrev) - , mNext(o.mNext) - { - // Take ownership - sq_resetobject(&o.mEnvRef); - sq_resetobject(&o.mFuncRef); - o.mPrev = nullptr; - o.mNext = nullptr; - // Attach to the chain - Attach(); - } - - /* ---------------------------------------------------------------------------------------- - * Destructor. - */ - ~Slot() - { - Release(); - // Detach from the chain - Detach(); - } - - /* ---------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - Slot & operator = (const Slot & o) = delete; - - /* ---------------------------------------------------------------------------------------- - * Move assignment operator. - */ - Slot & operator = (Slot && o) - { - if (this != &o) - { - // Release current resources, if any - Release(); - // Replicate data - mEnvHash = o.mEnvHash; - mFuncHash = o.mFuncHash; - mEnvRef = o.mEnvRef; - mFuncRef = o.mFuncRef; - mPrev = o.mPrev; - mNext = o.mNext; - // Take ownership - sq_resetobject(&o.mEnvRef); - sq_resetobject(&o.mFuncRef); - o.mPrev = nullptr; - o.mNext = nullptr; - // Attach to the chain - Attach(); - } - - return *this; - } - - /* ---------------------------------------------------------------------------------------- - * Equality comparison operator. - */ - bool operator == (const Slot & o) const - { - return (mEnvHash == o.mEnvHash) && (mFuncHash == o.mFuncHash); - } - - /* ---------------------------------------------------------------------------------------- - * Inequality comparison operator. - */ - bool operator != (const Slot & o) const - { - return (mEnvHash != o.mEnvHash) || (mFuncHash != o.mFuncHash); - } - - /* ---------------------------------------------------------------------------------------- - * Release managed script resources. - */ - void Release() - { - // Should we release any environment object? - if (!sq_isnull(mEnvRef)) - { - sq_release(DefaultVM::Get(), &mEnvRef); - sq_resetobject(&mEnvRef); - } - // Should we release any callback object? - if (!sq_isnull(mFuncRef)) - { - sq_release(DefaultVM::Get(), &mFuncRef); - sq_resetobject(&mFuncRef); - } - } - - /* ---------------------------------------------------------------------------------------- - * Attach the slot to the chain. - */ - void Attach() - { - // Is there a slot after us? - if (mNext != nullptr) - { - // Tell it that we're behind it - mNext->mPrev = this; - } - // Is there a node behind us? - if (mPrev != nullptr) - { - // Tell it that we're ahead of it - mPrev->mNext = this; - } - } - - /* ---------------------------------------------------------------------------------------- - * Detach the slot from the chain. - */ - void Detach() - { - // Is there a slot after us? - if (mNext != nullptr) - { - // Tell it we're no longer behind it - mNext->mPrev = mPrev; - } - // Is there a node behind us? - if (mPrev != nullptr) - { - // Tell it we're no longer ahead of it - mPrev->mNext = mNext; - } - mPrev = mNext = nullptr; - } - - /* ---------------------------------------------------------------------------------------- - * Attach the slot after another slot. - */ - void AttachNext(Slot * node) - { - Detach(); - // Assign the slot ahead of us - mNext = node; - // Is there a node to attach to? - if (mNext != nullptr) - { - // Steal the previous slot - mPrev = mNext->mPrev; - // Was there a previous slot? - if (mPrev != nullptr) - { - mPrev->mNext = this; // Tell it we're the next slot now - } - // Place ourself behind - mNext->mPrev = this; - } - } - - /* ---------------------------------------------------------------------------------------- - * Attach the slot before another slot. - */ - void AttachPrev(Slot * node) - { - Detach(); - // Assign the slot behind us - mPrev = node; - // Is there a node to attach to? - if (mPrev != nullptr) - { - // Steal the next slot - mNext = mPrev->mNext; - // Was there a next slot? - if (mNext != nullptr) - { - mNext->mPrev = this; // Tell it we're the previous slot now - } - // Place ourself ahead - mPrev->mNext = this; - } - } - }; - - // -------------------------------------------------------------------------------------------- - Slot * m_Head; // The chain of slots bound to this signal. - Object m_Data; // User data associated with this instance. - String m_Name; // The name that identifies this signal. - - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - Signal(); - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - explicit Signal(const CSStr name); - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - Signal(const String & name); - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - Signal(String && name); - -public: - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - Signal(const Signal & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - Signal(Signal && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~Signal(); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - Signal & operator = (const Signal & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - Signal & operator = (Signal && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to convert an instance of this type to a string. - */ - const String & ToString() const - { - return m_Name; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the associated user data. - */ - Object & GetData() - { - return m_Data; - } - - /* -------------------------------------------------------------------------------------------- - * Modify the associated user data. - */ - void SetData(Object & data) - { - m_Data = data; - } - - /* -------------------------------------------------------------------------------------------- - * The number of slots connected to the signal. - */ - SQInteger Count() const; - - /* -------------------------------------------------------------------------------------------- - * Clear all slots connected to the signal. - */ - void Clear(); - - /* -------------------------------------------------------------------------------------------- - * Connect a function with a specific environment to the signal. - */ - void Connect(Object & env, Function & func); - - /* -------------------------------------------------------------------------------------------- - * See whether a function with a specific environment is connected to the signal. - */ - bool Connected(Object & env, Function & func) const; - - /* -------------------------------------------------------------------------------------------- - * Disconnect a function with a specific environment from the signal. - */ - void Disconnect(Object & env, Function & func); - - /* -------------------------------------------------------------------------------------------- - * Disconnect all functions with a specific environment from the signal. - */ - void DisconnectThis(Object & env); - - /* -------------------------------------------------------------------------------------------- - * Disconnect all matching functions regardless of the environment from the signal. - */ - void DisconnectFunc(Function & func); - - /* -------------------------------------------------------------------------------------------- - * Count all functions with a specific environment from the signal. - */ - Uint32 CountThis(Object & env) const; - - /* -------------------------------------------------------------------------------------------- - * Count all matching functions regardless of the environment from the signal. - */ - Uint32 CountFunc(Function & func) const; - - /* -------------------------------------------------------------------------------------------- - * Make sure that specified slot is positioned ahead of all other slots. - */ - void Head(Object & env, Function & func); - - /* -------------------------------------------------------------------------------------------- - * Make sure that specified slot is positioned behind of all other slots. - */ - void Tail(Object & env, Function & func); - - /* -------------------------------------------------------------------------------------------- - * Emit the event to the connected slots. - */ - static SQInteger SqEmit(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Emit the event to the connected slots and collect returned values. - */ - static SQInteger SqQuery(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Emit the event to the connected slots and see if they consume it. - */ - static SQInteger SqConsume(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Emit the event to the connected slots and see if they approve it. - */ - static SQInteger SqApprove(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Emit the event to the connected slots and see if they return something. - */ - static SQInteger SqRequest(HSQUIRRELVM vm); - -private: - - // -------------------------------------------------------------------------------------------- - typedef std::pair< std::size_t, SignalReference > SignalElement; - typedef std::vector< SignalElement > SignalContainer; - typedef std::vector< Signal * > FreeSignals; - - // -------------------------------------------------------------------------------------------- - static SignalContainer s_Signals; // List of all created signals. - static FreeSignals s_FreeSignals; // List of signals without a name. - -public: - - /* -------------------------------------------------------------------------------------------- - * Terminate all signal instances and release any script resources. - */ - static void Terminate(); - - /* -------------------------------------------------------------------------------------------- - * Create a free signal without a specific name. - */ - static Object CreateFree(); - - /* -------------------------------------------------------------------------------------------- - * Create a new signal with the specified name. - */ - static Object Create(const StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Remove the signal with the specified name. - */ - static void Remove(const StackStrF & name); - - /* -------------------------------------------------------------------------------------------- - * Retrieve the signal with the specified name. - */ - static Object Fetch(const StackStrF & name); -}; - -} // Namespace:: SqMod - -#endif // _MISC_SIGNAL_HPP_ diff --git a/source/Signal.cpp b/source/Signal.cpp new file mode 100644 index 00000000..52f0f654 --- /dev/null +++ b/source/Signal.cpp @@ -0,0 +1,1716 @@ +// ------------------------------------------------------------------------------------------------ +#include "Signal.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +SQMODE_DECL_TYPENAME(Typename, _SC("SqSignalImpl")) + +// ------------------------------------------------------------------------------------------------ +Signal::SignalPool Signal::s_Signals; +Signal::FreeSignals Signal::s_FreeSignals; + +/* ------------------------------------------------------------------------------------------------ + * Class used to control the signal emitter. +*/ +struct SignalWrapper +{ + // -------------------------------------------------------------------------------------------- + using Slot = Signal::Slot; + // -------------------------------------------------------------------------------------------- + Signal * mSignal; // A raw pointer to the signal instance. + // -------------------------------------------------------------------------------------------- + Slot mSlot; // The specified slot. + HSQUIRRELVM mVM; // The specified virtual machine. + SQInteger mRes; // The result of the operation. + bool mOne; // Limit to one slot in the operation. + bool mAppend; // Append instead of push when leading or tailing. + + /* -------------------------------------------------------------------------------------------- + * Explicit constructor. + */ + SignalWrapper(HSQUIRRELVM vm, bool extra = false) + : mSignal(nullptr) + , mSlot() + , mVM(vm) + , mRes(Initialize(vm, extra)) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Extracts the information from the stack of the specified virtual machine. + */ + SQInteger Initialize(HSQUIRRELVM vm, bool extra) + { + const SQInteger top = sq_gettop(vm); + // See if the minimum amount of arguments were specified + if (top <= 1) + { + return sq_throwerror(vm, "Wrong number of parameters"); + } + // Attempt to extract the signal instance + try + { + mSignal = Var< Signal * >(vm, 1).value; + } + catch (const Sqrat::Exception & e) + { + return sq_throwerror(vm, e.what()); + } + // Do we have a valid signal instance? + if (!mSignal) + { + return sq_throwerror(vm, "Invalid signal instance"); + } + // By default, extra parameters start after callback + SQInteger extpos = 3; + // Is the first parameter a function? + if (sq_gettype(vm, 2) & (_RT_CLOSURE | _RT_NATIVECLOSURE)) + { + // Attempt to grab the callback object + SQRESULT res = sq_getstackobj(vm, 2, &mSlot.mFuncRef); + // Did we fail to retrieve the callback object? + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + else + { + sq_addref(vm, &mSlot.mFuncRef); + } + // Grab the hash of the callback object + mSlot.mFuncHash = sq_gethash(vm, 2); + // Push the root table on the stack + sq_pushroottable(vm); + // Attempt to grab root table as the environment + res = sq_getstackobj(vm, -1, &mSlot.mThisRef); + // Did we fail to retrieve the root table? + if (SQ_FAILED(res)) + { + // Pop the root table from the stack + sq_pop(vm, 1); + // Propagate the error + return res; + } + else + { + sq_addref(vm, &mSlot.mThisRef); + } + // Grab the hash of the root table + mSlot.mThisHash = sq_gethash(vm, -1); + // Pop the root table from the stack + sq_pop(vm, 1); + } + // Should we look for a specific environment? + else if (top >= 3 && sq_gettype(vm, 3) & (_RT_CLOSURE | _RT_NATIVECLOSURE)) + { + // Is the first type at suitable to be an environment at least? + if (!(sq_gettype(vm, 2) & (_RT_TABLE | _RT_CLASS | _RT_INSTANCE))) + { + return sq_throwerror(vm, "Invalid environment object"); + } + // Attempt to grab the environment object + SQRESULT res = sq_getstackobj(vm, 2, &mSlot.mThisRef); + // Did we fail to retrieve the environment object? + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + else + { + sq_addref(vm, &mSlot.mThisRef); + } + // Grab the hash of the environment object + mSlot.mThisHash = sq_gethash(vm, 2); + // Attempt to grab the callback object + res = sq_getstackobj(vm, 3, &mSlot.mFuncRef); + // Did we fail to retrieve the callback object? + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + else + { + sq_addref(vm, &mSlot.mFuncRef); + } + // Grab the hash of the callback object + mSlot.mFuncHash = sq_gethash(vm, 3); + // The extra parameters start one slot higher + ++extpos; + } + else + { + return sq_throwerror(vm, "Missing callback function"); + } + // Should we look for the extra parameters? + if (extra && top >= extpos) + { + SQBool value; + // Attempt to retrieve the parameter value + sq_tobool(vm, extpos, &value); + // Convert the retrieved value + mOne = static_cast< bool >(value); + // The next extra parameter starts one slot higher + ++extpos; + } + else + { + mOne = false; + } + // Should we look for the extra parameters? + if (extra && top >= extpos) + { + SQBool value; + // Attempt to retrieve the parameter value + sq_tobool(vm, extpos, &value); + // Convert the retrieved value + mAppend = static_cast< bool >(value); + } + else + { + mAppend = true; + } + // Initialization was successful + return SQ_OK; + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + SignalWrapper(const SignalWrapper & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ + SignalWrapper(SignalWrapper && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. (disabled) + */ + SignalWrapper & operator = (const SignalWrapper & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + SignalWrapper & operator = (SignalWrapper && o) = delete; + +}; + +/* ------------------------------------------------------------------------------------------------ + * Helper functor to locate specific slots. +*/ +template < class Slot > struct MatchSlot +{ + // -------------------------------------------------------------------------------------------- + const SQHash mThisHash; // The environment to search for. + const SQHash mFuncHash; // The callback to search for. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + MatchSlot(SQHash t, SQHash f) + : mThisHash(t), mFuncHash(f) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + inline bool operator () (const Slot & s) const + { + return (mThisHash == s.mThisHash) && (mFuncHash == s.mFuncHash); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Helper functor to locate slots with specific environments. +*/ +template < class Slot > struct MatchThis +{ + // -------------------------------------------------------------------------------------------- + const SQHash mThisHash; // The environment to search for. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + MatchThis(SQHash t) + : mThisHash(t) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + inline bool operator () (const Slot & s) const + { + return (mThisHash == s.mThisHash); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Helper functor to locate slots with specific callbacks. +*/ +template < class Slot > struct MatchFunc +{ + // -------------------------------------------------------------------------------------------- + const SQHash mFuncHash; // The callback to search for. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + MatchFunc(SQHash f) + : mFuncHash(f) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + inline bool operator () (const Slot & s) const + { + return (mFuncHash == s.mFuncHash); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * See if a certain slot exists using the provided functor. +*/ +template < typename F, class Slot > static bool ExistsIf(F func, Slot * itr, Slot * end) +{ + // Process slots within the given range + while (itr != end) + { + // Does this slot satisfy the functor? + if (func(*(itr++))) + { + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Count the number of slots that the provided functor deems worthy. +*/ +template < typename F, class Slot > static Signal::SizeType CountIf(F func, Slot * itr, Slot * end) +{ + Signal::SizeType count = 0; + // Process slots within the given range + while (itr != end) + { + // Should we count this slot? + if (func(*(itr++))) + { + ++count; + } + } + // Return the final count + return count; +} + +/* ------------------------------------------------------------------------------------------------ + * Remove all slot from the specified range if the provided functor demands it. +*/ +template < typename F, class Slot, class Scope > +static Signal::SizeType RemoveIf(F func, Slot * itr, Slot * end, Scope * scope) +{ + Slot * dest = itr; + // Number of removed slots + Signal::SizeType count = 0; + // Process slots within the given range + while (itr != end) + { + // Should we remove this slot? + if (func(*itr)) + { + // Release the stored references + itr->Release(); + // Are we currently signaling? + if (scope != nullptr) + { + scope->Descend(itr); // Update iterators + } + // Increase the counter + ++count; + } + // Were there any slots removed? + else if (itr != dest) + { + // Offset the current scope + *dest = std::move(*itr); + // Advance the destination + ++dest; + } + else + { + ++dest; // We avoided a move assignment + } + // Advance the iterator + ++itr; + } + // Return the final count + return count; +} + +/* ------------------------------------------------------------------------------------------------ + * Move to the front all slots that the provided functor demands. +*/ +template < typename F, class Slot, class Scope > +static void LeadIf(F func, Slot * front, Slot * end, bool one, bool append, Scope * scope) +{ + Slot * itr = front; + // Process slots within the given range + while (itr != end) + { + // Should this slot become a lead? + if (!func(*itr)) + { + ++itr; + // Skip it + continue; + } + // Is this slot right behind the current lead? + else if ((itr - front) == 1) + { + // Swap them + itr->Swap(*front); + // Are we currently signaling? + if (scope != nullptr) + { + scope->Lead(itr); // Update iterators + } + } + // Is this not the current lead? + else if (itr != front) + { + // Backup the values of this slot + Slot tmp(std::move(*itr)); + // Shift back all the slots before it + for (Slot * dest = itr, * src = (itr - 1); dest != front; dest = src, --src) + { + dest->Swap(*src); // Swap with the one bellow it + } + // Finally, place the slot into lead + *front = std::move(tmp); + // Are we currently signaling? + if (scope != nullptr) + { + scope->Lead(itr); // Update iterators + } + } + // Advance the iterator + ++itr; + // Are we using the append method? + if (append) + { + ++front; // Don't overrule the current lead + } + // Should we make only one lead? + if (one) + { + break; // Then stop here! + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Move to the back all slots that the provided functor demands. +*/ +template < typename F, class Slot, class Scope > +static void TailIf(F func, Slot * front, Slot * back, bool one, bool append, Scope * scope) +{ + Slot * itr = back; + // Process slots within the given range + while (itr >= front) + { + // Should this slot become a tail? + if (!func(*itr)) + { + --itr; + // Skip it + continue; + } + // Is this slot right behind the current tail? + else if ((back - itr) == 1) + { + // Swap them + itr->Swap(*front); + // Are we currently signaling? + if (scope != nullptr) + { + scope->Tail(itr); // Update iterators + } + } + // Is this not the current tail? + else if (itr != back) + { + // Backup the values of this slot + Slot tmp(std::move(*itr)); + // Shift up all the slots before it + for (Slot * dest = itr, * src = (itr + 1); dest != back; dest = src, ++src) + { + dest->Swap(*src); // Swap with the one above it + } + // Finally, place the slot into tail + *back = std::move(tmp); + // Are we currently signaling? + if (scope != nullptr) + { + scope->Tail(itr); // Update iterators + } + } + // Advance the iterator + --itr; + // Are we using the append method? + if (append) + { + --back; // Don't overrule the current tail + } + // Should we make only one tail? + if (one) + { + break; // Then stop here! + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Scope::Descend(Pointer ptr) +{ + // Is the descended pointer withing this scope? + if (ptr <= mEnd) + { + // Is the iterator affected by this? + if (ptr < mItr || mItr > mEnd) + { + --mItr; + } + // Update the end iterator + --mEnd; + } + // Is this that last scope? + if (mChild != nullptr) + { + mChild->Descend(ptr); // Let the others know as well + } +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Scope::Lead(Pointer ptr) +{ + // Is the descended pointer in our scope? + if (ptr <= mEnd) + { + // Does it affect our iterator? + if (ptr >= mItr && mItr != mEnd) + { + ++mItr; + } + } + // Is the descended pointer out of our scope? + else if (ptr > mEnd) + { + ++mItr, ++mEnd; + } + // Is this that last scope? + if (mChild != nullptr) + { + mChild->Lead(ptr); // Let the others know as well + } +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Scope::Tail(Pointer ptr) +{ + // Is the descended pointer in our scope? + if (ptr <= mEnd) + { + // Did this scope already finish processing? + if (mItr != mEnd) + { + // Does it affect our iterator? + if (ptr < mItr) + { + --mItr; + } + // Update the end iterator + --mEnd; + } + } + // Is this that last scope? + if (mChild != nullptr) + { + mChild->Tail(ptr); // Let the others know as well + } +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Scope::Finish() +{ + // Forcefully skip all remaining slots + mItr = mEnd; + // Is this that last scope? + if (mChild != nullptr) + { + mChild->Finish(); // Let the others know as well + } +} + +// ------------------------------------------------------------------------------------------------ +Signal::Signal() + : m_Used(0) + , m_Size(SMB_SIZE) + , m_Slots(m_SMB) + , m_Scope(nullptr) + , m_Name() + , m_Data() +{ + s_FreeSignals.push_back(this); +} + +// ------------------------------------------------------------------------------------------------ +Signal::Signal(String && name) + : m_Used(0) + , m_Size(SMB_SIZE) + , m_Slots(m_SMB) + , m_Scope(nullptr) + , m_Name(std::forward< String >(name)) + , m_Data() +{ + if (m_Name.empty()) + { + s_FreeSignals.push_back(this); + } +} +// ------------------------------------------------------------------------------------------------ +Signal::~Signal() +{ + ClearSlots(); + // Should we erase this from the fee signals list? + if (m_Name.empty()) + { + s_FreeSignals.erase(std::remove(s_FreeSignals.begin(), s_FreeSignals.end(), this), + s_FreeSignals.end()); + } +} + +// ------------------------------------------------------------------------------------------------ +bool Signal::AdjustSlots(SizeType capacity) +{ + // Is it necessary to resize? + if (capacity <= m_Size) + { + return true; // Already have that memory available! + } + // Do not alter the current capacity + SizeType size = m_Size; + // Calculate the next optimal size of the buffer + while (size < capacity) + { + size += (size + 1) >> 1; + } + // Attempt to allocate a memory buffer of the resulted size + Pointer slots = reinterpret_cast< Pointer >(new uint8_t[size * sizeof(Slot)]); + // See if the memory could be allocated + if (slots == nullptr) + { + return false; // Unable to acquire the memory! + } + // Do not alter the pointer to the new buffer + Pointer dest = slots; + // Are there any existing slots? + if (m_Used) + { + // Grab the range of slots to be transfered + Pointer src = m_Slots, end = (m_Slots + m_Used); + // Transfer the existing slots + while (src != end) + { + // Transfer to the new buffer + new (dest++) Slot(std::move(*(src))); + // Destroy the old instance + (src++)->~Slot(); + } + // Grab the end of the remaining slots + end = (m_Slots + m_Size); + // Destroy the remaining slots + while (src != end) + { + (src++)->~Slot(); + } + } + // Grab the end of the new buffer + Pointer end = (slots + size); + // Initialize the remaining slots + while (dest != end) + { + new (dest++) Slot(); + } + // Update the iterators from current scopes + for (Scope * scope = m_Scope; scope != nullptr; scope = scope->mChild) + { + scope->mItr = slots + (scope->mItr - m_Slots); + scope->mEnd = slots + (scope->mEnd - m_Slots); + } + // Should we delete the current buffer? + if (m_Slots != m_SMB) + { + delete[] reinterpret_cast< uint8_t * >(m_Slots); + } + // Assign the new buffer + m_Slots = slots; + // Assign the new capacity + m_Size = size; + // The buffer was successfully adjusted + return true; +} + +// ------------------------------------------------------------------------------------------------ +void Signal::ClearSlots() +{ + // Release every connected slot + for (Pointer itr = m_Slots, end = m_Slots + m_Used; itr != end; ++itr) + { + itr->Release(); + } + // Are we currently signaling? + if (m_Scope != nullptr) + { + m_Scope->Finish(); // Update iterators + } +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Connect(SignalWrapper & w) +{ + // Make sure we have enough space to store the slot + if ((m_Used < m_Size) || AdjustSlots(m_Used + 1)) + { + m_Slots[m_Used++].Swap(w.mSlot); // Connect the slot to the signal + } + else + { + sq_throwerror(w.mVM, "Unable to acquire enough memory"); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::ConnectOnce(SignalWrapper & w) +{ + // Disconnect every occurrence of this slot first + w.mRes = Eliminate(w); + // Did we fail to disconnect it? + if (SQ_FAILED(w.mRes)) + { + return w.mRes; // Propagate the error + } + // Finally, attempt to connect it again + return Connect(w); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal:: Disconnect(SignalWrapper & w) +{ + return Eliminate(w); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Exists(SignalWrapper & w) +{ + // Forward the call to the actual function + const bool r = ExistsIf(MatchSlot< Slot >(w.mSlot.mThisHash, w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushbool(w.mVM, r); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::ExistsThis(SignalWrapper & w) +{ + // Forward the call to the actual function + const bool r = ExistsIf(MatchThis< Slot >(w.mSlot.mThisHash), m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushbool(w.mVM, r); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::ExistsFunc(SignalWrapper & w) +{ + // Forward the call to the actual function + const bool r = ExistsIf(MatchFunc< Slot >(w.mSlot.mFuncHash), m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushbool(w.mVM, r); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Count(SignalWrapper & w) +{ + // Forward the call to the actual function + const SizeType r = CountIf(MatchSlot< Slot >(w.mSlot.mThisHash, w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushinteger(w.mVM, static_cast< SQInteger >(r)); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::CountThis(SignalWrapper & w) +{ + // Forward the call to the actual function + const SizeType r = CountIf(MatchThis< Slot >(w.mSlot.mThisHash), m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushinteger(w.mVM, static_cast< SQInteger >(r)); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::CountFunc(SignalWrapper & w) +{ + // Forward the call to the actual function + const SizeType r = CountIf(MatchFunc< Slot >(w.mSlot.mFuncHash), m_Slots, m_Slots + m_Used); + // Push the resulted value on the stack + sq_pushinteger(w.mVM, static_cast< SQInteger >(r)); + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Lead(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + LeadIf(MatchSlot< Slot >(w.mSlot.mThisHash, w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::LeadThis(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + LeadIf(MatchThis< Slot >(w.mSlot.mThisHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::LeadFunc(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + LeadIf(MatchFunc< Slot >(w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Tail(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + TailIf(MatchSlot< Slot >(w.mSlot.mThisHash, w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::TailThis(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + TailIf(MatchThis< Slot >(w.mSlot.mThisHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::TailFunc(SignalWrapper & w) +{ + // Make sure that there's more than one slot connected + if (m_Used > 1) + { + TailIf(MatchFunc< Slot >(w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used, w.mOne, w.mAppend, m_Scope); + } + // Specify that we don't return a value + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Eliminate(SignalWrapper & w) +{ + // Make sure that there's at least one slot connected + if (m_Used != 0) + { + // Backup the current number of used slots + const SizeType count = m_Used; + // Forward the call to the actual function + RemoveIf(MatchSlot< Slot >(w.mSlot.mThisHash, w.mSlot.mFuncHash), + m_Slots, m_Slots + m_Used, m_Scope); + // Push the number of removed slots + sq_pushinteger(w.mVM, static_cast< SQInteger >(count - m_Used)); + } + else + { + sq_pushinteger(w.mVM, 0); + } + + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::EliminateThis(SignalWrapper & w) +{ + // Make sure that there's at least one slot connected + if (m_Used != 0) + { + // Backup the current number of used slots + const SizeType count = m_Used; + // Forward the call to the actual function + RemoveIf(MatchThis< Slot >(w.mSlot.mThisHash), m_Slots, m_Slots + m_Used, m_Scope); + // Push the number of removed slots + sq_pushinteger(w.mVM, static_cast< SQInteger >(count - m_Used)); + } + else + { + sq_pushinteger(w.mVM, 0); + } + + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::EliminateFunc(SignalWrapper & w) +{ + // Make sure that there's at least one slot connected + if (m_Used != 0) + { + // Backup the current number of used slots + const SizeType count = m_Used; + // Forward the call to the actual function + RemoveIf(MatchFunc< Slot >(w.mSlot.mFuncHash), m_Slots, m_Slots + m_Used, m_Scope); + // Push the number of removed slots + sq_pushinteger(w.mVM, static_cast< SQInteger >(count - m_Used)); + } + else + { + sq_pushinteger(w.mVM, 0); + } + + // Specify that we returned a value + return 1; +} + +// ------------------------------------------------------------------------------------------------ +#define SQMOD_SIGNAL_CONTROL_WRAPPER(_f, _e) /* +*/ SQInteger Signal::Sq##_f(HSQUIRRELVM vm) { /* +*/ SignalWrapper w(vm, _e); /* +*/ if (SQ_FAILED(w.mRes)) return w.mRes; /* +*/ else return w.mSignal->_f(w); /* +*/ } /* +*/ /* +*/ + +// ------------------------------------------------------------------------------------------------ +SQMOD_SIGNAL_CONTROL_WRAPPER(Connect, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(ConnectOnce, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(Exists, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(Disconnect, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(ExistsThis, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(ExistsFunc, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(Count, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(CountThis, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(CountFunc, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(Lead, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(LeadThis, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(LeadFunc, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(Tail, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(TailThis, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(TailFunc, true) +SQMOD_SIGNAL_CONTROL_WRAPPER(Eliminate, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(EliminateThis, false) +SQMOD_SIGNAL_CONTROL_WRAPPER(EliminateFunc, false) + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Emit(HSQUIRRELVM vm, SQInteger top) +{ + // Are there any slots connected? + if (!m_Used) return 0; + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Contains the last received result + SQRESULT res = SQ_OK; + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Are there any parameters to forward? + if (top > 1) + { + for (SQInteger i = 2; i <= top; ++i) + { + sq_push(vm, i); + } + } + // Make the function call and store the result + res = sq_call(vm, top, false, ErrorHandling::IsEnabled()); + // Pop the callback object from the stack + sq_pop(vm, 1); + // Validate the result + if (SQ_FAILED(res)) + { + break; // Stop emitting signals + } + } + // Return the last result + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Query(HSQUIRRELVM vm, SQInteger top) +{ + // Are there any slots connected? + if (!m_Used) return 0; + // The collector and the specified environment + HSQOBJECT cthis, cfunc; + // Attempt to grab the collector environment + SQRESULT res = sq_getstackobj(vm, 2, &cthis); + // Validate the result + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + // Was there a valid environment? + else if (sq_isnull(cthis)) + { + // Default to the root table + sq_pushroottable(vm); + // Try to grab the collector environment again + res = sq_getstackobj(vm, -1, &cthis); + // Pop the root table from the stack + sq_pop(vm, 1); + // Validate the result + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + } + // Grab the collector callback + res = sq_getstackobj(vm, 3, &cfunc); + // Validate the result + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + // Some dummy checks to make sure the collector is a callable object + else if (!(sq_type(cfunc) & (_RT_CLOSURE | _RT_NATIVECLOSURE))) + { + return sq_throwerror(vm, "Invalid collector callback"); + } + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Are there any parameters to forward? + if (top > 3) + { + for (SQInteger i = 4; i <= top; ++i) + { + sq_push(vm, i); + } + } + // Make the function call and store the result + res = sq_call(vm, top-2, true, ErrorHandling::IsEnabled()); + // Validate the result + if (SQ_FAILED(res)) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // Stop emitting signals + break; + } + // Push the collector onto the stack + sq_pushobject(vm, cfunc); + sq_pushobject(vm, cthis); + // Push the returned value + sq_push(vm, -3); + // Make the function call and store the result + res = sq_call(vm, 2, false, ErrorHandling::IsEnabled()); + // Pop the callback object, return value and collector from the stack + sq_pop(vm, 3); + // Validate the result + if (SQ_FAILED(res)) + { + break; // Stop emitting signals + } + } + // Return the last result + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Consume(HSQUIRRELVM vm, SQInteger top) +{ + // Are there any slots connected? + if (!m_Used) return 0; + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Contains the last received result + SQRESULT res = SQ_OK; + // Default to not consumed + SQBool ret = SQFalse; + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Are there any parameters to forward? + if (top > 1) + { + for (SQInteger i = 2; i <= top; ++i) + { + sq_push(vm, i); + } + } + // Make the function call and store the result + res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); + // Validate the result + if (SQ_FAILED(res)) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // Stop emitting signals + break; + } + // Is the returned value not null? + else if (sq_gettype(vm, -1) != OT_NULL) + { + // Obtain the returned value + sq_tobool(vm, -1, &ret); + // Should we proceed to the next slot or stop here? + if (ret == SQTrue) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // The slot consumed the signal + break; + } + } + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + } + // Did we fail to process slots? + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + // Forward the returned value to the invoker + sq_pushbool(vm, ret); + // Specify that we returned something + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Approve(HSQUIRRELVM vm, SQInteger top) +{ + // Are there any slots connected? + if (!m_Used) return 0; + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Contains the last received result + SQRESULT res = SQ_OK; + // Default to approved + SQBool ret = SQTrue; + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Are there any parameters to forward? + if (top > 1) + { + for (SQInteger i = 2; i <= top; ++i) + { + sq_push(vm, i); + } + } + // Make the function call and store the result + res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); + // Validate the result + if (SQ_FAILED(res)) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // Stop emitting signals + break; + } + // Is the returned value not null? + else if (sq_gettype(vm, -1) != OT_NULL) + { + // Obtain the returned value + sq_tobool(vm, -1, &ret); + // Should we proceed to the next slot or stop here? + if (ret == SQFalse) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // The slot did not approve the signal + break; + } + } + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + } + // Did we fail to process slots? + if (SQ_FAILED(res)) + { + return res; // Propagate the error + } + // Forward the returned value to the invoker + sq_pushbool(vm, ret); + // Specify that we returned something + return 1; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::Request(HSQUIRRELVM vm, SQInteger top) +{ + // Are there any slots connected? + if (!m_Used) return 0; + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Contains the last received result + SQRESULT res = SQ_OK; + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Are there any parameters to forward? + if (top > 1) + { + for (SQInteger i = 2; i <= top; ++i) + { + sq_push(vm, i); + } + } + // Make the function call and store the result + res = sq_call(vm, top, true, ErrorHandling::IsEnabled()); + // Validate the result + if (SQ_FAILED(res)) + { + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + // Stop emitting signals + break; + } + // Is the returned value not null? + else if (sq_gettype(vm, -1) != OT_NULL) + { + // Remove the callback object from the stack + sq_remove(vm, -2); + // Specify that we returned something + res = 1; + // The slot did not approve the signal + break; + } + // Pop the callback object and return value from the stack + sq_pop(vm, 2); + } + // Return the last result + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::SqEmit(HSQUIRRELVM vm) +{ + const SQInteger top = sq_gettop(vm); + // Contains the last received result + SQRESULT res = SQ_OK; + // Attempt to forward the call to the signal instance + try + { + // Attempt to grab the signal instance from the stack + Signal * signal = Var< Signal * >(vm, 1).value; + // Do we have a valid signal instance? + if (!signal) + { + res = sq_throwerror(vm, "Invalid signal instance"); + } + // Forward the call to the signal instance + else + { + res = signal->Emit(vm, top); + } + } + catch (const Sqrat::Exception & e) + { + res = sq_throwerror(vm, e.what()); + } + // The execution was successful + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::SqQuery(HSQUIRRELVM vm) +{ + const SQInteger top = sq_gettop(vm); + // Do we have the collector environment? + if (top <= 1) + { + return sq_throwerror(vm, "Missing collector environment"); + } + // Do we have the collector callback? + else if (top <= 2) + { + return sq_throwerror(vm, "Missing collector callback"); + } + // Contains the last received result + SQRESULT res = SQ_OK; + // Attempt to forward the call to the signal instance + try + { + // Attempt to grab the signal instance from the stack + Signal * signal = Var< Signal * >(vm, 1).value; + // Do we have a valid signal instance? + if (!signal) + { + res = sq_throwerror(vm, "Invalid signal instance"); + } + // Forward the call to the signal instance + else + { + res = signal->Query(vm, top); + } + } + catch (const Sqrat::Exception & e) + { + res = sq_throwerror(vm, e.what()); + } + // The execution was successful + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::SqConsume(HSQUIRRELVM vm) +{ + const SQInteger top = sq_gettop(vm); + // Contains the last received result + SQRESULT res = SQ_OK; + // Attempt to forward the call to the signal instance + try + { + // Attempt to grab the signal instance from the stack + Signal * signal = Var< Signal * >(vm, 1).value; + // Do we have a valid signal instance? + if (!signal) + { + res = sq_throwerror(vm, "Invalid signal instance"); + } + // Forward the call to the signal instance + else + { + res = signal->Consume(vm, top); + } + } + catch (const Sqrat::Exception & e) + { + res = sq_throwerror(vm, e.what()); + } + // The execution was successful + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::SqApprove(HSQUIRRELVM vm) +{ + const SQInteger top = sq_gettop(vm); + // Contains the last received result + SQRESULT res = SQ_OK; + // Attempt to forward the call to the signal instance + try + { + // Attempt to grab the signal instance from the stack + Signal * signal = Var< Signal * >(vm, 1).value; + // Do we have a valid signal instance? + if (!signal) + { + res = sq_throwerror(vm, "Invalid signal instance"); + } + // Forward the call to the signal instance + else + { + res = signal->Approve(vm, top); + } + } + catch (const Sqrat::Exception & e) + { + res = sq_throwerror(vm, e.what()); + } + // The execution was successful + return res; +} + +// ------------------------------------------------------------------------------------------------ +SQInteger Signal::SqRequest(HSQUIRRELVM vm) +{ + const SQInteger top = sq_gettop(vm); + // Contains the last received result + SQRESULT res = SQ_OK; + // Attempt to forward the call to the signal instance + try + { + // Attempt to grab the signal instance from the stack + Signal * signal = Var< Signal * >(vm, 1).value; + // Do we have a valid signal instance? + if (!signal) + { + res = sq_throwerror(vm, "Invalid signal instance"); + } + // Forward the call to the signal instance + else + { + res = signal->Request(vm, top); + } + } + catch (const Sqrat::Exception & e) + { + res = sq_throwerror(vm, e.what()); + } + // The execution was successful + return res; +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Terminate() +{ + // Terminate named signals + for (const auto & s : s_Signals) + { + // Clear slots + s.second.first->ClearSlots(); + // Release the name + s.second.first->m_Name.clear(); + // Release whatever is in the user data + s.second.first->m_Data.Release(); + } + // Finally clear the container itself + s_Signals.clear(); + // Create a copy so we don't invalidate iterators when destructor removes the instances + FreeSignals fsig(s_FreeSignals); + // Terminate anonymous signals + for (const auto & s : fsig) + { + // Clear slots + s->ClearSlots(); + // Release whatever is in the user data + s->m_Data.Release(); + } + // Finally clear the container itself + s_FreeSignals.clear(); +} + +// ------------------------------------------------------------------------------------------------ +LightObj Signal::CreateFree() +{ + // Remember the current stack size + const StackGuard sg; + // Create the signal instance + DeleteGuard< Signal > dg(new Signal()); + // Attempt to create the signal instance + ClassType< Signal >::PushInstance(DefaultVM::Get(), dg.Get()); + // This is now managed by the script + dg.Release(); + // Return the created signal + return Var< LightObj >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ +LightObj Signal::Create(const StackStrF & name) +{ + // Validate the signal name + if (name.mLen <= 0) + { + return CreateFree(); + } + // Create a copy of the name + String sname(name.mPtr, name.mLen); + // Compute the hash of the specified name + const std::size_t hash = std::hash< String >{}(sname); + // See if the signal already exists + for (const auto & e : s_Signals) + { + if (e.first == hash) + { + return e.second.second.mObj; // Found a match so let's return it + } + } + // Remember the current stack size + const StackGuard sg; + // Create the signal instance + DeleteGuard< Signal > dg(new Signal(std::move(sname))); + // Grab the signal instance pointer + Signal * ptr = dg.Get(); + // Attempt to create the signal instance + ClassType< Signal >::PushInstance(DefaultVM::Get(), ptr); + // This is now managed by the script + dg.Release(); + // Grab a reference to the instance created on the stack + s_Signals.emplace_back(hash, SignalPair(ptr, Var< LightObj >(DefaultVM::Get(), -1).value)); + // Return the created signal + return s_Signals.back().second.second.mObj; +} + +// ------------------------------------------------------------------------------------------------ +void Signal::Remove(const StackStrF & name) +{ + // Validate the signal name + if (name.mLen <= 0) + { + //STHROWF("Signals without names cannot be removed manually"); + } + // Create a copy of the name + const String sname(name.mPtr, name.mLen); + // Compute the hash of the specified name + const std::size_t hash = std::hash< String >{}(sname); + // Iterator to the existing signal, if any + SignalPool::const_iterator itr = s_Signals.cbegin(); + // Search for a signal with this name + for (; itr != s_Signals.cend(); ++itr) + { + if (itr->first == hash) + { + break; + } + } + // Did we find anything? + if (itr != s_Signals.cend()) + { + // Clear the name + itr->second.first->m_Name.clear(); + // Put it on the free list + s_FreeSignals.push_back(itr->second.first); + // Finally, remove it from the named list + s_Signals.erase(itr); + } +} + +// ------------------------------------------------------------------------------------------------ +const LightObj & Signal::Fetch(const StackStrF & name) +{ + // Validate the signal name + if (name.mLen <= 0) + { + //STHROWF("Signals without names cannot be retrieved manually"); + } + // Create a copy of the name + const String sname(name.mPtr, name.mLen); + // Compute the hash of the specified name + const std::size_t hash = std::hash< String >{}(sname); + // Search for a signal with this name + for (const auto & e : s_Signals) + { + if (e.first == hash) + { + return e.second.second; // Found a match so let's return it + } + } + // No such signal exists + //STHROWF("Unknown signal named (%s)", sname.c_str()); + // SHOULD NOT REACH THIS POINT! + static LightObj slo; + return slo; +} + +/* ------------------------------------------------------------------------------------------------ + * Forward the call to terminate the signals. +*/ +void TerminateSignals() +{ + Signal::Terminate(); +} + +// ------------------------------------------------------------------------------------------------ +void InitSignalPair(SignalPair & sp, LightObj & et, const char * name) +{ + // Remember the current stack size + const StackGuard sg; + // Create the signal instance + DeleteGuard< Signal > dg(new Signal()); + // Attempt to create the signal instance object + sp.second = LightObj(dg.Get()); + // Assign the signal instance itself + sp.first = dg.Get(); + // This is now managed by the script + dg.Release(); + // Should we bind this to a certain object? + if (name != nullptr) + { + et.Bind(name, sp.second); // Bind the signal to the specified object + } +} + +// ------------------------------------------------------------------------------------------------ +void ResetSignalPair(SignalPair & sp, bool clear) +{ + // See if the slots must be cleared as well + if (clear && sp.first != nullptr) + { + sp.first->ClearSlots(); + } + // Reset the signal pair + sp.first = nullptr; + sp.second.Release(); +} + +// ================================================================================================ +void Register_Signal(HSQUIRRELVM vm) +{ + + RootTable(vm).Bind(Typename::Str, + Class< Signal, NoConstructor< Signal > >(vm, Typename::Str) + // Meta-methods + .SquirrelFunc(_SC("_typename"), &Typename::Fn) + .Func(_SC("_tostring"), &Signal::ToString) + // Core Properties + .Prop(_SC("Data"), &Signal::GetData, &Signal::SetData) + .Func(_SC("Name"), &Signal::ToString) + .Prop(_SC("Slots"), &Signal::GetUsed) + .Prop(_SC("Empty"), &Signal::IsEmpty) + // Core Methods + .Func(_SC("Clear"), &Signal::ClearSlots) + // Squirrel Functions + .SquirrelFunc(_SC("Connect"), &Signal::SqConnect) + .SquirrelFunc(_SC("ConnectOnce"), &Signal::SqConnectOnce) + .SquirrelFunc(_SC("Exists"), &Signal::SqExists) + .SquirrelFunc(_SC("Disconnect"), &Signal::SqDisconnect) + .SquirrelFunc(_SC("ExistsThis"), &Signal::SqExistsThis) + .SquirrelFunc(_SC("ExistsFunc"), &Signal::SqExistsFunc) + .SquirrelFunc(_SC("Count"), &Signal::SqCount) + .SquirrelFunc(_SC("CountThis"), &Signal::SqCountThis) + .SquirrelFunc(_SC("CountFunc"), &Signal::SqCountFunc) + .SquirrelFunc(_SC("Lead"), &Signal::SqLead) + .SquirrelFunc(_SC("LeadThis"), &Signal::SqLeadThis) + .SquirrelFunc(_SC("LeadFunc"), &Signal::SqLeadFunc) + .SquirrelFunc(_SC("Tail"), &Signal::SqTail) + .SquirrelFunc(_SC("TailThis"), &Signal::SqTailThis) + .SquirrelFunc(_SC("TailFunc"), &Signal::SqTailFunc) + .SquirrelFunc(_SC("Eliminate"), &Signal::SqEliminate) + .SquirrelFunc(_SC("EliminateThis"), &Signal::SqEliminateThis) + .SquirrelFunc(_SC("EliminateFunc"), &Signal::SqEliminateFunc) + .SquirrelFunc(_SC("Emit"), &Signal::SqEmit) + .SquirrelFunc(_SC("Query"), &Signal::SqQuery) + .SquirrelFunc(_SC("Consume"), &Signal::SqConsume) + .SquirrelFunc(_SC("Approve"), &Signal::SqApprove) + .SquirrelFunc(_SC("Request"), &Signal::SqRequest) + ); + + RootTable(vm) + .FmtFunc(_SC("SqSignal"), &Signal::Fetch) + .FmtFunc(_SC("SqCreateSignal"), &Signal::Create) + .FmtFunc(_SC("SqRemoveSignal"), &Signal::Remove); +} + +} // Namespace:: SqMod diff --git a/source/Signal.hpp b/source/Signal.hpp new file mode 100644 index 00000000..29acb878 --- /dev/null +++ b/source/Signal.hpp @@ -0,0 +1,767 @@ +#ifndef _SIGNAL_HPP_ +#define _SIGNAL_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Base/Shared.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +struct Signal; +struct SignalWrapper; + +/* ------------------------------------------------------------------------------------------------ + * Class used to deliver events to one or more listeners. +*/ +struct Signal +{ + friend class SignalWrapper; + // -------------------------------------------------------------------------------------------- + typedef unsigned int SizeType; // Type of value used to represent sizes and/or indexes. + // -------------------------------------------------------------------------------------------- + enum { SMB_SIZE = 8 }; + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + Signal(); + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + explicit Signal(const char * name) + : Signal(String(name)) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + explicit Signal(const String & name) + : Signal(String(name)) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + Signal(String && name); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor (disabled). + */ + Signal(const Signal & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor (disabled). + */ + Signal(Signal && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~Signal(); + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator (disabled). + */ + Signal & operator = (const Signal & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator (disabled). + */ + Signal & operator = (Signal && o) = delete; + +protected: + + /* -------------------------------------------------------------------------------------------- + * Adjust the internal buffer size if necessary. + */ + bool AdjustSlots(SizeType capacity); + + /* -------------------------------------------------------------------------------------------- + * Structure responsible for storing information about a slot. + */ + struct Slot { + SQHash mThisHash; // The hash of the specified environment. + SQHash mFuncHash; // The hash of the specified callback. + HSQOBJECT mThisRef; // The specified script environment. + HSQOBJECT mFuncRef; // The specified script callback. + + /* ---------------------------------------------------------------------------------------- + * Default constructor. + */ + Slot() + : mThisHash(0) + , mFuncHash(0) + , mThisRef() + , mFuncRef() + { + sq_resetobject(&mThisRef); + sq_resetobject(&mFuncRef); + } + + /* ---------------------------------------------------------------------------------------- + * Forwarding constructor. + */ + Slot(Object & env, Function & func) + : Slot(env.GetObject(), func.GetFunc()) + { + /* ... */ + } + + /* ---------------------------------------------------------------------------------------- + * Base constructor. + */ + Slot(HSQOBJECT & env, HSQOBJECT & func) + : mThisHash(0) + , mFuncHash(0) + , mThisRef(env) + , mFuncRef(func) + { + HSQUIRRELVM vm = DefaultVM::Get(); + // Remember the current stack size + const StackGuard sg(vm); + // Is there an explicit environment? + if (!sq_isnull(mThisRef)) + { + // Keep a reference to this environment + sq_addref(vm, &mThisRef); + // Push the environment on the stack + sq_pushobject(vm, mThisRef); + // Grab the hash of the environment object + mThisHash = sq_gethash(vm, -1); + } + // Is there an explicit function? + if (!sq_isnull(mFuncRef)) + { + // Keep a reference to this function + sq_addref(vm, &mFuncRef); + // Push the callback on the stack + sq_pushobject(vm, mFuncRef); + // Grab the hash of the callback object + mFuncHash = sq_gethash(vm, -1); + } + } + /* ---------------------------------------------------------------------------------------- + * Base constructor. + */ + Slot(HSQOBJECT & env, HSQOBJECT & func, SQHash envh, SQHash funch) + : mThisHash(envh) + , mFuncHash(funch) + , mThisRef(env) + , mFuncRef(func) + { + + } + + /* ---------------------------------------------------------------------------------------- + * Copy constructor. + */ + Slot(const Slot & o) + : mThisHash(o.mThisHash) + , mFuncHash(o.mFuncHash) + , mThisRef(o.mThisRef) + , mFuncRef(o.mFuncRef) + { + // Track reference + if (mFuncHash != 0) + { + sq_addref(DefaultVM::Get(), &mThisRef); + sq_addref(DefaultVM::Get(), &mFuncRef); + } + } + + /* ---------------------------------------------------------------------------------------- + * Move constructor. + */ + Slot(Slot && o) + : mThisHash(o.mThisHash) + , mFuncHash(o.mFuncHash) + , mThisRef(o.mThisRef) + , mFuncRef(o.mFuncRef) + { + // Take ownership + sq_resetobject(&o.mThisRef); + sq_resetobject(&o.mFuncRef); + } + + /* ---------------------------------------------------------------------------------------- + * Destructor. + */ + ~Slot() + { + Release(); + } + + /* ---------------------------------------------------------------------------------------- + * Copy assignment operator. (disabled) + */ + Slot & operator = (const Slot & o) + { + if (this != &o) + { + // Release current resources, if any + Release(); + // Replicate data + mThisHash = o.mThisHash; + mFuncHash = o.mFuncHash; + mThisRef = o.mThisRef; + mFuncRef = o.mFuncRef; + // Track reference + sq_addref(DefaultVM::Get(), &const_cast< HSQOBJECT & >(o.mThisRef)); + sq_addref(DefaultVM::Get(), &const_cast< HSQOBJECT & >(o.mFuncRef)); + } + + return *this; + } + + /* ---------------------------------------------------------------------------------------- + * Move assignment operator. + */ + Slot & operator = (Slot && o) + { + if (this != &o) + { + // Release current resources, if any + Release(); + // Replicate data + mThisHash = o.mThisHash; + mFuncHash = o.mFuncHash; + mThisRef = o.mThisRef; + mFuncRef = o.mFuncRef; + // Take ownership + sq_resetobject(&o.mThisRef); + sq_resetobject(&o.mFuncRef); + } + + return *this; + } + + /* ---------------------------------------------------------------------------------------- + * Equality comparison operator. + */ + bool operator == (const Slot & o) const + { + return (mThisHash == o.mThisHash) && (mFuncHash == o.mFuncHash); + } + + /* ---------------------------------------------------------------------------------------- + * Inequality comparison operator. + */ + bool operator != (const Slot & o) const + { + return (mThisHash != o.mThisHash) || (mFuncHash != o.mFuncHash); + } + + /* ---------------------------------------------------------------------------------------- + * Release managed script resources. + */ + bool Available() const + { + return (mFuncHash == 0); + } + + /* ---------------------------------------------------------------------------------------- + * Release managed script resources. + */ + void Release() + { + // Should we release any environment object? + if (mThisHash != 0) + { + sq_release(DefaultVM::Get(), &mThisRef); + sq_resetobject(&mThisRef); + // Also reset the hash + mThisHash = 0; + } + // Should we release any callback object? + if (mFuncHash != 0) + { + sq_release(DefaultVM::Get(), &mFuncRef); + sq_resetobject(&mFuncRef); + // Also reset the hash + mFuncHash = 0; + } + } + + /* ---------------------------------------------------------------------------------------- + * Swap the values of two slots. + */ + void Swap(Slot & s) + { + // Swap the environment hash + SQHash h = mThisHash; + mThisHash = s.mThisHash; + s.mThisHash = h; + // Swap the callback hash + h = mFuncHash; + mFuncHash = s.mFuncHash; + s.mFuncHash = h; + // Swap the environment object + HSQOBJECT o = mThisRef; + mThisRef = s.mThisRef; + s.mThisRef = o; + // Swap the callback object + o = mFuncRef; + mFuncRef = s.mFuncRef; + s.mFuncRef = o; + } + }; + + // -------------------------------------------------------------------------------------------- + typedef Slot ValueType; // Value type used to represent a slot. + typedef ValueType & Reference; // Reference to the stored value type + typedef const ValueType & ConstReference; // Constant reference to the stored value type. + typedef ValueType * Pointer; // Pointer to the stored value type + typedef const ValueType * ConstPointer; // Constant pointer to the stored value type. + + // -------------------------------------------------------------------------------------------- + /// Execution scope used to adjust iterators when removing slots or adjusting the buffer. + struct Scope { + // ---------------------------------------------------------------------------------------- + Pointer mItr; ///< Currently executed slot. + Pointer mEnd; ///< Where the execution ends. + Scope * mParent; ///< Previous execution scope. + Scope * mChild; ///< Next execution scope. + // ---------------------------------------------------------------------------------------- + /// Default constructor. + Scope(Scope * parent, Pointer begin, Pointer end) + : mItr(begin), mEnd(end), mParent(parent), mChild(nullptr) + { + if (mParent != nullptr) mParent->mChild = this; + } + // ---------------------------------------------------------------------------------------- + /// Destructor. + ~Scope() { + if (mParent != nullptr) mParent->mChild = nullptr; + } + // ---------------------------------------------------------------------------------------- + /// Adjust the iterators to account for the fact that the specified slot was removed. + void Descend(Pointer ptr); + /// Adjust the iterators to account for the fact that the specified slot is now leading. + void Lead(Pointer ptr); + /// Adjust the iterators to account for the fact that the specified slot is now tailing. + void Tail(Pointer ptr); + /// Adjust the iterators to finish the execution abruptly. + void Finish(); + }; + +private: + + // -------------------------------------------------------------------------------------------- + SizeType m_Used; // The number of stored slots that are valid. + SizeType m_Size; // The size of the memory allocated for slots. + Pointer m_Slots; // Pointer to the memory containing the slots. + // -------------------------------------------------------------------------------------------- + Scope * m_Scope; // Current execution state. + // -------------------------------------------------------------------------------------------- + String m_Name; // The name that identifies this signal. + LightObj m_Data; // User data associated with this instance. + // -------------------------------------------------------------------------------------------- + ValueType m_SMB[SMB_SIZE]{}; // Small buffer optimization. + +public: + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to convert an instance of this type to a string. + */ + const String & ToString() const + { + return m_Name; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the associated user data. + */ + LightObj & GetData() + { + return m_Data; + } + + /* -------------------------------------------------------------------------------------------- + * Modify the associated user data. + */ + void SetData(LightObj & data) + { + m_Data = data; + } + + /* -------------------------------------------------------------------------------------------- + * The number of slots connected to the signal. + */ + SQInteger GetUsed() const + { + return static_cast< SQInteger >(m_Used); + } + + /* -------------------------------------------------------------------------------------------- + * Clear all slots connected to the signal. + */ + void ClearSlots(); + + /* -------------------------------------------------------------------------------------------- + * See if there are any slots connected. + */ + bool IsEmpty() const + { + return (m_Used == 0); + } + +protected: + + /* -------------------------------------------------------------------------------------------- + * Connect the specified slot to the signal. + */ + SQInteger Connect(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Connect the specified slot but not before disconnecting all other occurrences. + */ + SQInteger ConnectOnce(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Disconnect all occurrences of the specified slot from the signal. + */ + SQInteger Disconnect(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * See if the specified slot is connected to the signal. + */ + SQInteger Exists(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * See if the specified slot environment is connected to the signal. + */ + SQInteger ExistsThis(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * See if the specified slot callback is connected to the signal. + */ + SQInteger ExistsFunc(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Count all occurrences of the specified slot. + */ + SQInteger Count(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Count all occurrences of the specified slot environment. + */ + SQInteger CountThis(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Count all occurrences of the specified slot callback. + */ + SQInteger CountFunc(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot to the front. + */ + SQInteger Lead(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot environment to the front. + */ + SQInteger LeadThis(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot callback to the front. + */ + SQInteger LeadFunc(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot to the back. + */ + SQInteger Tail(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot environment to the back. + */ + SQInteger TailThis(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Move all occurrences of the specified slot callback to the back. + */ + SQInteger TailFunc(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Remove all occurrences of the specified slot. + */ + SQInteger Eliminate(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Remove all occurrences of the specified slot environment. + */ + SQInteger EliminateThis(SignalWrapper & w); + + /* -------------------------------------------------------------------------------------------- + * Remove all occurrences of the specified slot callback. + */ + SQInteger EliminateFunc(SignalWrapper & w); + +public: + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Connect` method of this class. + */ + static SQInteger SqConnect(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `ConnectOnce` method of this class. + */ + static SQInteger SqConnectOnce(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Exists` method of this class. + */ + static SQInteger SqExists(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Disconnect` method of this class. + */ + static SQInteger SqDisconnect(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `ExistsThis` method of this class. + */ + static SQInteger SqExistsThis(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `ExistsFunc` method of this class. + */ + static SQInteger SqExistsFunc(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Count` method of this class. + */ + static SQInteger SqCount(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `CountThis` method of this class. + */ + static SQInteger SqCountThis(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `CountFunc` method of this class. + */ + static SQInteger SqCountFunc(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Lead` method of this class. + */ + static SQInteger SqLead(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `LeadThis` method of this class. + */ + static SQInteger SqLeadThis(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `LeadFunc` method of this class. + */ + static SQInteger SqLeadFunc(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Tail` method of this class. + */ + static SQInteger SqTail(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `TailThis` method of this class. + */ + static SQInteger SqTailThis(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `TailFunc` method of this class. + */ + static SQInteger SqTailFunc(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Eliminate` method of this class. + */ + static SQInteger SqEliminate(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `EliminateThis` method of this class. + */ + static SQInteger SqEliminateThis(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `EliminateFunc` method of this class. + */ + static SQInteger SqEliminateFunc(HSQUIRRELVM vm); + +protected: + + /* -------------------------------------------------------------------------------------------- + * Emit the event to the connected slots. + */ + SQInteger Emit(HSQUIRRELVM vm, SQInteger top); + + /* -------------------------------------------------------------------------------------------- + * Emit the event to the connected slots and collect returned values. + */ + SQInteger Query(HSQUIRRELVM vm, SQInteger top); + + /* -------------------------------------------------------------------------------------------- + * Emit the event to the connected slots and see if they consume it. + */ + SQInteger Consume(HSQUIRRELVM vm, SQInteger top); + + /* -------------------------------------------------------------------------------------------- + * Emit the event to the connected slots and see if they approve it. + */ + SQInteger Approve(HSQUIRRELVM vm, SQInteger top); + + /* -------------------------------------------------------------------------------------------- + * Emit the event to the connected slots and see if they return something. + */ + SQInteger Request(HSQUIRRELVM vm, SQInteger top); + +public: + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Emit` method of this class. + */ + static SQInteger SqEmit(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Query` method of this class. + */ + static SQInteger SqQuery(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Consume` method of this class. + */ + static SQInteger SqConsume(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Approve` method of this class. + */ + static SQInteger SqApprove(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Squirrel wrapper for the `Request` method of this class. + */ + static SQInteger SqRequest(HSQUIRRELVM vm); + +protected: + + // -------------------------------------------------------------------------------------------- + typedef std::pair< std::size_t, SignalPair > SignalElement; + typedef std::vector< SignalElement > SignalPool; + typedef std::vector< Signal * > FreeSignals; + + // -------------------------------------------------------------------------------------------- + static SignalPool s_Signals; // List of all created signals. + static FreeSignals s_FreeSignals; // List of signals without a name. + + /* -------------------------------------------------------------------------------------------- + * Specialization for when there are no arguments given. + */ + void PushParameters() + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Specialization for when there's only one argument given/remaining. + */ + template < typename T > void PushParameters(T v) + { + Var< T >::push(DefaultVM::Get(), v); + } + + /* -------------------------------------------------------------------------------------------- + * Specialization for when there's more than one argument given. + */ + template < typename T, typename... Args > void PushParameters(T v, Args... args) + { + Var< T >::push(DefaultVM::Get(), v); + PushParameters(args...); + } + +public: + + /* -------------------------------------------------------------------------------------------- + * Terminate all signal instances and release any script resources. + */ + static void Terminate(); + + /* -------------------------------------------------------------------------------------------- + * Create a free signal without a specific name. + */ + static LightObj CreateFree(); + + /* -------------------------------------------------------------------------------------------- + * Create a new signal with the specified name. + */ + static LightObj Create(const StackStrF & name); + + /* -------------------------------------------------------------------------------------------- + * Remove the signal with the specified name. + */ + static void Remove(const StackStrF & name); + + /* -------------------------------------------------------------------------------------------- + * Retrieve the signal with the specified name. + */ + static const LightObj & Fetch(const StackStrF & name); + + /* -------------------------------------------------------------------------------------------- + * Emit a signal from the module. + */ + template < typename... Args > void operator () (Args&&... args) + { + // Are there any slots connected? + if (!m_Used) return; + // Enter a new execution scope + Scope scope(m_Scope, m_Slots, m_Slots + m_Used); + // Activate the current scope and create a guard to restore it + const AutoAssign< Scope * > aa(m_Scope, scope.mParent, &scope); + // Grab the default virtual machine + HSQUIRRELVM vm = DefaultVM::Get(); + // Process the slots from this scope + while (scope.mItr != scope.mEnd) + { + // Grab a reference to the current slot + const Slot & slot = *(scope.mItr++); + // Push the callback object + sq_pushobject(vm, slot.mFuncRef); + // Is there an explicit environment? + if (slot.mThisHash == 0) + { + sq_pushroottable(vm); + } + else + { + sq_pushobject(vm, slot.mThisRef); + } + // Push the given parameters on the stack + PushParameters(args...); + // Make the function call and store the result + const SQRESULT res = sq_call(vm, 1 + sizeof...(Args), false, ErrorHandling::IsEnabled()); + // Pop the callback object from the stack + sq_pop(vm, 1); + // Validate the result + if (SQ_FAILED(res)) + { + SQTHROW(vm, LastErrorString(vm)); // Stop emitting signals + } + } + } +}; + +} // Namespace:: SqMod + +#endif // _SIGNAL_HPP_ diff --git a/source/SqBase.hpp b/source/SqBase.hpp index eae42049..58cb6fb7 100644 --- a/source/SqBase.hpp +++ b/source/SqBase.hpp @@ -241,6 +241,7 @@ typedef std::basic_string< SQChar > String; // ------------------------------------------------------------------------------------------------ class Core; class Logger; +class Signal; // ------------------------------------------------------------------------------------------------ class CmdManager; diff --git a/source/Tasks.cpp b/source/Tasks.cpp index a1f5bf8a..f0aaffaf 100644 --- a/source/Tasks.cpp +++ b/source/Tasks.cpp @@ -184,7 +184,7 @@ void Tasks::Deinitialize() } // ------------------------------------------------------------------------------------------------ -Object & Tasks::FindEntity(Int32 id, Int32 type) +LightObj & Tasks::FindEntity(Int32 id, Int32 type) { switch (type) { @@ -195,7 +195,7 @@ Object & Tasks::FindEntity(Int32 id, Int32 type) case ENT_PICKUP: return Core::Get().GetPickup(id).mObj; case ENT_PLAYER: return Core::Get().GetPlayer(id).mObj; case ENT_VEHICLE: return Core::Get().GetVehicle(id).mObj; - default: return NullObject(); + default: return NullLightObj(); } } diff --git a/source/Tasks.hpp b/source/Tasks.hpp index 946e0119..9b3a0e04 100644 --- a/source/Tasks.hpp +++ b/source/Tasks.hpp @@ -328,7 +328,7 @@ protected: /* -------------------------------------------------------------------------------------------- * Retrieve the instance of the specified entity. */ - static Object & FindEntity(Int32 id, Int32 type); + static LightObj & FindEntity(Int32 id, Int32 type); /* -------------------------------------------------------------------------------------------- * Find an unoccupied task slot.