From 42f9136141657cbe3fd0801c579e37dd1ff47a30 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sun, 12 Jul 2015 15:22:51 +0300 Subject: [PATCH] Remove DELE and NAME handling from RefIdCollection and RefIdData --- apps/opencs/model/world/refidcollection.cpp | 56 +----------- apps/opencs/model/world/refiddata.cpp | 12 +-- apps/opencs/model/world/refiddata.hpp | 96 +++++++++++++++++---- 3 files changed, 87 insertions(+), 77 deletions(-) diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5495926b4..0ca050e18 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -767,61 +767,7 @@ const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (int index) con void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type) { - std::string id = reader.getHNOString ("NAME"); - - int index = searchId (id); - - if (reader.isNextSub ("DELE")) - { - reader.skipRecord(); - - if (index==-1) - { - // deleting a record that does not exist - - // ignore it for now - - /// \todo report the problem to the user - } - else if (base) - { - mData.erase (index, 1); - } - else - { - mData.getRecord (mData.globalToLocalIndex (index)).mState = RecordBase::State_Deleted; - } - } - else - { - if (index==-1) - { - // new record - int index = mData.getAppendIndex (type); - mData.appendRecord (type, id, base); - - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); - - mData.load (localIndex, reader, base); - - mData.getRecord (localIndex).mState = - base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - } - else - { - // old record - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); - - if (!base) - if (mData.getRecord (localIndex).mState==RecordBase::State_Erased) - throw std::logic_error ("attempt to access a deleted record"); - - mData.load (localIndex, reader, base); - - if (!base) - mData.getRecord (localIndex).mState = RecordBase::State_Modified; - } - } + mData.load(reader, base, type); } int CSMWorld::RefIdCollection::getAppendIndex (const std::string& id, UniversalId::Type type) const diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 7f5c25f36..68f3fc4ad 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -161,15 +161,15 @@ int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const return index; } -void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base) +void CSMWorld::RefIdData::load (ESM::ESMReader& reader, bool base, CSMWorld::UniversalId::Type type) { - std::map::iterator iter = - mRecordContainers.find (index.second); + std::map::iterator found = + mRecordContainers.find (type); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (found == mRecordContainers.end()) + throw std::logic_error ("Invalid type for an Object (Reference ID)"); - iter->second->load (index.first, reader, base); + found->second->load(reader, base); } void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 85d16a6eb..17d913911 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -49,7 +49,7 @@ namespace CSMWorld virtual void insertRecord (RecordBase& record) = 0; - virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; + virtual void load (ESM::ESMReader& reader, bool base) = 0; virtual void erase (int index, int count) = 0; @@ -73,7 +73,7 @@ namespace CSMWorld virtual void insertRecord (RecordBase& record); - virtual void load (int index, ESM::ESMReader& reader, bool base); + virtual void load (ESM::ESMReader& reader, bool base); virtual void erase (int index, int count); @@ -122,9 +122,67 @@ namespace CSMWorld } template - void RefIdDataContainer::load (int index, ESM::ESMReader& reader, bool base) + void RefIdDataContainer::load (ESM::ESMReader& reader, bool base) { - (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); + RecordT record; + record.load(reader); + + typename std::vector >::iterator found = mContainer.begin(); + for (; found != mContainer.end(); ++found) + { + if (found->get().mId == record.mId) + { + break; + } + } + + if (record.mIsDeleted) + { + if (found == mContainer.end()) + { + // deleting a record that does not exist + // ignore it for now + /// \todo report the problem to the user + return; + } + + if (base) + { + mContainer.erase(found); + } + else + { + found->mState = RecordBase::State_Deleted; + } + } + else + { + if (found == mContainer.end()) + { + appendRecord(record.mId, base); + if (base) + { + mContainer.back().mBase = record; + } + else + { + mContainer.back().mModified = record; + } + } + else + { + if (!base) + { + if (found->mState == RecordBase::State_Erased) + { + throw std::logic_error("Attempt to access a deleted record"); + } + + found->mState = RecordBase::State_Modified; + found->mModified = record; + } + } + } } template @@ -145,20 +203,26 @@ namespace CSMWorld template void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const { - CSMWorld::RecordBase::State state = mContainer.at (index).mState; + Record record = mContainer.at(index); + RecordT esmRecord; - if (state==CSMWorld::RecordBase::State_Modified || - state==CSMWorld::RecordBase::State_ModifiedOnly) + switch (record.mState) { - writer.startRecord (mContainer.at (index).mModified.sRecordId); - writer.writeHNCString ("NAME", getId (index)); - mContainer.at (index).mModified.save (writer); - writer.endRecord (mContainer.at (index).mModified.sRecordId); - } - else if (state==CSMWorld::RecordBase::State_Deleted) - { - /// \todo write record with delete flag + case RecordBase::State_Modified: + case RecordBase::State_ModifiedOnly: + esmRecord = record.mModified; + break; + case RecordBase::State_Deleted: + esmRecord = record.mBase; + esmRecord.mIsDeleted = true; + break; + default: + break; } + + writer.startRecord(esmRecord.sRecordId); + esmRecord.save(writer); + writer.endRecord(esmRecord.sRecordId); } @@ -220,7 +284,7 @@ namespace CSMWorld int getAppendIndex (UniversalId::Type type) const; - void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); + void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); int getSize() const;