mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +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.
|
||||
*/
|
||||
class ScriptLoader
|
||||
struct ScriptLoader
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
CSimpleIniA & m_Config; // The processed configuration.
|
||||
|
||||
public:
|
||||
Function m_Callback{}; // Null callback.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
explicit ScriptLoader(CSimpleIniA & conf)
|
||||
: m_Config(conf)
|
||||
: m_Config(conf), m_Callback()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -90,7 +89,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Function call operator.
|
||||
*/
|
||||
bool operator () (const char * key, const char * val) const
|
||||
bool operator () (const char * key, const char * val)
|
||||
{
|
||||
// Validate the specified key
|
||||
if (!key || *key == '\0')
|
||||
@ -104,11 +103,11 @@ public:
|
||||
}
|
||||
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)
|
||||
{
|
||||
return Core::Get().LoadScript(val, false);
|
||||
return Core::Get().LoadScript(val, m_Callback, false);
|
||||
}
|
||||
// Move to the next element!
|
||||
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?
|
||||
if (!filepath || *filepath == '\0')
|
||||
@ -761,7 +760,7 @@ bool Core::LoadScript(const SQChar * filepath, bool delay)
|
||||
else if (m_Executed)
|
||||
{
|
||||
// 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
|
||||
try
|
||||
@ -782,7 +781,14 @@ bool Core::LoadScript(const SQChar * filepath, bool delay)
|
||||
// Attempt to execute the compiled script code
|
||||
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)
|
||||
{
|
||||
@ -803,7 +809,7 @@ bool Core::LoadScript(const SQChar * filepath, bool delay)
|
||||
try
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
@ -900,7 +906,14 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
|
||||
// Attempt to execute the compiled script code
|
||||
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)
|
||||
{
|
||||
@ -925,11 +938,18 @@ bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
|
||||
// Attempt to execute the compiled script code
|
||||
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)
|
||||
{
|
||||
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
|
||||
return false;
|
||||
}
|
||||
@ -2477,12 +2497,19 @@ static SQInteger SqLoadScript(HSQUIRRELVM vm)
|
||||
{
|
||||
return sq_throwerror(vm, "Failed to retrieve the delay parameter");
|
||||
}
|
||||
Function cb;
|
||||
// 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
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool SqLoadScriptNotify(bool delay, StackStrF & path, Function & cb)
|
||||
{
|
||||
return Core::Get().LoadScript(path.mPtr, cb, delay);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqGetEvents(HSQUIRRELVM vm)
|
||||
{
|
||||
@ -2813,6 +2840,7 @@ void Register_Core(HSQUIRRELVM vm)
|
||||
.Func(_SC("OnPreLoad"), &SqGetPreLoadEvent)
|
||||
.Func(_SC("OnPostLoad"), &SqGetPostLoadEvent)
|
||||
.Func(_SC("OnUnload"), &SqGetUnloadEvent)
|
||||
.CbFunc(_SC("LoadScriptNotify"), &SqLoadScriptNotify)
|
||||
.SquirrelFunc(_SC("ForceEnableNullEntities"), &SqForceEnableNullEntities)
|
||||
.SquirrelFunc(_SC("LoadScript"), &SqLoadScript, -3, ".b.")
|
||||
.SquirrelFunc(_SC("On"), &SqGetEvents);
|
||||
|
@ -368,7 +368,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
|
@ -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()
|
||||
, mFunc(std::move(cb))
|
||||
, mPath(path)
|
||||
, mData()
|
||||
, mLine()
|
||||
|
@ -19,20 +19,19 @@ class Core;
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Script mExec; // Reference to the script object.
|
||||
String mPath; // Path to the script file.
|
||||
String mData; // The contents of the script file.
|
||||
Line mLine; // List of lines of code in the data.
|
||||
bool mInfo; // Whether this script contains line information.
|
||||
bool mDelay; // Don't execute immediately after compilation.
|
||||
Script mExec{}; // Reference to the script object.
|
||||
Function mFunc{}; // Callback to invoke after script was executed.
|
||||
String mPath{}; // Path to the script file.
|
||||
String mData{}; // The contents of the script file.
|
||||
Line mLine{}; // List of lines of code in the data.
|
||||
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.
|
||||
@ -42,7 +41,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
|
@ -42,6 +42,8 @@ namespace Sqrat {
|
||||
class Script : public Object {
|
||||
public:
|
||||
|
||||
using Object::Object;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user