Use heterogenous maps for scripts

This commit is contained in:
Evil Eye 2022-08-12 20:56:50 +02:00
parent 51938f9ef7
commit 2deec591cd
6 changed files with 26 additions and 31 deletions

View file

@ -1,7 +1,7 @@
#ifndef GAME_MWBASE_SCRIPTMANAGER_H
#define GAME_MWBASE_SCRIPTMANAGER_H
#include <string>
#include <string_view>
namespace Interpreter
{
@ -38,10 +38,10 @@ namespace MWBase
virtual void clear() = 0;
virtual bool run (const std::string& name, Interpreter::Context& interpreterContext) = 0;
virtual bool run(std::string_view name, Interpreter::Context& interpreterContext) = 0;
///< Run the script with the given name (compile first, if not compiled yet)
virtual bool compile (const std::string& name) = 0;
virtual bool compile(std::string_view name) = 0;
///< Compile script with the given namen
/// \return Success?

View file

@ -261,7 +261,7 @@ namespace MWGui
if (!script.empty() && MWBase::Environment::get().getWorld()->getScriptsEnabled())
{
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
MWBase::Environment::get().getScriptManager()->run(std::string{script}, interpreterContext);
MWBase::Environment::get().getScriptManager()->run(script, interpreterContext);
}
// Clean up summoned creatures as well

View file

@ -309,17 +309,16 @@ namespace MWScript
Locals& GlobalScripts::getLocals(std::string_view name)
{
std::string name2 = ::Misc::StringUtils::lowerCase (name);
auto iter = mScripts.find (name2);
auto iter = mScripts.find(name);
if (iter==mScripts.end())
{
const ESM::Script *script = mStore.get<ESM::Script>().find(name2);
const ESM::Script *script = mStore.get<ESM::Script>().find(name);
auto desc = std::make_shared<GlobalScriptDesc>();
desc->mLocals.configure (*script);
iter = mScripts.insert (std::make_pair (name2, desc)).first;
iter = mScripts.emplace(name, desc).first;
}
return iter->second->mLocals;
@ -327,8 +326,7 @@ namespace MWScript
const Locals* GlobalScripts::getLocalsIfPresent(std::string_view name) const
{
std::string name2 = ::Misc::StringUtils::lowerCase (name);
auto iter = mScripts.find (name2);
auto iter = mScripts.find(name);
if (iter==mScripts.end())
return nullptr;
return &iter->second->mLocals;

View file

@ -3,13 +3,14 @@
#include <string>
#include <string_view>
#include <map>
#include <unordered_map>
#include <memory>
#include <utility>
#include <variant>
#include <cstdint>
#include <components/misc/algorithm.hpp>
#include "locals.hpp"
#include "../mwworld/ptr.hpp"
@ -51,7 +52,7 @@ namespace MWScript
class GlobalScripts
{
const MWWorld::ESMStore& mStore;
std::map<std::string, std::shared_ptr<GlobalScriptDesc> > mScripts;
std::unordered_map<std::string, std::shared_ptr<GlobalScriptDesc>, ::Misc::StringUtils::CiHash, ::Misc::StringUtils::CiEqual> mScripts;
public:

View file

@ -39,14 +39,14 @@ namespace MWScript
std::sort (mScriptBlacklist.begin(), mScriptBlacklist.end());
}
bool ScriptManager::compile (const std::string& name)
bool ScriptManager::compile(std::string_view name)
{
mParser.reset();
mErrorHandler.reset();
if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
{
mErrorHandler.setContext(name);
mErrorHandler.setContext(script->mId);
bool Success = true;
try
@ -89,10 +89,10 @@ namespace MWScript
return false;
}
bool ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext)
bool ScriptManager::run(std::string_view name, Interpreter::Context& interpreterContext)
{
// compile script
ScriptCollection::iterator iter = mScripts.find (name);
auto iter = mScripts.find(name);
if (iter==mScripts.end())
{
@ -167,27 +167,25 @@ namespace MWScript
const Compiler::Locals& ScriptManager::getLocals(std::string_view name)
{
std::string name2 = Misc::StringUtils::lowerCase (name);
{
auto iter = mScripts.find (name2);
auto iter = mScripts.find(name);
if (iter!=mScripts.end())
return iter->second.mLocals;
}
{
auto iter = mOtherLocals.find (name2);
auto iter = mOtherLocals.find(name);
if (iter!=mOtherLocals.end())
return iter->second;
}
if (const ESM::Script *script = mStore.get<ESM::Script>().search (name2))
if (const ESM::Script* script = mStore.get<ESM::Script>().search(name))
{
Compiler::Locals locals;
const Compiler::ContextOverride override(mErrorHandler, name2 + "[local variables]");
const Compiler::ContextOverride override(mErrorHandler, std::string{name} + "[local variables]");
std::istringstream stream (script->mScriptText);
Compiler::QuickFileParser parser (mErrorHandler, mCompilerContext, locals);
@ -207,12 +205,12 @@ namespace MWScript
locals.clear();
}
auto iter = mOtherLocals.emplace(name2, locals).first;
auto iter = mOtherLocals.emplace(name, locals).first;
return iter->second;
}
throw std::logic_error("script " + name2 + " does not exist");
throw std::logic_error("script " + std::string{name} + " does not exist");
}
GlobalScripts& ScriptManager::getGlobalScripts()

View file

@ -53,11 +53,9 @@ namespace MWScript
{}
};
typedef std::map<std::string, CompiledScript> ScriptCollection;
ScriptCollection mScripts;
std::unordered_map<std::string, CompiledScript, ::Misc::StringUtils::CiHash, ::Misc::StringUtils::CiEqual> mScripts;
GlobalScripts mGlobalScripts;
std::map<std::string, Compiler::Locals> mOtherLocals;
std::unordered_map<std::string, Compiler::Locals, ::Misc::StringUtils::CiHash, ::Misc::StringUtils::CiEqual> mOtherLocals;
std::vector<std::string> mScriptBlacklist;
public:
@ -68,10 +66,10 @@ namespace MWScript
void clear() override;
bool run (const std::string& name, Interpreter::Context& interpreterContext) override;
bool run(std::string_view name, Interpreter::Context& interpreterContext) override;
///< Run the script with the given name (compile first, if not compiled yet)
bool compile (const std::string& name) override;
bool compile(std::string_view name) override;
///< Compile script with the given namen
/// \return Success?