mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Implement script loading with notification.
This commit is contained in:
parent
a710ceebff
commit
f2c1f8afd7
@ -71,18 +71,17 @@ extern Buffer GetRealFilePath(const SQChar * path);
|
|||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Loader used to process a section from the configuration file and look for scripts to load.
|
* Loader used to process a section from the configuration file and look for scripts to load.
|
||||||
*/
|
*/
|
||||||
class ScriptLoader
|
struct ScriptLoader
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
CSimpleIniA & m_Config; // The processed configuration.
|
CSimpleIniA & m_Config; // The processed configuration.
|
||||||
|
Function m_Callback{}; // Null callback.
|
||||||
public:
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
explicit ScriptLoader(CSimpleIniA & conf)
|
explicit ScriptLoader(CSimpleIniA & conf)
|
||||||
: m_Config(conf)
|
: m_Config(conf), m_Callback()
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -90,7 +89,7 @@ public:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Function call operator.
|
* Function call operator.
|
||||||
*/
|
*/
|
||||||
bool operator () (const char * key, const char * val) const
|
bool operator () (const char * key, const char * val)
|
||||||
{
|
{
|
||||||
// Validate the specified key
|
// Validate the specified key
|
||||||
if (!key || *key == '\0')
|
if (!key || *key == '\0')
|
||||||
@ -104,11 +103,11 @@ public:
|
|||||||
}
|
}
|
||||||
else if (std::strcmp(key, "Compile") == 0)
|
else if (std::strcmp(key, "Compile") == 0)
|
||||||
{
|
{
|
||||||
return Core::Get().LoadScript(val, true);
|
return Core::Get().LoadScript(val, m_Callback, true);
|
||||||
}
|
}
|
||||||
else if (std::strcmp(key, "Execute") == 0)
|
else if (std::strcmp(key, "Execute") == 0)
|
||||||
{
|
{
|
||||||
return Core::Get().LoadScript(val, false);
|
return Core::Get().LoadScript(val, m_Callback, false);
|
||||||
}
|
}
|
||||||
// Move to the next element!
|
// Move to the next element!
|
||||||
return true;
|
return true;
|
||||||
@ -717,7 +716,7 @@ Core::Scripts::iterator Core::FindPendingScript(const SQChar * src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool Core::LoadScript(const SQChar * filepath, bool delay)
|
bool Core::LoadScript(const SQChar * filepath, Function & cb, bool delay)
|
||||||
{
|
{
|
||||||
// Is the specified path empty?
|
// Is the specified path empty?
|
||||||
if (!filepath || *filepath == '\0')
|
if (!filepath || *filepath == '\0')
|
||||||
@ -761,7 +760,7 @@ bool Core::LoadScript(const SQChar * filepath, 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, delay, m_Debugging);
|
m_Scripts.emplace_back(path, cb, delay, m_Debugging);
|
||||||
|
|
||||||
// Attempt to load and compile the script file
|
// Attempt to load and compile the script file
|
||||||
try
|
try
|
||||||
@ -782,7 +781,14 @@ bool Core::LoadScript(const SQChar * filepath, bool delay)
|
|||||||
// Attempt to execute the compiled script code
|
// Attempt to execute the compiled script code
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_Scripts.back().mExec.Run();
|
auto & s = m_Scripts.back();
|
||||||
|
// Attempt to run the script
|
||||||
|
s.mExec.Run();
|
||||||
|
// Does someone need to be notified?
|
||||||
|
if (!s.mFunc.IsNull())
|
||||||
|
{
|
||||||
|
s.mFunc.Execute(s.mPath, s.mExec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception & e)
|
catch (const std::exception & e)
|
||||||
{
|
{
|
||||||
@ -803,7 +809,7 @@ bool Core::LoadScript(const SQChar * filepath, 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, delay, m_Debugging);
|
m_PendingScripts.emplace_back(path, cb, delay, m_Debugging);
|
||||||
}
|
}
|
||||||
catch (const std::exception & e)
|
catch (const std::exception & e)
|
||||||
{
|
{
|
||||||
@ -900,7 +906,14 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
|
|||||||
// Attempt to execute the compiled script code
|
// Attempt to execute the compiled script code
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
(*itr).mExec.Run();
|
auto & s = *itr;
|
||||||
|
// Attempt to run the script
|
||||||
|
s.mExec.Run();
|
||||||
|
// Does someone need to be notified?
|
||||||
|
if (!s.mFunc.IsNull())
|
||||||
|
{
|
||||||
|
s.mFunc.Execute(s.mPath, s.mExec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception & e)
|
catch (const std::exception & e)
|
||||||
{
|
{
|
||||||
@ -925,11 +938,18 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
|
|||||||
// Attempt to execute the compiled script code
|
// Attempt to execute the compiled script code
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
(*itr).mExec.Run();
|
auto & s = *itr;
|
||||||
|
// Attempt to run the script
|
||||||
|
s.mExec.Run();
|
||||||
|
// Does someone need to be notified?
|
||||||
|
if (!s.mFunc.IsNull())
|
||||||
|
{
|
||||||
|
s.mFunc.Execute(s.mPath, s.mExec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception & e)
|
catch (const std::exception & e)
|
||||||
{
|
{
|
||||||
LogFtl("Unable to execute: %s", (*itr).mPath.c_str());
|
LogFtl("Unable to execute (%s) exception caught: %s", (*itr).mPath.c_str(), e.what());
|
||||||
// Failed to execute properly
|
// Failed to execute properly
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2477,12 +2497,19 @@ 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;
|
||||||
// Forward the call to the actual implementation
|
// Forward the call to the actual implementation
|
||||||
sq_pushbool(vm, Core::Get().LoadScript(val.mPtr, static_cast< bool >(delay)));
|
sq_pushbool(vm, Core::Get().LoadScript(val.mPtr, cb, 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)
|
||||||
|
{
|
||||||
|
return Core::Get().LoadScript(path.mPtr, cb, delay);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static SQInteger SqGetEvents(HSQUIRRELVM vm)
|
static SQInteger SqGetEvents(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
@ -2813,6 +2840,7 @@ void Register_Core(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("OnPreLoad"), &SqGetPreLoadEvent)
|
.Func(_SC("OnPreLoad"), &SqGetPreLoadEvent)
|
||||||
.Func(_SC("OnPostLoad"), &SqGetPostLoadEvent)
|
.Func(_SC("OnPostLoad"), &SqGetPostLoadEvent)
|
||||||
.Func(_SC("OnUnload"), &SqGetUnloadEvent)
|
.Func(_SC("OnUnload"), &SqGetUnloadEvent)
|
||||||
|
.CbFunc(_SC("LoadScriptNotify"), &SqLoadScriptNotify)
|
||||||
.SquirrelFunc(_SC("ForceEnableNullEntities"), &SqForceEnableNullEntities)
|
.SquirrelFunc(_SC("ForceEnableNullEntities"), &SqForceEnableNullEntities)
|
||||||
.SquirrelFunc(_SC("LoadScript"), &SqLoadScript, -3, ".b.")
|
.SquirrelFunc(_SC("LoadScript"), &SqLoadScript, -3, ".b.")
|
||||||
.SquirrelFunc(_SC("On"), &SqGetEvents);
|
.SquirrelFunc(_SC("On"), &SqGetEvents);
|
||||||
|
@ -368,7 +368,7 @@ public:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Adds a script to the load queue.
|
* Adds a script to the load queue.
|
||||||
*/
|
*/
|
||||||
bool LoadScript(const SQChar * filepath, bool delay);
|
bool LoadScript(const SQChar * filepath, Function & cb, bool delay = false);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Modify the name for the currently assigned incoming connection.
|
* Modify the name for the currently assigned incoming connection.
|
||||||
|
@ -148,8 +148,9 @@ void ScriptSrc::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ScriptSrc::ScriptSrc(const String & path, bool delay, bool info) // NOLINT(modernize-pass-by-value)
|
ScriptSrc::ScriptSrc(const String & path, Function & cb, bool delay, bool info) // NOLINT(modernize-pass-by-value)
|
||||||
: mExec()
|
: mExec()
|
||||||
|
, mFunc(std::move(cb))
|
||||||
, mPath(path)
|
, mPath(path)
|
||||||
, mData()
|
, mData()
|
||||||
, mLine()
|
, mLine()
|
||||||
|
@ -19,20 +19,19 @@ class Core;
|
|||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Hold a information about loaded scripts as it's contents and executable code.
|
* Hold a information about loaded scripts as it's contents and executable code.
|
||||||
*/
|
*/
|
||||||
class ScriptSrc
|
struct ScriptSrc
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
typedef std::vector< std::pair< uint32_t, uint32_t > > Line;
|
typedef std::vector< std::pair< uint32_t, uint32_t > > Line;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Script mExec; // Reference to the script object.
|
Script mExec{}; // Reference to the script object.
|
||||||
String mPath; // Path to the script file.
|
Function mFunc{}; // Callback to invoke after script was executed.
|
||||||
String mData; // The contents of the script file.
|
String mPath{}; // Path to the script file.
|
||||||
Line mLine; // List of lines of code in the data.
|
String mData{}; // The contents of the script file.
|
||||||
bool mInfo; // Whether this script contains line information.
|
Line mLine{}; // List of lines of code in the data.
|
||||||
bool mDelay; // Don't execute immediately after compilation.
|
bool mInfo{false}; // Whether this script contains line information.
|
||||||
|
bool mDelay{false}; // Don't execute immediately after compilation.
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Read file contents and calculate information about the lines of code.
|
* Read file contents and calculate information about the lines of code.
|
||||||
@ -42,7 +41,7 @@ public:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Base constructor.
|
* Base constructor.
|
||||||
*/
|
*/
|
||||||
explicit ScriptSrc(const String & path, bool delay = false, bool info = false);
|
explicit ScriptSrc(const String & path, Function & cb, bool delay = false, bool info = false);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Copy constructor.
|
* Copy constructor.
|
||||||
|
@ -42,6 +42,8 @@ namespace Sqrat {
|
|||||||
class Script : public Object {
|
class Script : public Object {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using Object::Object;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
///
|
///
|
||||||
@ -245,4 +247,49 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push Script instances to and from the stack as references (Script is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<Script> {
|
||||||
|
|
||||||
|
Script value; ///< The actual value of get operations
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Attempts to get the value off the stack at idx as an Script
|
||||||
|
///
|
||||||
|
/// \param vm Target VM
|
||||||
|
/// \param idx Index trying to be read
|
||||||
|
///
|
||||||
|
/// \remarks
|
||||||
|
/// This function MUST have its Error handled if it occurred.
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Var(HSQUIRRELVM vm, SQInteger idx) : value(idx, vm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Called by Sqrat::PushVar to put an Script on the stack
|
||||||
|
///
|
||||||
|
/// \param vm Target VM
|
||||||
|
/// \param value Value to push on to the VM's stack
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void push(HSQUIRRELVM vm, const Script& value) {
|
||||||
|
sq_pushobject(vm, value.GetObj());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push Script instances to and from the stack as references (Script is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<Script&> : Var<Script> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Script>(vm, idx) {}};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push Script instances to and from the stack as references (Script is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<const Script&> : Var<Script> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Script>(vm, idx) {}};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -328,6 +328,23 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Sets a key in the Table to a specific function with callback support
|
||||||
|
///
|
||||||
|
/// \param name The key in the table being assigned a value
|
||||||
|
/// \param method Function that is being placed in the Table
|
||||||
|
///
|
||||||
|
/// \tparam F Type of function (only define this if you need to choose a certain template specialization or overload)
|
||||||
|
///
|
||||||
|
/// \return The Table itself so the call can be chained
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class F>
|
||||||
|
TableBase& CbFunc(const SQChar* name, F method) {
|
||||||
|
BindFunc(name, &method, sizeof(method), SqGlobalFunc(method));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Sets a key in the Table to a specific function and allows the key to be overloaded with functions of a different amount of arguments
|
/// Sets a key in the Table to a specific function and allows the key to be overloaded with functions of a different amount of arguments
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user