properly handle cells that don't exist

This commit is contained in:
Marc Zinnschlag 2015-10-15 14:46:08 +02:00
parent 773df6fd22
commit 361634489e
3 changed files with 73 additions and 34 deletions

View file

@ -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<CSMWorld::CellCoordinates, bool> 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<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
int rows = references.rowCount();
addObjects (0, rows-1);
const CSMWorld::IdCollection<CSMWorld::Land>& 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<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
if (esmLand.getLandData (ESM::Land::DATA_VHGT))
int rows = references.rowCount();
addObjects (0, rows-1);
const CSMWorld::IdCollection<CSMWorld::Land>& 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<CSMWorld::IdTable&> (
*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<CSMWorld::IdTable&> (
*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;
}

View file

@ -40,6 +40,7 @@ namespace CSVRender
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
CSMWorld::CellCoordinates mCoordinates;
std::auto_ptr<CellArrow> 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;
};
}

View file

@ -1,5 +1,6 @@
#include "pagedworldspacewidget.hpp"
#include <memory>
#include <sstream>
#include <QMouseEvent>
@ -26,17 +27,14 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
{
// remove (or name/region modified)
// remove/update
std::map<CSMWorld::CellCoordinates, Cell *>::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> 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));