From 0a8ffbfb1d67080b1e22b0f7756794fa6134b94c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 14 Feb 2014 12:46:54 +0100 Subject: [PATCH] added missing implementation for CSMWorld::ScriptContext::getMemberType --- apps/opencs/model/world/scriptcontext.cpp | 56 ++++++++++++++++++++++- apps/opencs/model/world/scriptcontext.hpp | 3 ++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/scriptcontext.cpp b/apps/opencs/model/world/scriptcontext.cpp index 2627c49f3e..ee95f06c86 100644 --- a/apps/opencs/model/world/scriptcontext.cpp +++ b/apps/opencs/model/world/scriptcontext.cpp @@ -5,6 +5,10 @@ #include +#include +#include +#include + #include "data.hpp" CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {} @@ -36,7 +40,57 @@ char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const std::pair CSMWorld::ScriptContext::getMemberType (const std::string& name, const std::string& id) const { - return std::make_pair (' ', false); + /// \todo invalidate locals cache on change to scripts + + std::string id2 = Misc::StringUtils::lowerCase (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().searchColumnIndex (Columns::ColumnId_Script); + + if (columnIndex!=-1) + { + id2 = Misc::StringUtils::lowerCase (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::iterator iter = mLocals.find (id2); + + 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, locals)).first; + } + + return std::make_pair (iter->second.getType (Misc::StringUtils::lowerCase (name)), reference); } bool CSMWorld::ScriptContext::isId (const std::string& name) const diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index 3baca99b24..400748e5fa 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -3,8 +3,10 @@ #include #include +#include #include +#include namespace CSMWorld { @@ -15,6 +17,7 @@ namespace CSMWorld const Data& mData; mutable std::vector mIds; mutable bool mIdsUpdated; + mutable std::map mLocals; public: