From b3cdc101a48e79cc8fd4c02b5f273d57a817f1ae Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Mon, 19 Jun 2017 16:10:31 +0300 Subject: [PATCH] Do not overwrite the core state upon receiving recursive event calls from the server. And allow the script to implement a similar approach. --- source/Core.hpp | 64 ++++++++++++++++++++++++++++++++++++++++++++ source/CoreFuncs.cpp | 24 ++++++++++++++--- source/Main.cpp | 20 +++++++------- 3 files changed, 94 insertions(+), 14 deletions(-) diff --git a/source/Core.hpp b/source/Core.hpp index 353da6e5..550c9f63 100644 --- a/source/Core.hpp +++ b/source/Core.hpp @@ -1375,6 +1375,70 @@ public: SignalPair mOnScriptLoaded; }; +/* ------------------------------------------------------------------------------------------------ + * Structure used to preserve the core state across recursive event calls from the server. +*/ +struct CoreState +{ + /* -------------------------------------------------------------------------------------------- + * Backup the current core state. + */ + CoreState() + : m_State(Core::Get().GetState()) + { + //... + } + + /* -------------------------------------------------------------------------------------------- + * Backup the current core state and set the given state. + */ + CoreState(int s) + : m_State(Core::Get().GetState()) + { + Core::Get().SetState(s); + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor (disabled). + */ + CoreState(const CoreState & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor (disabled). + */ + CoreState(CoreState && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. Restore the grabbed core state. + */ + ~CoreState() + { + Core::Get().SetState(m_State); + } + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator (disabled). + */ + CoreState & operator = (const CoreState & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator (disabled). + */ + CoreState & operator = (CoreState && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Retrieve the guarded state. + */ + int GetValue() const + { + return m_State; + } + +protected: + + int m_State; // The core state at the time when this instance was created. +}; + } // Namespace:: SqMod #endif // _CORE_HPP_ diff --git a/source/CoreFuncs.cpp b/source/CoreFuncs.cpp index be5dfe39..cf4a6963 100644 --- a/source/CoreFuncs.cpp +++ b/source/CoreFuncs.cpp @@ -8,6 +8,9 @@ namespace SqMod { extern bool GetReloadStatus(); extern void SetReloadStatus(bool toggle); +// ------------------------------------------------------------------------------------------------ +SQMODE_DECL_TYPENAME(CoreStateTypename, _SC("SqCoreState")) + // ------------------------------------------------------------------------------------------------ static SQInteger SqLoadScript(HSQUIRRELVM vm) { @@ -308,8 +311,20 @@ static bool DelVehicle(Int32 id, Int32 header, LightObj & payload) // ================================================================================================ void Register_Core(HSQUIRRELVM vm) { - RootTable(vm) - .Bind(_SC("SqCore"), Table(vm) + Table corens(vm); + + corens.Bind(_SC("State"), + Class< CoreState, NoCopy< CoreState > >(vm, CoreStateTypename::Str) + // Constructors + .Ctor() + .Ctor< int >() + // Meta-methods + .SquirrelFunc(_SC("_typename"), &CoreStateTypename::Fn) + // Member Properties + .Prop(_SC("Value"), &CoreState::GetValue) + ); + + corens .Func(_SC("Reload"), &SqSetReloadStatus) .Func(_SC("Reloading"), &SqGetReloadStatus) .Func(_SC("ReloadBecause"), &SqReloadBecause) @@ -340,8 +355,9 @@ void Register_Core(HSQUIRRELVM vm) .Func(_SC("OnPostLoad"), &SqGetPostLoadEvent) .Func(_SC("OnUnload"), &SqGetUnloadEvent) .SquirrelFunc(_SC("LoadScript"), &SqLoadScript) - .SquirrelFunc(_SC("On"), &SqGetEvents) - ); + .SquirrelFunc(_SC("On"), &SqGetEvents); + + RootTable(vm).Bind(_SC("SqCore"), corens); } } // Namespace:: SqMod diff --git a/source/Main.cpp b/source/Main.cpp index 3a091f72..e34f32d7 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -78,7 +78,7 @@ void DoReload() static uint8_t OnServerInitialise(void) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -198,7 +198,7 @@ static void OnServerFrame(float elapsed_time) static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -216,7 +216,7 @@ static uint8_t OnIncomingConnection(CStr player_name, size_t name_buffer_size, CCStr user_password, CCStr ip_address) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -280,7 +280,7 @@ static void OnPlayerDisconnect(int32_t player_id, vcmpDisconnectReason reason) static uint8_t OnPlayerRequestClass(int32_t player_id, int32_t offset) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -297,7 +297,7 @@ static uint8_t OnPlayerRequestClass(int32_t player_id, int32_t offset) static uint8_t OnPlayerRequestSpawn(int32_t player_id) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -362,7 +362,7 @@ static void OnPlayerUpdate(int32_t player_id, vcmpPlayerUpdate update_type) static uint8_t OnPlayerRequestEnterVehicle(int32_t player_id, int32_t vehicle_id, int32_t slot_index) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -597,7 +597,7 @@ static void OnPlayerAwayChange(int32_t player_id, uint8_t is_away) static uint8_t OnPlayerMessage(int32_t player_id, CCStr message) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -614,7 +614,7 @@ static uint8_t OnPlayerMessage(int32_t player_id, CCStr message) static uint8_t OnPlayerCommand(int32_t player_id, CCStr message) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -631,7 +631,7 @@ static uint8_t OnPlayerCommand(int32_t player_id, CCStr message) static uint8_t OnPlayerPrivateMessage(int32_t player_id, int32_t target_player_id, CCStr message) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try { @@ -765,7 +765,7 @@ static void OnObjectTouched(int32_t object_id, int32_t player_id) static uint8_t OnPickupPickAttempt(int32_t pickup_id, int32_t player_id) { // Mark the initialization as successful by default - Core::Get().SetState(SQMOD_SUCCESS); + const CoreState cs(SQMOD_SUCCESS); // Attempt to forward the event try {