diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 99d32d06b..50324f3e8 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -96,22 +96,21 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) throw std::runtime_error(error.str()); } } else { - it->second->load(esm); - std::string id = it->second->getLastAddedRecordId(); - if (it->second->isLastAddedRecordDeleted()) + RecordId id = it->second->load(esm); + if (id.mIsDeleted) { - it->second->eraseStatic(id); + it->second->eraseStatic(id.mId); continue; } if (n.val==ESM::REC_DIAL) { - dialogue = const_cast(mDialogs.find(id)); + dialogue = const_cast(mDialogs.find(id.mId)); } else { dialogue = 0; } // Insert the reference into the global lookup - if (!id.empty() && isCacheableRecord(n.val)) { - mIds[Misc::StringUtils::lowerCase (id)] = n.val; + if (!id.mId.empty() && isCacheableRecord(n.val)) { + mIds[Misc::StringUtils::lowerCase (id.mId)] = n.val; } } listener->setProgress(static_cast(esm.getFileOffset() / (float)esm.getFileSize() * 1000)); @@ -184,13 +183,12 @@ void ESMStore::setUp() case ESM::REC_LEVC: { - StoreBase *store = mStores[type]; - store->read (reader); + RecordId id = mStores[type]->read (reader); // FIXME: there might be stale dynamic IDs in mIds from an earlier savegame // that really should be cleared instead of just overwritten - mIds[store->getLastAddedRecordId()] = type; + mIds[id.mId] = type; } if (type==ESM::REC_NPC_) diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index aeb96dcab..c8c42d17d 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -44,6 +44,10 @@ namespace namespace MWWorld { + RecordId::RecordId(const std::string &id, bool isDeleted) + : mId(id), mIsDeleted(isDeleted) + {} + template IndexedStore::IndexedStore() { @@ -180,7 +184,7 @@ namespace MWWorld return ptr; } template - void Store::load(ESM::ESMReader &esm) + RecordId Store::load(ESM::ESMReader &esm) { T record; record.load(esm); @@ -190,7 +194,7 @@ namespace MWWorld if (inserted.second) mShared.push_back(&inserted.first->second); - mLastAddedRecord = record; + return RecordId(record.mId, ESM::isRecordDeleted(record)); } template void Store::setUp() @@ -317,25 +321,13 @@ namespace MWWorld } } template - void Store::read(ESM::ESMReader& reader) + RecordId Store::read(ESM::ESMReader& reader) { T record; record.load (reader); insert (record); - mLastAddedRecord = record; - } - - - template - std::string Store::getLastAddedRecordId() const - { - return ESM::getRecordId(mLastAddedRecord); - } - template - bool Store::isLastAddedRecordDeleted() const - { - return ESM::isRecordDeleted(mLastAddedRecord); + return RecordId(record.mId, ESM::isRecordDeleted(record)); } // LandTexture @@ -375,7 +367,7 @@ namespace MWWorld assert(plugin < mStatic.size()); return mStatic[plugin].size(); } - void Store::load(ESM::ESMReader &esm, size_t plugin) + RecordId Store::load(ESM::ESMReader &esm, size_t plugin) { ESM::LandTexture lt; lt.load(esm); @@ -389,11 +381,13 @@ namespace MWWorld ltexl.resize(lt.mIndex+1); // Store it - ltexl[lt.mIndex] = mLastAddedRecord = lt; + ltexl[lt.mIndex] = lt; + + return RecordId(lt.mId, lt.mIsDeleted); } - void Store::load(ESM::ESMReader &esm) + RecordId Store::load(ESM::ESMReader &esm) { - load(esm, esm.getIndex()); + return load(esm, esm.getIndex()); } Store::iterator Store::begin(size_t plugin) const { @@ -405,16 +399,6 @@ namespace MWWorld assert(plugin < mStatic.size()); return mStatic[plugin].end(); } - - std::string Store::getLastAddedRecordId() const - { - return ESM::getRecordId(mLastAddedRecord); - } - - bool Store::isLastAddedRecordDeleted() const - { - return ESM::isRecordDeleted(mLastAddedRecord); - } // Land //========================================================================= @@ -462,7 +446,7 @@ namespace MWWorld } return ptr; } - void Store::load(ESM::ESMReader &esm) + RecordId Store::load(ESM::ESMReader &esm) { ESM::Land *ptr = new ESM::Land(); ptr->load(esm); @@ -480,6 +464,8 @@ namespace MWWorld } mStatic.push_back(ptr); + + return RecordId(); // No ID and can't be deleted (for now) } void Store::setUp() { @@ -622,7 +608,7 @@ namespace MWWorld mSharedExt.push_back(&(it->second)); } } - void Store::load(ESM::ESMReader &esm) + RecordId Store::load(ESM::ESMReader &esm) { // Don't automatically assume that a new cell must be spawned. Multiple plugins write to the same cell, // and we merge all this data into one Cell object. However, we can't simply search for the cell id, @@ -704,6 +690,7 @@ namespace MWWorld mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = cell; } } + return RecordId("", cell.mIsDeleted); } Store::iterator Store::intBegin() const { @@ -859,7 +846,7 @@ namespace MWWorld { mCells = &cells; } - void Store::load(ESM::ESMReader &esm) + RecordId Store::load(ESM::ESMReader &esm) { ESM::Pathgrid pathgrid; pathgrid.load(esm); @@ -884,6 +871,8 @@ namespace MWWorld if (!ret.second) ret.first->second = pathgrid; } + + return RecordId(); // No ID and can't be deleted (for now) } size_t Store::getSize() const { @@ -1035,7 +1024,7 @@ namespace MWWorld } template <> - inline void Store::load(ESM::ESMReader &esm) { + inline RecordId Store::load(ESM::ESMReader &esm) { // The original letter case of a dialogue ID is saved, because it's printed ESM::Dialogue dialogue; dialogue.load(esm); @@ -1053,7 +1042,7 @@ namespace MWWorld found->second.mType = dialogue.mType; } - mLastAddedRecord = dialogue; + return RecordId(dialogue.mId, dialogue.mIsDeleted); } @@ -1061,7 +1050,7 @@ namespace MWWorld //========================================================================= template <> - inline void Store::load(ESM::ESMReader &esm) { + inline RecordId Store::load(ESM::ESMReader &esm) { ESM::Script script; script.load(esm); Misc::StringUtils::toLower(script.mId); @@ -1072,7 +1061,7 @@ namespace MWWorld else inserted.first->second = script; - mLastAddedRecord = script; + return RecordId(script.mId, script.mIsDeleted); } @@ -1080,7 +1069,7 @@ namespace MWWorld //========================================================================= template <> - inline void Store::load(ESM::ESMReader &esm) + inline RecordId Store::load(ESM::ESMReader &esm) { ESM::StartScript script; script.load(esm); @@ -1092,7 +1081,7 @@ namespace MWWorld else inserted.first->second = script; - mLastAddedRecord = script; + return RecordId(script.mId); } } diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 0fdfffd41..bbbd30cd0 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -19,6 +19,14 @@ namespace Loading namespace MWWorld { + struct RecordId + { + std::string mId; + bool mIsDeleted; + + RecordId(const std::string &id = "", bool isDeleted = false); + }; + struct StoreBase { virtual ~StoreBase() {} @@ -28,19 +36,15 @@ namespace MWWorld virtual size_t getSize() const = 0; virtual int getDynamicSize() const { return 0; } - virtual void load(ESM::ESMReader &esm) = 0; + virtual RecordId load(ESM::ESMReader &esm) = 0; virtual bool eraseStatic(const std::string &id) {return false;} virtual void clearDynamic() {} virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const {} - virtual void read (ESM::ESMReader& reader) {} + virtual RecordId read (ESM::ESMReader& reader) { return RecordId(); } ///< Read into dynamic storage - - virtual std::string getLastAddedRecordId() const { return ""; } - ///< Returns the last loaded/read ID or empty string if a loaded record has no ID - virtual bool isLastAddedRecordDeleted() const { return false; } }; template @@ -137,8 +141,6 @@ namespace MWWorld // for heads/hairs in the character creation) std::map mDynamic; - T mLastAddedRecord; - typedef std::map Dynamic; typedef std::map Static; @@ -185,12 +187,9 @@ namespace MWWorld bool erase(const std::string &id); bool erase(const T &item); - void load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm); void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - void read(ESM::ESMReader& reader); - - std::string getLastAddedRecordId() const; - bool isLastAddedRecordDeleted() const; + RecordId read(ESM::ESMReader& reader); }; template <> @@ -199,7 +198,6 @@ namespace MWWorld // For multiple ESM/ESP files we need one list per file. typedef std::vector LandTextureList; std::vector mStatic; - ESM::LandTexture mLastAddedRecord; public: Store(); @@ -214,14 +212,11 @@ namespace MWWorld size_t getSize() const; size_t getSize(size_t plugin) const; - void load(ESM::ESMReader &esm, size_t plugin); - void load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm, size_t plugin); + RecordId load(ESM::ESMReader &esm); iterator begin(size_t plugin) const; iterator end(size_t plugin) const; - - std::string getLastAddedRecordId() const; - bool isLastAddedRecordDeleted() const; }; template <> @@ -243,7 +238,7 @@ namespace MWWorld ESM::Land *search(int x, int y) const; ESM::Land *find(int x, int y) const; - void load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm); void setUp(); }; @@ -293,7 +288,7 @@ namespace MWWorld void setUp(); - void load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm); iterator intBegin() const; iterator intEnd() const; @@ -335,7 +330,7 @@ namespace MWWorld Store(); void setCells(Store& cells); - void load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm); size_t getSize() const; void setUp(); diff --git a/components/esm/util.hpp b/components/esm/util.hpp index 94a7956ef..ca6917fd1 100644 --- a/components/esm/util.hpp +++ b/components/esm/util.hpp @@ -60,12 +60,6 @@ struct Vector3 bool readDeleSubRecord(ESMReader &esm); void writeDeleSubRecord(ESMWriter &esm); -template -std::string getRecordId(const RecordT &record) -{ - return record.mId; -} - template bool isRecordDeleted(const RecordT &record) {