mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 20:53:53 +00:00
65cdd489fb
Fixed some types removed useless header applied clang format fixed compile tests fixed clang tidy, and closer to logic before this MR Removed hardcoded refids unless there is a returned value we don't use static RefIds can use == between RefId and hardcoded string Fix clang format Fixed a few instances where std::string was used, when only const std::string& was needed removed unused variable
144 lines
3.7 KiB
C++
144 lines
3.7 KiB
C++
#include "scriptcontext.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
#include <type_traits>
|
|
|
|
#include <apps/opencs/model/world/columns.hpp>
|
|
#include <apps/opencs/model/world/idcollection.hpp>
|
|
#include <apps/opencs/model/world/record.hpp>
|
|
#include <apps/opencs/model/world/refidcollection.hpp>
|
|
|
|
#include <components/compiler/nullerrorhandler.hpp>
|
|
#include <components/compiler/quickfileparser.hpp>
|
|
#include <components/compiler/scanner.hpp>
|
|
#include <components/esm3/loadglob.hpp>
|
|
#include <components/esm3/loadscpt.hpp>
|
|
#include <components/esm3/variant.hpp>
|
|
#include <components/misc/strings/lower.hpp>
|
|
|
|
#include "data.hpp"
|
|
|
|
CSMWorld::ScriptContext::ScriptContext(const Data& data)
|
|
: mData(data)
|
|
, mIdsUpdated(false)
|
|
{
|
|
}
|
|
|
|
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
char CSMWorld::ScriptContext::getGlobalType(const std::string& name) const
|
|
{
|
|
int index = mData.getGlobals().searchId(name);
|
|
|
|
if (index != -1)
|
|
{
|
|
switch (mData.getGlobals().getRecord(index).get().mValue.getType())
|
|
{
|
|
case ESM::VT_Short:
|
|
return 's';
|
|
case ESM::VT_Long:
|
|
return 'l';
|
|
case ESM::VT_Float:
|
|
return 'f';
|
|
|
|
default:
|
|
return ' ';
|
|
}
|
|
}
|
|
|
|
return ' ';
|
|
}
|
|
|
|
std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string& name, const ESM::RefId& id) const
|
|
{
|
|
ESM::RefId id2 = id;
|
|
|
|
int index = mData.getScripts().searchId(id2);
|
|
bool reference = false;
|
|
|
|
if (index == -1)
|
|
{
|
|
// ID is not a script ID. Search for a matching referenceable instead.
|
|
index = mData.getReferenceables().searchId(id2);
|
|
|
|
if (index != -1)
|
|
{
|
|
// Referenceable found.
|
|
int columnIndex = mData.getReferenceables().findColumnIndex(Columns::ColumnId_Script);
|
|
|
|
id2 = ESM::RefId::stringRefId(
|
|
mData.getReferenceables().getData(index, columnIndex).toString().toUtf8().constData());
|
|
|
|
if (!id2.empty())
|
|
{
|
|
// Referenceable has a script -> use it.
|
|
index = mData.getScripts().searchId(id2);
|
|
reference = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (index == -1)
|
|
return std::make_pair(' ', false);
|
|
|
|
std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(id2.getRefIdString());
|
|
|
|
if (iter == mLocals.end())
|
|
{
|
|
Compiler::Locals locals;
|
|
|
|
Compiler::NullErrorHandler errorHandler;
|
|
std::istringstream stream(mData.getScripts().getRecord(index).get().mScriptText);
|
|
Compiler::QuickFileParser parser(errorHandler, *this, locals);
|
|
Compiler::Scanner scanner(errorHandler, stream, getExtensions());
|
|
scanner.scan(parser);
|
|
|
|
iter = mLocals.insert(std::make_pair(id2.getRefIdString(), locals)).first;
|
|
}
|
|
|
|
return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference);
|
|
}
|
|
|
|
bool CSMWorld::ScriptContext::isId(const ESM::RefId& name) const
|
|
{
|
|
if (!mIdsUpdated)
|
|
{
|
|
mIds = mData.getIds();
|
|
|
|
std::sort(mIds.begin(), mIds.end());
|
|
|
|
mIdsUpdated = true;
|
|
}
|
|
|
|
return std::binary_search(mIds.begin(), mIds.end(), name);
|
|
}
|
|
|
|
void CSMWorld::ScriptContext::invalidateIds()
|
|
{
|
|
mIdsUpdated = false;
|
|
}
|
|
|
|
void CSMWorld::ScriptContext::clear()
|
|
{
|
|
mIds.clear();
|
|
mIdsUpdated = false;
|
|
mLocals.clear();
|
|
}
|
|
|
|
bool CSMWorld::ScriptContext::clearLocals(const std::string& script)
|
|
{
|
|
std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(Misc::StringUtils::lowerCase(script));
|
|
|
|
if (iter != mLocals.end())
|
|
{
|
|
mLocals.erase(iter);
|
|
mIdsUpdated = false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|