mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Rework RefIdData code. Update the index map when a new record is loaded
This commit is contained in:
parent
b55a4999ca
commit
5e623a2a1d
@ -3,10 +3,20 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {}
|
||||
|
||||
|
||||
std::string CSMWorld::RefIdData::getRecordId(const CSMWorld::RefIdData::LocalIndex &index) const
|
||||
{
|
||||
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator found =
|
||||
mRecordContainers.find (index.second);
|
||||
|
||||
if (found == mRecordContainers.end())
|
||||
throw std::logic_error ("invalid local index type");
|
||||
|
||||
return found->second->getId(index.first);
|
||||
}
|
||||
|
||||
CSMWorld::RefIdData::RefIdData()
|
||||
{
|
||||
mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators));
|
||||
@ -167,9 +177,21 @@ void CSMWorld::RefIdData::load (ESM::ESMReader& reader, bool base, CSMWorld::Uni
|
||||
mRecordContainers.find (type);
|
||||
|
||||
if (found == mRecordContainers.end())
|
||||
throw std::logic_error ("Invalid type for an Object (Reference ID)");
|
||||
throw std::logic_error ("Invalid Referenceable ID type");
|
||||
|
||||
found->second->load(reader, base);
|
||||
int index = found->second->load(reader, base);
|
||||
if (index != -1)
|
||||
{
|
||||
LocalIndex localIndex = LocalIndex(index, type);
|
||||
if (base && getRecord(localIndex).mState == RecordBase::State_Deleted)
|
||||
{
|
||||
erase(localIndex, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIndex[Misc::StringUtils::lowerCase(getRecordId(localIndex))] = localIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSMWorld::RefIdData::erase (const LocalIndex& index, int count)
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <components/esm/loadmisc.hpp>
|
||||
#include <components/esm/esmwriter.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "record.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
@ -49,7 +51,8 @@ namespace CSMWorld
|
||||
|
||||
virtual void insertRecord (RecordBase& record) = 0;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base) = 0;
|
||||
virtual int load (ESM::ESMReader& reader, bool base) = 0;
|
||||
///< \return index of a loaded record or -1 if no record was loaded
|
||||
|
||||
virtual void erase (int index, int count) = 0;
|
||||
|
||||
@ -73,7 +76,8 @@ namespace CSMWorld
|
||||
|
||||
virtual void insertRecord (RecordBase& record);
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base);
|
||||
virtual int load (ESM::ESMReader& reader, bool base);
|
||||
///< \return index of a loaded record or -1 if no record was loaded
|
||||
|
||||
virtual void erase (int index, int count);
|
||||
|
||||
@ -122,15 +126,16 @@ namespace CSMWorld
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
void RefIdDataContainer<RecordT>::load (ESM::ESMReader& reader, bool base)
|
||||
int RefIdDataContainer<RecordT>::load (ESM::ESMReader& reader, bool base)
|
||||
{
|
||||
RecordT record;
|
||||
record.load(reader);
|
||||
|
||||
typename std::vector<Record<RecordT> >::iterator found = mContainer.begin();
|
||||
for (; found != mContainer.end(); ++found)
|
||||
int index = 0;
|
||||
int numRecords = static_cast<int>(mContainer.size());
|
||||
for (; index < numRecords; ++index)
|
||||
{
|
||||
if (found->get().mId == record.mId)
|
||||
if (Misc::StringUtils::ciEqual(mContainer[index].get().mId, record.mId))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -138,26 +143,21 @@ namespace CSMWorld
|
||||
|
||||
if (record.mIsDeleted)
|
||||
{
|
||||
if (found == mContainer.end())
|
||||
if (index == numRecords)
|
||||
{
|
||||
// deleting a record that does not exist
|
||||
// ignore it for now
|
||||
/// \todo report the problem to the user
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (base)
|
||||
{
|
||||
mContainer.erase(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
found->mState = RecordBase::State_Deleted;
|
||||
}
|
||||
// Flag the record as Deleted even for a base content file.
|
||||
// RefIdData is responsible for its erasure.
|
||||
mContainer[index].mState = RecordBase::State_Deleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (found == mContainer.end())
|
||||
if (index == numRecords)
|
||||
{
|
||||
appendRecord(record.mId, base);
|
||||
if (base)
|
||||
@ -169,20 +169,13 @@ namespace CSMWorld
|
||||
mContainer.back().mModified = record;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!base)
|
||||
{
|
||||
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;
|
||||
}
|
||||
mContainer[index].setModified(record);
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
@ -204,25 +197,15 @@ namespace CSMWorld
|
||||
void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
|
||||
{
|
||||
Record<RecordT> record = mContainer.at(index);
|
||||
RecordT esmRecord;
|
||||
RecordT esmRecord = record.get();
|
||||
|
||||
switch (record.mState)
|
||||
if (record.isModified() || record.mState == RecordBase::State_Deleted)
|
||||
{
|
||||
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;
|
||||
esmRecord.mIsDeleted = (record.mState == RecordBase::State_Deleted);
|
||||
writer.startRecord(esmRecord.sRecordId);
|
||||
esmRecord.save(writer);
|
||||
writer.endRecord(esmRecord.sRecordId);
|
||||
}
|
||||
|
||||
writer.startRecord(esmRecord.sRecordId);
|
||||
esmRecord.save(writer);
|
||||
writer.endRecord(esmRecord.sRecordId);
|
||||
}
|
||||
|
||||
|
||||
@ -262,6 +245,8 @@ namespace CSMWorld
|
||||
void erase (const LocalIndex& index, int count);
|
||||
///< Must not spill over into another type.
|
||||
|
||||
std::string getRecordId(const LocalIndex &index) const;
|
||||
|
||||
public:
|
||||
|
||||
RefIdData();
|
||||
|
Loading…
x
Reference in New Issue
Block a user