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

Implement a simple system for snippets to be notified when the scripts were loaded and about to be unloaded.

This commit is contained in:
Sandu Liviu Catalin 2016-08-25 03:08:44 +03:00
parent fae1e51c7b
commit 64416c093c
3 changed files with 175 additions and 0 deletions

View File

@ -144,6 +144,9 @@ Core::Core()
, m_Debugging(false)
, m_Executed(false)
, m_Shutdown(false)
, m_LockPreLoadSignal(false)
, m_LockPostLoadSignal(false)
, m_LockUnloadSignal(false)
{
/* ... */
}
@ -350,6 +353,11 @@ bool Core::Execute()
return false; // No reason to execute the plug-in
}
// Unlock signal containers
m_LockPreLoadSignal = false;
m_LockPostLoadSignal = false;
m_LockUnloadSignal = false;
LogDbg("Signaling outside plug-ins to register their API");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_LOAD_CMD, "");
@ -380,9 +388,27 @@ bool Core::Execute()
m_NullPlayer = Object(new CPlayer(-1));
m_NullVehicle = Object(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();
// 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();
// Import already existing entities
ImportPlayers();
ImportBlips();
@ -403,6 +429,15 @@ void Core::Terminate(bool shutdown)
// Is there a virtual machine present?
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();
LogDbg("Signaling outside plug-ins to release their resources");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_TERMINATE_CMD, "");
@ -436,6 +471,10 @@ 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)
{
@ -767,6 +806,75 @@ 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)
{

View File

@ -526,6 +526,8 @@ 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.
@ -563,6 +565,14 @@ private:
bool m_Debugging; // Enable debugging features, if any.
bool m_Executed; // Whether the scripts were executed.
bool m_Shutdown; // Whether the server currently shutting down.
bool m_LockPreLoadSignal; // Lock pre load signal container.
bool m_LockPostLoadSignal; // Lock post load signal container.
bool m_LockUnloadSignal; // Lock unload signal container.
// --------------------------------------------------------------------------------------------
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.
@ -913,6 +923,21 @@ protected:
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.
*/

View File

@ -41,6 +41,42 @@ static SQInteger SqLoadScript(HSQUIRRELVM vm)
return 1;
}
// ------------------------------------------------------------------------------------------------
static void SqBindPreLoad(Object & env, Function & func)
{
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)
{
@ -284,6 +320,12 @@ 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)