mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Fix the script loading process and further improve it with multi stage loading of scripts.
This commit is contained in:
parent
e99e6259f7
commit
a35b127871
187
source/Core.cpp
187
source/Core.cpp
@ -127,6 +127,7 @@ Core::Core()
|
|||||||
: m_State(0)
|
: m_State(0)
|
||||||
, m_VM(nullptr)
|
, m_VM(nullptr)
|
||||||
, m_Scripts()
|
, m_Scripts()
|
||||||
|
, m_PendingScripts()
|
||||||
, m_Options()
|
, m_Options()
|
||||||
, m_Blips()
|
, m_Blips()
|
||||||
, m_Checkpoints()
|
, m_Checkpoints()
|
||||||
@ -300,7 +301,7 @@ bool Core::Initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See if any script could be queued for loading
|
// See if any script could be queued for loading
|
||||||
if (m_Scripts.empty() && !conf.GetBoolValue("Squirrel", "EmptyInit", false))
|
if (m_PendingScripts.empty() && !conf.GetBoolValue("Squirrel", "EmptyInit", false))
|
||||||
{
|
{
|
||||||
LogErr("No scripts loaded. No reason to load the plug-in");
|
LogErr("No scripts loaded. No reason to load the plug-in");
|
||||||
// No point in loading the plug-in
|
// No point in loading the plug-in
|
||||||
@ -344,7 +345,7 @@ bool Core::Initialize()
|
|||||||
bool Core::Execute()
|
bool Core::Execute()
|
||||||
{
|
{
|
||||||
// Are there any scripts to execute?
|
// Are there any scripts to execute?
|
||||||
if (cLogErr(m_Scripts.empty(), "No scripts to execute. Plug-in has no purpose"))
|
if (cLogErr(m_PendingScripts.empty(), "No scripts to execute. Plug-in has no purpose"))
|
||||||
{
|
{
|
||||||
return false; // No reason to execute the plug-in
|
return false; // No reason to execute the plug-in
|
||||||
}
|
}
|
||||||
@ -353,74 +354,21 @@ bool Core::Execute()
|
|||||||
// Tell modules to do their monkey business
|
// Tell modules to do their monkey business
|
||||||
_Func->SendPluginCommand(SQMOD_LOAD_CMD, "");
|
_Func->SendPluginCommand(SQMOD_LOAD_CMD, "");
|
||||||
|
|
||||||
LogDbg("Attempting to compile the specified scripts");
|
// Load pending scripts while we're in the bounds of the allowed recursiveness
|
||||||
// Compile scripts first so that the constants can take effect
|
for (unsigned levels = 0; (m_PendingScripts.empty() == false) && (levels < 8); ++levels)
|
||||||
for (auto & s : m_Scripts)
|
|
||||||
{
|
{
|
||||||
// Is this script already compiled?
|
// Remember the last script from the pool
|
||||||
if (!s.mExec.IsNull())
|
const Scripts::size_type last = m_Scripts.size();
|
||||||
|
// Push pending scripts to the back of the list
|
||||||
|
std::move(m_PendingScripts.begin(), m_PendingScripts.end(), std::back_inserter(m_Scripts));
|
||||||
|
// Clear all pending scripts, if any
|
||||||
|
m_PendingScripts.clear();
|
||||||
|
// Process all pending scripts
|
||||||
|
if (DoScripts(m_Scripts.begin() + last, m_Scripts.end()) == false)
|
||||||
{
|
{
|
||||||
continue; // Already compiled!
|
return false; // One of the scripts failed to execute
|
||||||
}
|
}
|
||||||
|
LogDbg("Completed execution of stage (%u) scripts", levels);
|
||||||
// Attempt to load and compile the script file
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s.mExec.CompileFile(s.mPath);
|
|
||||||
}
|
|
||||||
catch (const Sqrat::Exception & e)
|
|
||||||
{
|
|
||||||
LogFtl("Unable to compile: %s", s.mPath.c_str());
|
|
||||||
// Failed to execute properly
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogDbg("Successfully compiled script: %s", s.mPath.c_str());
|
|
||||||
|
|
||||||
// Should we delay the execution of this script?
|
|
||||||
if (s.mDelay)
|
|
||||||
{
|
|
||||||
continue; // Execute later!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to execute the compiled script code
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s.mExec.Run();
|
|
||||||
}
|
|
||||||
catch (const Sqrat::Exception & e)
|
|
||||||
{
|
|
||||||
LogFtl("Unable to execute: %s", s.mPath.c_str());
|
|
||||||
// Failed to execute properly
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogScs("Successfully executed script: %s", s.mPath.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
LogDbg("Attempting to execute the specified scripts");
|
|
||||||
// Execute scripts only after compilation successful
|
|
||||||
for (auto & s : m_Scripts)
|
|
||||||
{
|
|
||||||
// Was this script delayed from execution?
|
|
||||||
if (!s.mDelay)
|
|
||||||
{
|
|
||||||
continue; // Already executed!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to execute the compiled script code
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s.mExec.Run();
|
|
||||||
}
|
|
||||||
catch (const Sqrat::Exception & e)
|
|
||||||
{
|
|
||||||
LogFtl("Unable to execute: %s", s.mPath.c_str());
|
|
||||||
// Failed to execute properly
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogScs("Successfully executed script: %s", s.mPath.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the null entity instances
|
// Create the null entity instances
|
||||||
@ -496,6 +444,7 @@ void Core::Terminate(bool shutdown)
|
|||||||
ResetFunc();
|
ResetFunc();
|
||||||
// Release the script instances
|
// Release the script instances
|
||||||
m_Scripts.clear();
|
m_Scripts.clear();
|
||||||
|
m_PendingScripts.clear(); // Just in case
|
||||||
// Specify that no scripts are left executed
|
// Specify that no scripts are left executed
|
||||||
m_Executed = false;
|
m_Executed = false;
|
||||||
// Assertions during close may cause double delete/close!
|
// Assertions during close may cause double delete/close!
|
||||||
@ -509,7 +458,7 @@ void Core::Terminate(bool shutdown)
|
|||||||
_Func->SendPluginCommand(SQMOD_RELEASED_CMD, "");
|
_Func->SendPluginCommand(SQMOD_RELEASED_CMD, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
LogDbg("Squirrel plugin was successfully terminated");
|
LogDbg("Squirrel plug---in was successfully terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -569,6 +518,7 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
// Failed to load
|
// Failed to load
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer bpath;
|
Buffer bpath;
|
||||||
// Attempt to get the real file path
|
// Attempt to get the real file path
|
||||||
try
|
try
|
||||||
@ -587,8 +537,10 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
// Failed to load
|
// Failed to load
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the path into a string
|
// Make the path into a string
|
||||||
String path(bpath.Data(), bpath.Position());
|
String path(bpath.Data(), bpath.Position());
|
||||||
|
|
||||||
// See if it wasn't already loaded
|
// See if it wasn't already loaded
|
||||||
if (std::find_if(m_Scripts.cbegin(), m_Scripts.cend(), [&path](Scripts::const_reference s) {
|
if (std::find_if(m_Scripts.cbegin(), m_Scripts.cend(), [&path](Scripts::const_reference s) {
|
||||||
return (s.mPath == path);
|
return (s.mPath == path);
|
||||||
@ -596,6 +548,13 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
{
|
{
|
||||||
LogWrn("Script was specified before: %s", path.c_str());
|
LogWrn("Script was specified before: %s", path.c_str());
|
||||||
}
|
}
|
||||||
|
// Also check the pending scripts container
|
||||||
|
else if (std::find_if(m_PendingScripts.cbegin(), m_PendingScripts.cend(), [&path](Scripts::const_reference s) {
|
||||||
|
return (s.mPath == path);
|
||||||
|
}) != m_PendingScripts.end())
|
||||||
|
{
|
||||||
|
LogWrn("Script was specified before: %s", path.c_str());
|
||||||
|
}
|
||||||
// Were the scripts already executed? Then there's no need to queue them
|
// Were the scripts already executed? Then there's no need to queue them
|
||||||
else if (m_Executed)
|
else if (m_Executed)
|
||||||
{
|
{
|
||||||
@ -610,7 +569,9 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
catch (const Sqrat::Exception & e)
|
catch (const Sqrat::Exception & e)
|
||||||
{
|
{
|
||||||
LogFtl("Unable to compile: %s", m_Scripts.back().mPath.c_str());
|
LogFtl("Unable to compile: %s", m_Scripts.back().mPath.c_str());
|
||||||
// Failed to execute properly
|
// Remove the script container since it's invalid
|
||||||
|
m_Scripts.pop_back();
|
||||||
|
// Failed to compile properly
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// At this point the script should be completely loaded
|
// At this point the script should be completely loaded
|
||||||
@ -624,6 +585,8 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
catch (const Sqrat::Exception & e)
|
catch (const Sqrat::Exception & e)
|
||||||
{
|
{
|
||||||
LogFtl("Unable to execute: %s", m_Scripts.back().mPath.c_str());
|
LogFtl("Unable to execute: %s", m_Scripts.back().mPath.c_str());
|
||||||
|
// Remove the script container since it's invalid
|
||||||
|
m_Scripts.pop_back();
|
||||||
// Failed to execute properly
|
// Failed to execute properly
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -633,10 +596,11 @@ bool Core::LoadScript(CSStr filepath, bool delay)
|
|||||||
// We don't compile the scripts yet. We just store their path and prepare the objects
|
// We don't compile the scripts yet. We just store their path and prepare the objects
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create a new script container and insert it into the script pool
|
// Create a new script container and insert it into the pending script pool
|
||||||
m_Scripts.emplace_back(m_VM, std::move(path), delay, m_Debugging);
|
m_PendingScripts.emplace_back(m_VM, std::move(path), delay, m_Debugging);
|
||||||
}
|
}
|
||||||
// At this point the script exists in the pool
|
|
||||||
|
// At this point the script exists in one of the pools
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,6 +635,85 @@ void Core::SetIncomingName(CSStr name)
|
|||||||
m_IncomingNameBuffer[len] = '\0';
|
m_IncomingNameBuffer[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
|
||||||
|
{
|
||||||
|
Scripts::iterator itr_state = itr;
|
||||||
|
|
||||||
|
LogDbg("Attempting to compile the specified scripts");
|
||||||
|
// Compile scripts first so that the constants can take effect
|
||||||
|
for (; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
// Is this script already compiled?
|
||||||
|
if (!(*itr).mExec.IsNull())
|
||||||
|
{
|
||||||
|
continue; // Already compiled!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to load and compile the script file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(*itr).mExec.CompileFile((*itr).mPath);
|
||||||
|
}
|
||||||
|
catch (const Sqrat::Exception & e)
|
||||||
|
{
|
||||||
|
LogFtl("Unable to compile: %s", (*itr).mPath.c_str());
|
||||||
|
// Failed to execute properly
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogDbg("Successfully compiled script: %s", (*itr).mPath.c_str());
|
||||||
|
|
||||||
|
// Should we delay the execution of this script?
|
||||||
|
if ((*itr).mDelay)
|
||||||
|
{
|
||||||
|
continue; // Execute later!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to execute the compiled script code
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(*itr).mExec.Run();
|
||||||
|
}
|
||||||
|
catch (const Sqrat::Exception & e)
|
||||||
|
{
|
||||||
|
LogFtl("Unable to execute: %s", (*itr).mPath.c_str());
|
||||||
|
// Failed to execute properly
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogScs("Successfully executed script: %s", (*itr).mPath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
LogDbg("Attempting to execute the specified scripts");
|
||||||
|
// Execute scripts only after compilation successful
|
||||||
|
for (itr = itr_state; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
// Was this script delayed from execution?
|
||||||
|
if (!(*itr).mDelay)
|
||||||
|
{
|
||||||
|
continue; // Already executed!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to execute the compiled script code
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(*itr).mExec.Run();
|
||||||
|
}
|
||||||
|
catch (const Sqrat::Exception & e)
|
||||||
|
{
|
||||||
|
LogFtl("Unable to execute: %s", (*itr).mPath.c_str());
|
||||||
|
// Failed to execute properly
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogScs("Successfully executed script: %s", (*itr).mPath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point the scripts were loaded and executed successfully
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Core::PrintFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...)
|
void Core::PrintFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...)
|
||||||
{
|
{
|
||||||
|
@ -536,6 +536,7 @@ private:
|
|||||||
Int32 m_State; // Current plug-in state.
|
Int32 m_State; // Current plug-in state.
|
||||||
HSQUIRRELVM m_VM; // Script virtual machine.
|
HSQUIRRELVM m_VM; // Script virtual machine.
|
||||||
Scripts m_Scripts; // Loaded scripts objects.
|
Scripts m_Scripts; // Loaded scripts objects.
|
||||||
|
Scripts m_PendingScripts; // Pending scripts objects.
|
||||||
Options m_Options; // Custom configuration options.
|
Options m_Options; // Custom configuration options.
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
@ -735,6 +736,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Script execution process.
|
||||||
|
*/
|
||||||
|
static bool DoScripts(Scripts::iterator itr, Scripts::iterator end);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Script output handlers.
|
* Script output handlers.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user