Load/read methods in MWWorld::Store return a pair (record ID, deleted flag)

openmw-38
Stanislav Bas 10 years ago
parent 2ed182b144
commit c266315a35

@ -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<ESM::Dialogue*>(mDialogs.find(id));
dialogue = const_cast<ESM::Dialogue*>(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<size_t>(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_)

@ -44,6 +44,10 @@ namespace
namespace MWWorld
{
RecordId::RecordId(const std::string &id, bool isDeleted)
: mId(id), mIsDeleted(isDeleted)
{}
template<typename T>
IndexedStore<T>::IndexedStore()
{
@ -180,7 +184,7 @@ namespace MWWorld
return ptr;
}
template<typename T>
void Store<T>::load(ESM::ESMReader &esm)
RecordId Store<T>::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<typename T>
void Store<T>::setUp()
@ -317,25 +321,13 @@ namespace MWWorld
}
}
template<typename T>
void Store<T>::read(ESM::ESMReader& reader)
RecordId Store<T>::read(ESM::ESMReader& reader)
{
T record;
record.load (reader);
insert (record);
mLastAddedRecord = record;
}
template<typename T>
std::string Store<T>::getLastAddedRecordId() const
{
return ESM::getRecordId(mLastAddedRecord);
}
template<typename T>
bool Store<T>::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<ESM::LandTexture>::load(ESM::ESMReader &esm, size_t plugin)
RecordId Store<ESM::LandTexture>::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<ESM::LandTexture>::load(ESM::ESMReader &esm)
RecordId Store<ESM::LandTexture>::load(ESM::ESMReader &esm)
{
load(esm, esm.getIndex());
return load(esm, esm.getIndex());
}
Store<ESM::LandTexture>::iterator Store<ESM::LandTexture>::begin(size_t plugin) const
{
@ -405,16 +399,6 @@ namespace MWWorld
assert(plugin < mStatic.size());
return mStatic[plugin].end();
}
std::string Store<ESM::LandTexture>::getLastAddedRecordId() const
{
return ESM::getRecordId(mLastAddedRecord);
}
bool Store<ESM::LandTexture>::isLastAddedRecordDeleted() const
{
return ESM::isRecordDeleted(mLastAddedRecord);
}
// Land
//=========================================================================
@ -462,7 +446,7 @@ namespace MWWorld
}
return ptr;
}
void Store<ESM::Land>::load(ESM::ESMReader &esm)
RecordId Store<ESM::Land>::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<ESM::Land>::setUp()
{
@ -622,7 +608,7 @@ namespace MWWorld
mSharedExt.push_back(&(it->second));
}
}
void Store<ESM::Cell>::load(ESM::ESMReader &esm)
RecordId Store<ESM::Cell>::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<ESM::Cell>::iterator Store<ESM::Cell>::intBegin() const
{
@ -859,7 +846,7 @@ namespace MWWorld
{
mCells = &cells;
}
void Store<ESM::Pathgrid>::load(ESM::ESMReader &esm)
RecordId Store<ESM::Pathgrid>::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<ESM::Pathgrid>::getSize() const
{
@ -1035,7 +1024,7 @@ namespace MWWorld
}
template <>
inline void Store<ESM::Dialogue>::load(ESM::ESMReader &esm) {
inline RecordId Store<ESM::Dialogue>::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<ESM::Script>::load(ESM::ESMReader &esm) {
inline RecordId Store<ESM::Script>::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<ESM::StartScript>::load(ESM::ESMReader &esm)
inline RecordId Store<ESM::StartScript>::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);
}
}

@ -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 <class T>
@ -137,8 +141,6 @@ namespace MWWorld
// for heads/hairs in the character creation)
std::map<std::string, T> mDynamic;
T mLastAddedRecord;
typedef std::map<std::string, T> Dynamic;
typedef std::map<std::string, T> 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<ESM::LandTexture> LandTextureList;
std::vector<LandTextureList> 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<ESM::Cell>& cells);
void load(ESM::ESMReader &esm);
RecordId load(ESM::ESMReader &esm);
size_t getSize() const;
void setUp();

@ -60,12 +60,6 @@ struct Vector3
bool readDeleSubRecord(ESMReader &esm);
void writeDeleSubRecord(ESMWriter &esm);
template <class RecordT>
std::string getRecordId(const RecordT &record)
{
return record.mId;
}
template <class RecordT>
bool isRecordDeleted(const RecordT &record)
{

Loading…
Cancel
Save