From 7bef97bf3331dbdf9544c2caad17ecf68b3be96b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 22 Sep 2015 15:36:00 +0200 Subject: [PATCH] fixed local variable caching issue in automatic error checking (Fixes #2927) --- apps/opencs/model/world/scriptcontext.cpp | 17 +++++++++++-- apps/opencs/model/world/scriptcontext.hpp | 3 +++ apps/opencs/view/world/scripterrortable.cpp | 5 ++++ apps/opencs/view/world/scripterrortable.hpp | 5 ++++ apps/opencs/view/world/scriptsubview.cpp | 27 ++++++++++++++++++++- apps/opencs/view/world/scriptsubview.hpp | 1 + 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/scriptcontext.cpp b/apps/opencs/model/world/scriptcontext.cpp index bcbca4b28..f644ad37a 100644 --- a/apps/opencs/model/world/scriptcontext.cpp +++ b/apps/opencs/model/world/scriptcontext.cpp @@ -39,8 +39,6 @@ char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const std::pair CSMWorld::ScriptContext::getMemberType (const std::string& name, const std::string& id) const { - /// \todo invalidate locals cache on change to scripts - std::string id2 = Misc::StringUtils::lowerCase (id); int index = mData.getScripts().searchId (id2); @@ -120,3 +118,18 @@ void CSMWorld::ScriptContext::clear() mIdsUpdated = false; mLocals.clear(); } + +bool CSMWorld::ScriptContext::clearLocals (const std::string& script) +{ + std::map::iterator iter = + mLocals.find (Misc::StringUtils::lowerCase (script)); + + if (iter!=mLocals.end()) + { + mLocals.erase (iter); + mIdsUpdated = false; + return true; + } + + return false; +} diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index 29ee42645..2cd59f070 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -46,6 +46,9 @@ namespace CSMWorld void clear(); ///< Remove all cached data. + + /// \return Were there any locals that needed clearing? + bool clearLocals (const std::string& script); }; } diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index b44e1c0bd..a9e315c73 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -131,6 +131,11 @@ void CSVWorld::ScriptErrorTable::clear() setRowCount (0); } +bool CSVWorld::ScriptErrorTable::clearLocals (const std::string& script) +{ + return mContext.clearLocals (script); +} + void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) { if (item (row, 1)) diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 98db425cf..33af7c864 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -44,6 +44,11 @@ namespace CSVWorld void clear(); + /// Clear local variable cache for \a script. + /// + /// \return Were there any locals that needed clearing? + bool clearLocals (const std::string& script); + private slots: void cellClicked (int row, int column); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index d405d1765..d99f789b3 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -89,6 +89,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); mColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_ScriptText); + mIdColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); mStateColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); QString source = mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString(); @@ -241,6 +242,15 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo ScriptEdit::ChangeLock lock (*mEditor); + bool updateRequired = false; + + for (int i=topLeft.row(); i<=bottomRight.row(); ++i) + { + std::string id = mModel->data (mModel->index (i, mIdColumn)).toString().toUtf8().constData(); + if (mErrors->clearLocals (id)) + updateRequired = true; + } + QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) @@ -256,13 +266,28 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo mEditor->setPlainText (source); mEditor->setTextCursor (cursor); - recompile(); + updateRequired = true; } } + + if (updateRequired) + recompile(); } void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end) { + bool updateRequired = false; + + for (int i=start; i<=end; ++i) + { + std::string id = mModel->data (mModel->index (i, mIdColumn)).toString().toUtf8().constData(); + if (mErrors->clearLocals (id)) + updateRequired = true; + } + + if (updateRequired) + recompile(); + QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); if (!parent.isValid() && index.row()>=start && index.row()<=end) diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 6125dd259..907dc7958 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -38,6 +38,7 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; + int mIdColumn; int mStateColumn; TableBottomBox *mBottom; RecordButtonBar *mButtons;