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

Extend notification script loading with support for context.

This replaces the second argument from callback. Initial implementation was missing this feature.
This commit is contained in:
Sandu Liviu Catalin 2021-07-04 02:19:37 +03:00
parent 494aed47bf
commit 3c30b9c7a2
4 changed files with 43 additions and 15 deletions

View File

@ -76,12 +76,13 @@ struct ScriptLoader
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
CSimpleIniA & m_Config; // The processed configuration. CSimpleIniA & m_Config; // The processed configuration.
Function m_Callback{}; // Null callback. Function m_Callback{}; // Null callback.
LightObj m_Context{}; // Callback context.
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Default constructor. * Default constructor.
*/ */
explicit ScriptLoader(CSimpleIniA & conf) explicit ScriptLoader(CSimpleIniA & conf)
: m_Config(conf), m_Callback() : m_Config(conf), m_Callback(), m_Context()
{ {
/* ... */ /* ... */
} }
@ -103,11 +104,11 @@ struct ScriptLoader
} }
else if (std::strcmp(key, "Compile") == 0) else if (std::strcmp(key, "Compile") == 0)
{ {
return Core::Get().LoadScript(val, m_Callback, true); return Core::Get().LoadScript(val, m_Callback, m_Context, true);
} }
else if (std::strcmp(key, "Execute") == 0) else if (std::strcmp(key, "Execute") == 0)
{ {
return Core::Get().LoadScript(val, m_Callback, false); return Core::Get().LoadScript(val, m_Callback, m_Context, false);
} }
// Move to the next element! // Move to the next element!
return true; return true;
@ -716,7 +717,7 @@ Core::Scripts::iterator Core::FindPendingScript(const SQChar * src)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Core::LoadScript(const SQChar * filepath, Function & cb, bool delay) bool Core::LoadScript(const SQChar * filepath, Function & cb, LightObj & ctx, bool delay)
{ {
// Is the specified path empty? // Is the specified path empty?
if (!filepath || *filepath == '\0') if (!filepath || *filepath == '\0')
@ -760,7 +761,7 @@ bool Core::LoadScript(const SQChar * filepath, Function & cb, bool delay)
else if (m_Executed) else if (m_Executed)
{ {
// Create a new script container and insert it into the script pool // Create a new script container and insert it into the script pool
m_Scripts.emplace_back(path, cb, delay, m_Debugging); m_Scripts.emplace_back(path, cb, ctx, delay, m_Debugging);
// Attempt to load and compile the script file // Attempt to load and compile the script file
try try
@ -787,12 +788,20 @@ bool Core::LoadScript(const SQChar * filepath, Function & cb, bool delay)
// Does someone need to be notified? // Does someone need to be notified?
if (!s.mFunc.IsNull()) if (!s.mFunc.IsNull())
{ {
s.mFunc.Execute(s.mPath, s.mExec); // Invoke the associated script
s.mFunc.Execute(s.mPath, s.mCtx);
// Release callback since we know it exists
s.mFunc.Release();
} }
// Release context, if any
s.mCtx.Release();
} }
catch (const std::exception & e) catch (const std::exception & e)
{ {
LogFtl("Unable to execute (%s) exception caught: %s", path.c_str(), e.what()); LogFtl("Unable to execute (%s) exception caught: %s", path.c_str(), e.what());
// Release callback and context objects, if any
m_Scripts.back().mFunc.Release();
m_Scripts.back().mCtx.Release();
// Remove the script container since it's invalid // Remove the script container since it's invalid
m_Scripts.pop_back(); m_Scripts.pop_back();
// Failed to execute properly // Failed to execute properly
@ -809,7 +818,7 @@ bool Core::LoadScript(const SQChar * filepath, Function & cb, bool delay)
try try
{ {
// Create a new script container and insert it into the pending script pool // Create a new script container and insert it into the pending script pool
m_PendingScripts.emplace_back(path, cb, delay, m_Debugging); m_PendingScripts.emplace_back(path, cb, ctx, delay, m_Debugging);
} }
catch (const std::exception & e) catch (const std::exception & e)
{ {
@ -912,12 +921,20 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
// Does someone need to be notified? // Does someone need to be notified?
if (!s.mFunc.IsNull()) if (!s.mFunc.IsNull())
{ {
s.mFunc.Execute(s.mPath, s.mExec); // Invoke the associated script
s.mFunc.Execute(s.mPath, s.mCtx);
// Release callback since we know it exists
s.mFunc.Release();
} }
// Release context, if any
s.mCtx.Release();
} }
catch (const std::exception & e) catch (const std::exception & e)
{ {
LogFtl("Unable to execute (%s) exception caught: %s", (*itr).mPath.c_str(), e.what()); LogFtl("Unable to execute (%s) exception caught: %s", (*itr).mPath.c_str(), e.what());
// Release callback and context objects, if any
itr->mFunc.Release();
itr->mCtx.Release();
// Failed to execute properly // Failed to execute properly
return false; return false;
} }
@ -944,12 +961,20 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
// Does someone need to be notified? // Does someone need to be notified?
if (!s.mFunc.IsNull()) if (!s.mFunc.IsNull())
{ {
s.mFunc.Execute(s.mPath, s.mExec); // Invoke the associated script
s.mFunc.Execute(s.mPath, s.mCtx);
// Release callback since we know it exists
s.mFunc.Release();
} }
// Release context, if any
s.mCtx.Release();
} }
catch (const std::exception & e) catch (const std::exception & e)
{ {
LogFtl("Unable to execute (%s) exception caught: %s", (*itr).mPath.c_str(), e.what()); LogFtl("Unable to execute (%s) exception caught: %s", (*itr).mPath.c_str(), e.what());
// Release callback and context objects, if any
itr->mFunc.Release();
itr->mCtx.Release();
// Failed to execute properly // Failed to execute properly
return false; return false;
} }
@ -2498,16 +2523,17 @@ static SQInteger SqLoadScript(HSQUIRRELVM vm)
return sq_throwerror(vm, "Failed to retrieve the delay parameter"); return sq_throwerror(vm, "Failed to retrieve the delay parameter");
} }
Function cb; Function cb;
LightObj ctx;
// Forward the call to the actual implementation // Forward the call to the actual implementation
sq_pushbool(vm, Core::Get().LoadScript(val.mPtr, cb, static_cast< bool >(delay))); sq_pushbool(vm, Core::Get().LoadScript(val.mPtr, cb, ctx, static_cast< bool >(delay)));
// We have an argument on the stack // We have an argument on the stack
return 1; return 1;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static bool SqLoadScriptNotify(bool delay, StackStrF & path, Function & cb) static bool SqLoadScriptNotify(bool delay, StackStrF & path, LightObj & ctx, Function & cb)
{ {
return Core::Get().LoadScript(path.mPtr, cb, delay); return Core::Get().LoadScript(path.mPtr, cb, ctx, delay);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -368,7 +368,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Adds a script to the load queue. * Adds a script to the load queue.
*/ */
bool LoadScript(const SQChar * filepath, Function & cb, bool delay = false); bool LoadScript(const SQChar * filepath, Function & cb, LightObj & ctx, bool delay = false);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the name for the currently assigned incoming connection. * Modify the name for the currently assigned incoming connection.

View File

@ -148,9 +148,10 @@ void ScriptSrc::Process()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ScriptSrc::ScriptSrc(const String & path, Function & cb, bool delay, bool info) // NOLINT(modernize-pass-by-value) ScriptSrc::ScriptSrc(const String & path, Function & cb, LightObj & ctx, bool delay, bool info) // NOLINT(modernize-pass-by-value)
: mExec() : mExec()
, mFunc(std::move(cb)) , mFunc(std::move(cb))
, mCtx(std::move(ctx))
, mPath(path) , mPath(path)
, mData() , mData()
, mLine() , mLine()

View File

@ -27,6 +27,7 @@ struct ScriptSrc
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
Script mExec{}; // Reference to the script object. Script mExec{}; // Reference to the script object.
Function mFunc{}; // Callback to invoke after script was executed. Function mFunc{}; // Callback to invoke after script was executed.
LightObj mCtx{}; // Object to be passed over to the callback as context.
String mPath{}; // Path to the script file. String mPath{}; // Path to the script file.
String mData{}; // The contents of the script file. String mData{}; // The contents of the script file.
Line mLine{}; // List of lines of code in the data. Line mLine{}; // List of lines of code in the data.
@ -41,7 +42,7 @@ struct ScriptSrc
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Base constructor. * Base constructor.
*/ */
explicit ScriptSrc(const String & path, Function & cb, bool delay = false, bool info = false); explicit ScriptSrc(const String & path, Function & cb, LightObj & ctx, bool delay = false, bool info = false);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. * Copy constructor.