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

pull/579/head
Andrei Kortunov 5 years ago
parent f12123a172
commit b05d071e69

@ -47,6 +47,7 @@
Feature #5445: Handle NiLines Feature #5445: Handle NiLines
Feature #5457: Realistic diagonal movement Feature #5457: Realistic diagonal movement
Feature #5486: Fixes trainers to choose their training skills based on their base skill points 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 Task #5480: Drop Qt4 support
0.46.0 0.46.0

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

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

@ -41,7 +41,20 @@ namespace MWScript
Interpreter::Interpreter mInterpreter; Interpreter::Interpreter mInterpreter;
bool mOpcodesInstalled; 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; typedef std::map<std::string, CompiledScript> ScriptCollection;
ScriptCollection mScripts; ScriptCollection mScripts;
@ -55,6 +68,8 @@ namespace MWScript
Compiler::Context& compilerContext, int warningsMode, Compiler::Context& compilerContext, int warningsMode,
const std::vector<std::string>& scriptBlacklist); const std::vector<std::string>& scriptBlacklist);
virtual void clear();
virtual bool run (const std::string& name, Interpreter::Context& interpreterContext); virtual bool run (const std::string& name, Interpreter::Context& interpreterContext);
///< Run the script with the given name (compile first, if not compiled yet) ///< 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().getSoundManager()->clear();
MWBase::Environment::get().getDialogueManager()->clear(); MWBase::Environment::get().getDialogueManager()->clear();
MWBase::Environment::get().getJournal()->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().getWorld()->clear();
MWBase::Environment::get().getWindowManager()->clear(); MWBase::Environment::get().getWindowManager()->clear();
MWBase::Environment::get().getInputManager()->clear(); MWBase::Environment::get().getInputManager()->clear();

Loading…
Cancel
Save