From 361634489ed7a1286919bef02b687fe3682cd619 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 15 Oct 2015 14:46:08 +0200 Subject: [PATCH] properly handle cells that don't exist --- apps/opencs/view/render/cell.cpp | 52 +++++++++++++------ apps/opencs/view/render/cell.hpp | 8 ++- .../view/render/pagedworldspacewidget.cpp | 47 +++++++++++------ 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 5ec69a5f26..da40f7e7cb 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -51,8 +51,9 @@ bool CSVRender::Cell::addObjects (int start, int end) return modified; } -CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id) -: mData (data), mId (Misc::StringUtils::lowerCase (id)) +CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, + bool deleted) +: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted) { std::pair result = CSMWorld::CellCoordinates::fromId (id); @@ -62,24 +63,27 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellNode = new osg::Group; rootNode->addChild(mCellNode); - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); - - int rows = references.rowCount(); - - addObjects (0, rows-1); - - const CSMWorld::IdCollection& land = mData.getLand(); - int landIndex = land.searchId(mId); - if (landIndex != -1) + if (!mDeleted) { - const ESM::Land& esmLand = land.getRecord(mId).get(); + CSMWorld::IdTable& references = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_References)); - if (esmLand.getLandData (ESM::Land::DATA_VHGT)) + int rows = references.rowCount(); + + addObjects (0, rows-1); + + const CSMWorld::IdCollection& land = mData.getLand(); + int landIndex = land.searchId(mId); + if (landIndex != -1) { - mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1)); - mTerrain->loadCell(esmLand.mX, - esmLand.mY); + const ESM::Land& esmLand = land.getRecord(mId).get(); + + if (esmLand.getLandData (ESM::Land::DATA_VHGT)) + { + mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1)); + mTerrain->loadCell(esmLand.mX, + esmLand.mY); + } } } } @@ -125,6 +129,9 @@ bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent, bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { + if (mDeleted) + return false; + CSMWorld::IdTable& references = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_References)); @@ -192,6 +199,9 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int if (parent.isValid()) return false; + if (mDeleted) + return false; + CSMWorld::IdTable& references = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_References)); @@ -212,6 +222,9 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int if (parent.isValid()) return false; + if (mDeleted) + return false; + return addObjects (start, end); } @@ -258,3 +271,8 @@ CSMWorld::CellCoordinates CSVRender::Cell::getCoordinates() const { return mCoordinates; } + +bool CSVRender::Cell::isDeleted() const +{ + return mDeleted; +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 7cced4fe37..59f4cafee4 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -40,6 +40,7 @@ namespace CSVRender std::auto_ptr mTerrain; CSMWorld::CellCoordinates mCoordinates; std::auto_ptr mCellArrows[4]; + bool mDeleted; /// Ignored if cell does not have an object with the given ID. /// @@ -62,7 +63,10 @@ namespace CSVRender public: - Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id); + /// \note Deleted covers both cells that are deleted and cells that don't exist in + /// the first place. + Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, + bool deleted = false); ~Cell(); @@ -93,6 +97,8 @@ namespace CSVRender /// Returns 0, 0 in case of an unpaged cell. CSMWorld::CellCoordinates getCoordinates() const; + + bool isDeleted() const; }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 070ce7d17d..dd740ab9ae 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -1,5 +1,6 @@ #include "pagedworldspacewidget.hpp" +#include #include #include @@ -26,17 +27,14 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); { - // remove (or name/region modified) + // remove/update std::map::iterator iter (mCells.begin()); while (iter!=mCells.end()) { - int index = cells.searchId (iter->first.getId (mWorldspace)); - - /// \todo handle cells that don't exist - if (!mSelection.has (iter->first) || index==-1 || - cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted) + if (!mSelection.has (iter->first)) { + // remove delete iter->second; mCells.erase (iter++); @@ -44,12 +42,33 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } else { - // check if name or region field has changed - // FIXME: config setting - //std::string name = cells.getRecord(index).get().mName; - //std::string region = cells.getRecord(index).get().mRegion; + // update + int index = cells.searchId (iter->first.getId (mWorldspace)); - // cell marker update goes here + bool deleted = index==-1 || + cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted; + + if (deleted!=iter->second->isDeleted()) + { + modified = true; + + std::auto_ptr cell (new Cell (mDocument.getData(), mRootNode, + iter->first.getId (mWorldspace), deleted)); + + delete iter->second; + iter->second = cell.release(); + } + else if (!deleted) + { + // delete state has not changed -> just update + + // TODO check if name or region field has changed (cell marker) + // FIXME: config setting + //std::string name = cells.getRecord(index).get().mName; + //std::string region = cells.getRecord(index).get().mRegion; + + modified = true; + } ++iter; } @@ -60,11 +79,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); ++iter) { - int index = cells.searchId (iter->getId (mWorldspace)); - - /// \todo handle cells that don't exist - if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && - mCells.find (*iter)==mCells.end()) + if (mCells.find (*iter)==mCells.end()) { Cell *cell = new Cell (mDocument.getData(), mRootNode, iter->getId (mWorldspace));