1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 10:53:54 +00:00
openmw/apps/opencs/model/world/scriptcontext.cpp

145 lines
3.6 KiB
C++
Raw Normal View History

#include "scriptcontext.hpp"
2013-09-19 10:30:42 +00:00
#include <algorithm>
#include <sstream>
2022-10-19 17:02:00 +00:00
#include <type_traits>
2013-09-19 10:30:42 +00:00
2022-10-19 17:02:00 +00:00
#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>
2013-09-19 10:30:42 +00:00
#include <components/compiler/nullerrorhandler.hpp>
2022-09-22 18:26:05 +00:00
#include <components/compiler/quickfileparser.hpp>
#include <components/compiler/scanner.hpp>
2022-10-19 17:02:00 +00:00
#include <components/esm3/loadglob.hpp>
#include <components/esm3/loadscpt.hpp>
#include <components/esm3/variant.hpp>
#include <components/misc/strings/lower.hpp>
2013-09-19 10:30:42 +00:00
#include "data.hpp"
2022-09-22 18:26:05 +00:00
CSMWorld::ScriptContext::ScriptContext(const Data& data)
: mData(data)
, mIdsUpdated(false)
{
}
2013-09-19 10:30:42 +00:00
bool CSMWorld::ScriptContext::canDeclareLocals() const
{
2014-02-14 12:38:30 +00:00
return true;
}
2022-09-22 18:26:05 +00:00
char CSMWorld::ScriptContext::getGlobalType(const std::string& name) const
{
const int index = mData.getGlobals().searchId(ESM::RefId::stringRefId(name));
2022-09-22 18:26:05 +00:00
if (index != -1)
{
2022-09-22 18:26:05 +00:00
switch (mData.getGlobals().getRecord(index).get().mValue.getType())
{
2022-09-22 18:26:05 +00:00
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;
2022-09-22 18:26:05 +00:00
int index = mData.getScripts().searchId(id2);
bool reference = false;
2022-09-22 18:26:05 +00:00
if (index == -1)
{
// ID is not a script ID. Search for a matching referenceable instead.
2022-09-22 18:26:05 +00:00
index = mData.getReferenceables().searchId(id2);
2022-09-22 18:26:05 +00:00
if (index != -1)
{
// Referenceable found.
2022-09-22 18:26:05 +00:00
int columnIndex = mData.getReferenceables().findColumnIndex(Columns::ColumnId_Script);
id2 = ESM::RefId::stringRefId(
2022-09-22 18:26:05 +00:00
mData.getReferenceables().getData(index, columnIndex).toString().toUtf8().constData());
2014-10-13 13:26:47 +00:00
if (!id2.empty())
{
2014-10-13 13:26:47 +00:00
// Referenceable has a script -> use it.
2022-09-22 18:26:05 +00:00
index = mData.getScripts().searchId(id2);
2014-10-13 13:26:47 +00:00
reference = true;
}
}
}
2022-09-22 18:26:05 +00:00
if (index == -1)
return std::make_pair(' ', false);
auto iter = mLocals.find(id2);
2022-09-22 18:26:05 +00:00
if (iter == mLocals.end())
{
Compiler::Locals locals;
Compiler::NullErrorHandler errorHandler;
2022-09-22 18:26:05 +00:00
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.emplace(id2, std::move(locals)).first;
}
2022-09-22 18:26:05 +00:00
return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference);
}
bool CSMWorld::ScriptContext::isId(const ESM::RefId& name) const
{
2013-09-19 10:30:42 +00:00
if (!mIdsUpdated)
{
mIds = mData.getIds();
2022-09-22 18:26:05 +00:00
std::sort(mIds.begin(), mIds.end());
2013-09-19 10:30:42 +00:00
mIdsUpdated = true;
}
return std::binary_search(mIds.begin(), mIds.end(), name);
2013-09-19 10:30:42 +00:00
}
void CSMWorld::ScriptContext::invalidateIds()
{
mIdsUpdated = false;
2014-02-14 12:38:30 +00:00
}
void CSMWorld::ScriptContext::clear()
{
mIds.clear();
mIdsUpdated = false;
mLocals.clear();
2015-03-11 14:54:45 +00:00
}
2022-09-22 18:26:05 +00:00
bool CSMWorld::ScriptContext::clearLocals(const std::string& script)
{
const auto iter = mLocals.find(script);
2022-09-22 18:26:05 +00:00
if (iter != mLocals.end())
{
2022-09-22 18:26:05 +00:00
mLocals.erase(iter);
mIdsUpdated = false;
return true;
}
return false;
}