Resume failed scripts execution after game reload (feature #5524)

pull/2969/head
Andrei Kortunov 4 years ago
parent f12123a172
commit b05d071e69

@ -47,6 +47,7 @@
Feature #5445: Handle NiLines
Feature #5457: Realistic diagonal movement
Feature #5486: Fixes trainers to choose their training skills based on their base skill points
Feature #5524: Resume failed script execution after reload
Task #5480: Drop Qt4 support
0.46.0

@ -35,6 +35,8 @@ namespace MWBase
virtual ~ScriptManager() {}
virtual void clear() = 0;
virtual bool run (const std::string& name, Interpreter::Context& interpreterContext) = 0;
///< Run the script with the given name (compile first, if not compiled yet)

@ -79,8 +79,8 @@ namespace MWScript
if (Success)
{
std::vector<Interpreter::Type_Code> code;
mParser.getCode (code);
mScripts.insert (std::make_pair (name, std::make_pair (code, mParser.getLocals())));
mParser.getCode(code);
mScripts.emplace(name, CompiledScript(code, mParser.getLocals()));
return true;
}
@ -100,7 +100,7 @@ namespace MWScript
{
// failed -> ignore script from now on.
std::vector<Interpreter::Type_Code> empty;
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
mScripts.emplace(name, CompiledScript(empty, Compiler::Locals()));
return false;
}
@ -109,7 +109,7 @@ namespace MWScript
}
// execute script
if (!iter->second.first.empty())
if (!iter->second.mByteCode.empty() && iter->second.mActive)
try
{
if (!mOpcodesInstalled)
@ -118,7 +118,7 @@ namespace MWScript
mOpcodesInstalled = true;
}
mInterpreter.run (&iter->second.first[0], iter->second.first.size(), interpreterContext);
mInterpreter.run (&iter->second.mByteCode[0], iter->second.mByteCode.size(), interpreterContext);
return true;
}
catch (const MissingImplicitRefError& e)
@ -129,11 +129,21 @@ namespace MWScript
{
Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what();
iter->second.first.clear(); // don't execute again.
iter->second.mActive = false; // don't execute again.
}
return false;
}
void ScriptManager::clear()
{
for (auto& script : mScripts)
{
script.second.mActive = true;
}
mGlobalScripts.clear();
}
std::pair<int, int> ScriptManager::compileAll()
{
int count = 0;
@ -163,7 +173,7 @@ namespace MWScript
ScriptCollection::iterator iter = mScripts.find (name2);
if (iter!=mScripts.end())
return iter->second.second;
return iter->second.mLocals;
}
{

@ -41,7 +41,20 @@ namespace MWScript
Interpreter::Interpreter mInterpreter;
bool mOpcodesInstalled;
typedef std::pair<std::vector<Interpreter::Type_Code>, Compiler::Locals> CompiledScript;
struct CompiledScript
{
std::vector<Interpreter::Type_Code> mByteCode;
Compiler::Locals mLocals;
bool mActive;
CompiledScript(const std::vector<Interpreter::Type_Code>& code, const Compiler::Locals& locals)
{
mByteCode = code;
mLocals = locals;
mActive = true;
}
};
typedef std::map<std::string, CompiledScript> ScriptCollection;
ScriptCollection mScripts;
@ -55,6 +68,8 @@ namespace MWScript
Compiler::Context& compilerContext, int warningsMode,
const std::vector<std::string>& scriptBlacklist);
virtual void clear();
virtual bool run (const std::string& name, Interpreter::Context& interpreterContext);
///< Run the script with the given name (compile first, if not compiled yet)

@ -47,7 +47,7 @@ void MWState::StateManager::cleanup (bool force)
MWBase::Environment::get().getSoundManager()->clear();
MWBase::Environment::get().getDialogueManager()->clear();
MWBase::Environment::get().getJournal()->clear();
MWBase::Environment::get().getScriptManager()->getGlobalScripts().clear();
MWBase::Environment::get().getScriptManager()->clear();
MWBase::Environment::get().getWorld()->clear();
MWBase::Environment::get().getWindowManager()->clear();
MWBase::Environment::get().getInputManager()->clear();

Loading…
Cancel
Save