Load methods (for ESM records) accept a deleted flag in OpenCS

This commit is contained in:
Stanislav Bas 2015-07-21 20:25:43 +03:00
parent 67c8f95c4e
commit 13bb6be238
19 changed files with 56 additions and 161 deletions

View file

@ -107,10 +107,8 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
{
// if the topic is deleted, we do not need to bother with INFO records.
ESM::Dialogue dialogue = topic.get();
dialogue.mIsDeleted = true;
writer.startRecord(dialogue.sRecordId);
dialogue.save(writer);
dialogue.save(writer, true);
writer.endRecord(dialogue.sRecordId);
return;
}
@ -121,7 +119,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
{
if (topic.isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
{
infoModified = true;
break;
@ -131,7 +129,6 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
if (topic.isModified() || infoModified)
{
ESM::Dialogue dialogue = topic.get();
writer.startRecord (dialogue.sRecordId);
dialogue.save (writer);
writer.endRecord (dialogue.sRecordId);
@ -143,7 +140,6 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
{
ESM::DialInfo info = iter->get();
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
info.mIsDeleted = (iter->mState == CSMWorld::RecordBase::State_Deleted);
info.mPrev = "";
if (iter!=range.first)
@ -164,7 +160,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
}
writer.startRecord (info.sRecordId);
info.save (writer);
info.save (writer, iter->mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (info.sRecordId);
}
}
@ -213,9 +209,7 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
const CSMWorld::Record<CSMWorld::CellRef>& record =
mDocument.getData().getReferences().getRecord (i);
if (record.mState==CSMWorld::RecordBase::State_Deleted ||
record.mState==CSMWorld::RecordBase::State_Modified ||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
if (record.isModified() || record.mState == CSMWorld::RecordBase::State_Deleted)
{
std::string cellId = record.get().mOriginalCell.empty() ?
record.get().mCell : record.get().mOriginalCell;
@ -284,8 +278,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY;
}
cellRecord.mIsDeleted = (cell.mState == CSMWorld::RecordBase::State_Deleted);
cellRecord.save (writer);
cellRecord.save (writer, cell.mState == CSMWorld::RecordBase::State_Deleted);
// write references
if (references!=mState.getSubRecords().end())
@ -326,8 +319,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
writer.writeHNT ("CNDT", moved.mTarget, 8);
}
refRecord.mIsDeleted = (ref.mState == CSMWorld::RecordBase::State_Deleted);
refRecord.save (writer);
refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);
}
}
}
@ -366,9 +358,8 @@ void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& message
else
record.mCell = record.mId;
record.mIsDeleted = (pathgrid.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId);
record.save (writer);
record.save (writer, pathgrid.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId);
}
}
@ -393,10 +384,8 @@ void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted)
{
CSMWorld::Land record = land.get();
record.mLand->mIsDeleted = (land.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.mLand->sRecordId);
record.mLand->save (writer);
record.mLand->save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.mLand->sRecordId);
}
}
@ -421,10 +410,8 @@ void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& mess
if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted)
{
CSMWorld::LandTexture record = landTexture.get();
record.mIsDeleted = (landTexture.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId);
record.save (writer);
record.save (writer, landTexture.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId);
}
}

View file

@ -108,9 +108,8 @@ namespace CSMDoc
state == CSMWorld::RecordBase::State_ModifiedOnly ||
state == CSMWorld::RecordBase::State_Deleted)
{
CSMWorld::setRecordDeleted (record, state == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId);
record.save (writer);
record.save (writer, state == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId);
}
}

View file

@ -3,12 +3,12 @@
#include <sstream>
void CSMWorld::Cell::load (ESM::ESMReader &esm)
void CSMWorld::Cell::load (ESM::ESMReader &esm, bool &isDeleted)
{
ESM::Cell::load (esm, false);
ESM::Cell::load (esm, isDeleted, false);
mId = mName;
if (!(mData.mFlags & Interior))
if (isExterior())
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;

View file

@ -16,7 +16,7 @@ namespace CSMWorld
{
std::string mId;
void load (ESM::ESMReader &esm);
void load (ESM::ESMReader &esm, bool &isDeleted);
};
}

View file

@ -989,9 +989,11 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
case ESM::REC_DIAL:
{
ESM::Dialogue record;
record.load (*mReader);
bool isDeleted = false;
if (record.mIsDeleted)
record.load (*mReader, isDeleted);
if (isDeleted)
{
// record vector can be shuffled around which would make pointer to record invalid
mDialogue = 0;

View file

@ -1,3 +0,0 @@
#include "idcollection.hpp"

View file

@ -12,7 +12,7 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
{
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader);
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
public:
@ -34,21 +34,24 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
ESM::ESMReader& reader)
ESM::ESMReader& reader,
bool& isDeleted)
{
record.load (reader);
record.load (reader, isDeleted);
}
template<typename ESXRecordT, typename IdAccessorT>
int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
{
ESXRecordT record;
loadRecord (record, reader);
bool isDeleted = false;
loadRecord (record, reader, isDeleted);
std::string id = IdAccessorT().getId (record);
int index = this->searchId (id);
if (isRecordDeleted(record))
if (isDeleted)
{
if (index==-1)
{

View file

@ -108,10 +108,12 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector<int
void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue)
{
Info info;
info.load (reader);
bool isDeleted = false;
info.load (reader, isDeleted);
std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" + info.mId;
if (info.mIsDeleted)
if (isDeleted)
{
int index = searchId (id);

View file

@ -10,13 +10,12 @@ namespace CSMWorld
mLand.reset(new ESM::Land());
}
void Land::load(ESM::ESMReader &esm)
void Land::load(ESM::ESMReader &esm, bool &isDeleted)
{
mLand->load(esm);
mLand->load(esm, isDeleted);
std::ostringstream stream;
stream << "#" << mLand->mX << " " << mLand->mY;
mId = stream.str();
}

View file

@ -20,7 +20,7 @@ namespace CSMWorld
std::string mId;
/// Loads the metadata and ID
void load (ESM::ESMReader &esm);
void load (ESM::ESMReader &esm, bool &isDeleted);
void blank();
};

View file

@ -4,17 +4,13 @@
namespace CSMWorld
{
void LandTexture::load(ESM::ESMReader &esm)
void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted)
{
ESM::LandTexture::load(esm);
ESM::LandTexture::load(esm, isDeleted);
int plugin = esm.getIndex();
std::ostringstream stream;
stream << mIndex << "_" << plugin;
mId = stream.str();
}

View file

@ -15,7 +15,7 @@ namespace CSMWorld
{
std::string mId;
void load (ESM::ESMReader &esm);
void load (ESM::ESMReader &esm, bool &isDeleted);
};
}

View file

@ -4,33 +4,28 @@
#include <sstream>
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, const IdCollection<Cell>& cells)
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells)
{
load (esm);
load (esm, isDeleted);
// correct ID
if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1)
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str();
}
}
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm)
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted)
{
ESM::Pathgrid::load (esm);
ESM::Pathgrid::load (esm, isDeleted);
mId = mCell;
if (mCell.empty())
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str();
}
else
mId = mCell;
}

View file

@ -20,9 +20,8 @@ namespace CSMWorld
{
std::string mId;
void load (ESM::ESMReader &esm, const IdCollection<Cell>& cells);
void load (ESM::ESMReader &esm);
void load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells);
void load (ESM::ESMReader &esm, bool &isDeleted);
};
}

View file

@ -19,51 +19,3 @@ bool CSMWorld::RecordBase::isModified() const
{
return mState==State_Modified || mState==State_ModifiedOnly;
}
template<>
bool CSMWorld::isRecordDeleted(const CSMWorld::Land &land)
{
return land.mLand->mIsDeleted;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::GameSetting &setting)
{
return false;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::MagicEffect &effect)
{
return false;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::Skill &skill)
{
return false;
}
template<>
void CSMWorld::setRecordDeleted(CSMWorld::Land &land, bool isDeleted)
{
land.mLand->mIsDeleted = isDeleted;
}
template<>
void CSMWorld::setRecordDeleted(ESM::GameSetting &setting, bool isDeleted)
{
// GameSetting doesn't have a Deleted flag
}
template<>
void CSMWorld::setRecordDeleted(ESM::MagicEffect &effect, bool isDeleted)
{
// MagicEffect doesn't have a Deleted flag
}
template<>
void CSMWorld::setRecordDeleted(ESM::Skill &skill, bool isDeleted)
{
// Skill doesn't have a Deleted flag
}

View file

@ -3,12 +3,6 @@
#include <stdexcept>
#include <components/esm/loadgmst.hpp>
#include <components/esm/loadmgef.hpp>
#include <components/esm/loadskil.hpp>
#include "land.hpp"
namespace CSMWorld
{
struct RecordBase
@ -160,39 +154,6 @@ namespace CSMWorld
mState = State_Erased;
}
}
// Not all records can be deleted (may be changed in the future),
// so we need to use a separate method to check whether a record is deleted or not.
template<typename ESXRecordT>
bool isRecordDeleted(const ESXRecordT &record)
{
return record.mIsDeleted;
}
template<>
bool isRecordDeleted(const Land &land);
template<>
bool isRecordDeleted(const ESM::GameSetting &setting);
template<>
bool isRecordDeleted(const ESM::MagicEffect &effect);
template<>
bool isRecordDeleted(const ESM::Skill &skill);
// ... and also a separate method for setting the deleted flag of a record
template<typename ESXRecordT>
void setRecordDeleted(ESXRecordT &record, bool isDeleted = false)
{
record.mIsDeleted = isDeleted;
}
template<>
void setRecordDeleted(Land &land, bool isDeleted);
template<>
void setRecordDeleted(ESM::GameSetting &setting, bool isDeleted);
template<>
void setRecordDeleted(ESM::MagicEffect &effect, bool isDeleted);
template<>
void setRecordDeleted(ESM::Skill &skill, bool isDeleted);
}
#endif

View file

@ -21,9 +21,10 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CellRef ref;
ESM::MovedCellRef mref;
bool isDeleted = false;
// hack to initialise mindex
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, true, &mref))
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, isDeleted, true, &mref))
{
// Keep mOriginalCell empty when in modified (as an indicator that the
// original cell will always be equal the current cell).
@ -79,7 +80,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
break;
}
if (ref.mIsDeleted)
if (isDeleted)
{
if (iter==cache.end())
{

View file

@ -129,7 +129,9 @@ namespace CSMWorld
int RefIdDataContainer<RecordT>::load (ESM::ESMReader& reader, bool base)
{
RecordT record;
record.load(reader);
bool isDeleted = false;
record.load(reader, isDeleted);
int index = 0;
int numRecords = static_cast<int>(mContainer.size());
@ -141,7 +143,7 @@ namespace CSMWorld
}
}
if (record.mIsDeleted)
if (isDeleted)
{
if (index == numRecords)
{
@ -197,13 +199,12 @@ namespace CSMWorld
void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
{
Record<RecordT> record = mContainer.at(index);
RecordT esmRecord = record.get();
if (record.isModified() || record.mState == RecordBase::State_Deleted)
{
esmRecord.mIsDeleted = (record.mState == RecordBase::State_Deleted);
RecordT esmRecord = record.get();
writer.startRecord(esmRecord.sRecordId);
esmRecord.save(writer);
esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
writer.endRecord(esmRecord.sRecordId);
}
}

View file

@ -20,7 +20,7 @@ namespace CSMWorld
{
const IdCollection<Cell>& mCells;
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader);
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
public:
@ -29,9 +29,10 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
void SubCellCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
ESM::ESMReader& reader)
ESM::ESMReader& reader,
bool& isDeleted)
{
record.load (reader, mCells);
record.load (reader, isDeleted, mCells);
}
template<typename ESXRecordT, typename IdAccessorT>