Use std::unique_ptr to store records in collections, RefidCollection and RefIdData.

(copied the changes from commit 23e7e3c165)
cherry-pick-2bee171c
cc9cii 4 years ago
parent 469cc44ef7
commit be45092e55

@ -1,6 +1,7 @@
#include "document.hpp"
#include <cassert>
#include <memory>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@ -115,10 +116,10 @@ void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst)
{
if (getData().getGmsts().searchId (gmst.mId)==-1)
{
CSMWorld::Record<ESM::GameSetting> record;
record.mBase = gmst;
record.mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getGmsts().appendRecord (record);
std::unique_ptr<CSMWorld::Record<ESM::GameSetting> > record(new CSMWorld::Record<ESM::GameSetting>);
record->mBase = gmst;
record->mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getGmsts().appendRecord (std::move(record));
}
}
@ -126,10 +127,10 @@ void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global)
{
if (getData().getGlobals().searchId (global.mId)==-1)
{
CSMWorld::Record<ESM::Global> record;
record.mBase = global;
record.mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getGlobals().appendRecord (record);
std::unique_ptr<CSMWorld::Record<ESM::Global> > record(new CSMWorld::Record<ESM::Global>);
record->mBase = global;
record->mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getGlobals().appendRecord (std::move(record));
}
}
@ -137,10 +138,10 @@ void CSMDoc::Document::addOptionalMagicEffect (const ESM::MagicEffect& magicEffe
{
if (getData().getMagicEffects().searchId (magicEffect.mId)==-1)
{
CSMWorld::Record<ESM::MagicEffect> record;
record.mBase = magicEffect;
record.mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getMagicEffects().appendRecord (record);
std::unique_ptr<CSMWorld::Record<ESM::MagicEffect> > record(new CSMWorld::Record<ESM::MagicEffect>);
record->mBase = magicEffect;
record->mState = CSMWorld::RecordBase::State_BaseOnly;
getData().getMagicEffects().appendRecord (std::move(record));
}
}

@ -114,7 +114,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
{
if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted)
{
infoModified = true;
break;
@ -140,9 +140,9 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
// write modified selected info records
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
{
if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted)
{
ESM::DialInfo info = iter->get();
ESM::DialInfo info = (*iter)->get();
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
info.mPrev = "";
@ -151,7 +151,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
CSMWorld::InfoCollection::RecordConstIterator prev = iter;
--prev;
info.mPrev = prev->get().mId.substr (prev->get().mId.find_last_of ('#')+1);
info.mPrev = (*prev)->get().mId.substr ((*prev)->get().mId.find_last_of ('#')+1);
}
CSMWorld::InfoCollection::RecordConstIterator next = iter;
@ -160,11 +160,11 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
info.mNext = "";
if (next!=range.second)
{
info.mNext = next->get().mId.substr (next->get().mId.find_last_of ('#')+1);
info.mNext = (*next)->get().mId.substr ((*next)->get().mId.find_last_of ('#')+1);
}
writer.startRecord (info.sRecordId);
info.save (writer, iter->mState == CSMWorld::RecordBase::State_Deleted);
info.save (writer, (*iter)->mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (info.sRecordId);
}
}

@ -35,7 +35,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages)
for (CSMWorld::InfoCollection::RecordConstIterator it = range.first; it != range.second; ++it)
{
const CSMWorld::Record<CSMWorld::Info> infoRecord = (*it);
const CSMWorld::Record<CSMWorld::Info> infoRecord = (*it->get());
if (infoRecord.isDeleted())
continue;

@ -103,10 +103,9 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa
ref.mRefNum.mContentFile = 0;
ref.mNew = false;
CSMWorld::Record<CSMWorld::CellRef> newRecord (
CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &ref);
mState.mTarget->getData().getReferences().appendRecord (newRecord);
mState.mTarget->getData().getReferences().appendRecord (
std::make_unique<CSMWorld::Record<CSMWorld::CellRef> >(
CSMWorld::Record<CSMWorld::CellRef>(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &ref)));
}
}
@ -128,7 +127,9 @@ void CSMTools::PopulateLandTexturesMergeStage::perform (int stage, CSMDoc::Messa
if (!record.isDeleted())
{
mState.mTarget->getData().getLandTextures().appendRecord(record);
mState.mTarget->getData().getLandTextures().appendRecord(
std::make_unique<CSMWorld::Record<CSMWorld::LandTexture> >(
CSMWorld::Record<CSMWorld::LandTexture>(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get())));
}
}
@ -150,7 +151,9 @@ void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages)
if (!record.isDeleted())
{
mState.mTarget->getData().getLand().appendRecord (record);
mState.mTarget->getData().getLand().appendRecord (
std::make_unique<CSMWorld::Record<CSMWorld::Land> >(
CSMWorld::Record<CSMWorld::Land>(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get())));
}
}
@ -185,10 +188,9 @@ void CSMTools::FixLandsAndLandTexturesMergeStage::perform (int stage, CSMDoc::Me
const CSMWorld::Record<CSMWorld::Land>& oldRecord =
mState.mTarget->getData().getLand().getRecord (stage);
CSMWorld::Record<CSMWorld::Land> newRecord(CSMWorld::RecordBase::State_ModifiedOnly,
nullptr, &oldRecord.get());
mState.mTarget->getData().getLand().setRecord(stage, newRecord);
mState.mTarget->getData().getLand().setRecord (stage,
std::make_unique<CSMWorld::Record<CSMWorld::Land> >(
CSMWorld::Record<CSMWorld::Land>(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &oldRecord.get())));
}
}

@ -3,6 +3,7 @@
#include <algorithm>
#include <map>
#include <memory>
#include <components/to_utf8/to_utf8.hpp>
@ -82,7 +83,8 @@ namespace CSMTools
const CSMWorld::Record<RecordType>& record = source.getRecord (stage);
if (!record.isDeleted())
target.appendRecord (CSMWorld::Record<RecordType> (CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()));
target.appendRecord (std::make_unique<CSMWorld::Record<RecordType> >(
CSMWorld::Record<RecordType>(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get())));
}
class MergeRefIdsStage : public CSMDoc::Stage

@ -8,6 +8,7 @@
#include <stdexcept>
#include <string>
#include <functional>
#include <memory>
#include <QVariant>
@ -84,7 +85,7 @@ namespace CSMWorld
private:
std::vector<Record<ESXRecordT> > mRecords;
std::vector<std::unique_ptr<Record<ESXRecordT> > > mRecords;
std::map<std::string, int> mIndex;
std::vector<Column<ESXRecordT> *> mColumns;
@ -96,7 +97,7 @@ namespace CSMWorld
const std::map<std::string, int>& getIdMap() const;
const std::vector<Record<ESXRecordT> >& getRecords() const;
const std::vector<std::unique_ptr<Record<ESXRecordT> > >& getRecords() const;
bool reorderRowsImp (int baseIndex, const std::vector<int>& newOrder);
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
@ -158,12 +159,12 @@ namespace CSMWorld
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
void replace (int index, const RecordBase& record) override;
void replace (int index, std::unique_ptr<RecordBase> record) override;
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
void appendRecord (const RecordBase& record,
void appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type = UniversalId::Type_None) override;
///< If the record type does not match, an exception is thrown.
///< \param type Will be ignored, unless the collection supports multiple record types
@ -181,7 +182,7 @@ namespace CSMWorld
///
/// \param listDeleted include deleted record in the list
virtual void insertRecord (const RecordBase& record, int index,
virtual void insertRecord (std::unique_ptr<RecordBase> record, int index,
UniversalId::Type type = UniversalId::Type_None);
///< Insert record before index.
///
@ -198,7 +199,7 @@ namespace CSMWorld
void addColumn (Column<ESXRecordT> *column);
void setRecord (int index, const Record<ESXRecordT>& record);
void setRecord (int index, std::unique_ptr<Record<ESXRecordT> > record);
///< \attention This function must not change the ID.
NestableColumn *getNestableColumn (int column) const;
@ -211,7 +212,7 @@ namespace CSMWorld
}
template<typename ESXRecordT, typename IdAccessorT>
const std::vector<Record<ESXRecordT> >& Collection<ESXRecordT, IdAccessorT>::getRecords() const
const std::vector<std::unique_ptr<Record<ESXRecordT> > >& Collection<ESXRecordT, IdAccessorT>::getRecords() const
{
return mRecords;
}
@ -231,15 +232,15 @@ namespace CSMWorld
return false;
// reorder records
std::vector<Record<ESXRecordT> > buffer (size);
std::vector<std::unique_ptr<Record<ESXRecordT> > > buffer (size);
for (int i=0; i<size; ++i)
{
buffer[newOrder[i]] = mRecords [baseIndex+i];
buffer[newOrder[i]].setModified (buffer[newOrder[i]].get());
buffer[newOrder[i]] = std::move(mRecords [baseIndex+i]);
buffer[newOrder[i]]->setModified (buffer[newOrder[i]]->get());
}
std::copy (buffer.begin(), buffer.end(), mRecords.begin()+baseIndex);
std::move (buffer.begin(), buffer.end(), mRecords.begin()+baseIndex);
// adjust index
for (std::map<std::string, int>::iterator iter (mIndex.begin()); iter!=mIndex.end();
@ -255,18 +256,18 @@ namespace CSMWorld
int Collection<ESXRecordT, IdAccessorT>::cloneRecordImp(const std::string& origin,
const std::string& destination, UniversalId::Type type)
{
Record<ESXRecordT> copy;
copy.mModified = getRecord(origin).get();
copy.mState = RecordBase::State_ModifiedOnly;
IdAccessorT().setId(copy.get(), destination);
std::unique_ptr<Record<ESXRecordT> > copy(new Record<ESXRecordT>);
copy->mModified = getRecord(origin).get();
copy->mState = RecordBase::State_ModifiedOnly;
IdAccessorT().setId(copy->get(), destination);
if (type == UniversalId::Type_Reference) {
CSMWorld::CellRef* ptr = (CSMWorld::CellRef*) &copy.mModified;
CSMWorld::CellRef* ptr = (CSMWorld::CellRef*) &copy->mModified;
ptr->mRefNum.mIndex = 0;
}
int index = getAppendIndex(destination, type);
insertRecord(copy, getAppendIndex(destination, type));
insertRecord(std::move(copy), getAppendIndex(destination, type));
return index;
}
@ -275,7 +276,7 @@ namespace CSMWorld
int Collection<ESXRecordT, IdAccessorT>::touchRecordImp(const std::string& id)
{
int index = getIndex(id);
Record<ESXRecordT>& record = mRecords.at(index);
Record<ESXRecordT>& record = *mRecords.at(index);
if (record.isDeleted())
{
throw std::runtime_error("attempt to touch deleted record");
@ -302,7 +303,7 @@ namespace CSMWorld
const std::string& destination, const UniversalId::Type type)
{
int index = cloneRecordImp(origin, destination, type);
mRecords.at(index).get().mPlugin = 0;
mRecords.at(index)->get().mPlugin = 0;
}
template<typename ESXRecordT, typename IdAccessorT>
@ -317,7 +318,7 @@ namespace CSMWorld
int index = touchRecordImp(id);
if (index >= 0)
{
mRecords.at(index).get().mPlugin = 0;
mRecords.at(index)->get().mPlugin = 0;
return true;
}
@ -344,15 +345,15 @@ namespace CSMWorld
if (iter==mIndex.end())
{
Record<ESXRecordT> record2;
record2.mState = Record<ESXRecordT>::State_ModifiedOnly;
record2.mModified = record;
std::unique_ptr<Record<ESXRecordT> > record2(new Record<ESXRecordT>);
record2->mState = Record<ESXRecordT>::State_ModifiedOnly;
record2->mModified = record;
insertRecord (record2, getAppendIndex (id));
insertRecord (std::move(record2), getAppendIndex (id));
}
else
{
mRecords[iter->second].setModified (record);
mRecords[iter->second]->setModified (record);
}
}
@ -365,7 +366,7 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
std::string Collection<ESXRecordT, IdAccessorT>::getId (int index) const
{
return IdAccessorT().getId (mRecords.at (index).get());
return IdAccessorT().getId (mRecords.at (index)->get());
}
template<typename ESXRecordT, typename IdAccessorT>
@ -388,13 +389,13 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
QVariant Collection<ESXRecordT, IdAccessorT>::getData (int index, int column) const
{
return mColumns.at (column)->get (mRecords.at (index));
return mColumns.at (column)->get (*mRecords.at (index));
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::setData (int index, int column, const QVariant& data)
{
return mColumns.at (column)->set (mRecords.at (index), data);
return mColumns.at (column)->set (*mRecords.at (index), data);
}
template<typename ESXRecordT, typename IdAccessorT>
@ -421,8 +422,8 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::merge()
{
for (typename std::vector<Record<ESXRecordT> >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter)
iter->merge();
for (typename std::vector<std::unique_ptr<Record<ESXRecordT> > >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter)
(*iter)->merge();
purge();
}
@ -434,7 +435,7 @@ namespace CSMWorld
while (i<static_cast<int> (mRecords.size()))
{
if (mRecords[i].isErased())
if (mRecords[i]->isErased())
removeRows (i, 1);
else
++i;
@ -475,11 +476,11 @@ namespace CSMWorld
IdAccessorT().setId(record, id);
record.blank();
Record<ESXRecordT> record2;
record2.mState = Record<ESXRecordT>::State_ModifiedOnly;
record2.mModified = record;
std::unique_ptr<Record<ESXRecordT> > record2(new Record<ESXRecordT>);
record2->mState = Record<ESXRecordT>::State_ModifiedOnly;
record2->mModified = record;
insertRecord (record2, getAppendIndex (id, type), type);
insertRecord (std::move(record2), getAppendIndex (id, type), type);
}
template<typename ESXRecordT, typename IdAccessorT>
@ -496,18 +497,19 @@ namespace CSMWorld
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::replace (int index, const RecordBase& record)
void Collection<ESXRecordT, IdAccessorT>::replace (int index, std::unique_ptr<RecordBase> record)
{
mRecords.at (index) = dynamic_cast<const Record<ESXRecordT>&> (record);
std::unique_ptr<Record<ESXRecordT> > tmp(static_cast<Record<ESXRecordT>*>(record.release()));
mRecords.at (index) = std::move(tmp);
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::appendRecord (const RecordBase& record,
void Collection<ESXRecordT, IdAccessorT>::appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type)
{
insertRecord (record,
getAppendIndex (IdAccessorT().getId (
dynamic_cast<const Record<ESXRecordT>&> (record).get()), type), type);
int index =
getAppendIndex(IdAccessorT().getId(static_cast<Record<ESXRecordT>*>(record.get())->get()), type);
insertRecord (std::move(record), index, type);
}
template<typename ESXRecordT, typename IdAccessorT>
@ -525,8 +527,8 @@ namespace CSMWorld
for (typename std::map<std::string, int>::const_iterator iter = mIndex.begin();
iter!=mIndex.end(); ++iter)
{
if (listDeleted || !mRecords[iter->second].isDeleted())
ids.push_back (IdAccessorT().getId (mRecords[iter->second].get()));
if (listDeleted || !mRecords[iter->second]->isDeleted())
ids.push_back (IdAccessorT().getId (mRecords[iter->second]->get()));
}
return ids;
@ -536,25 +538,26 @@ namespace CSMWorld
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
{
int index = getIndex (id);
return mRecords.at (index);
return *mRecords.at (index);
}
template<typename ESXRecordT, typename IdAccessorT>
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (int index) const
{
return mRecords.at (index);
return *mRecords.at (index);
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::insertRecord (const RecordBase& record, int index,
void Collection<ESXRecordT, IdAccessorT>::insertRecord (std::unique_ptr<RecordBase> record, int index,
UniversalId::Type type)
{
if (index<0 || index>static_cast<int> (mRecords.size()))
throw std::runtime_error ("index out of range");
const Record<ESXRecordT>& record2 = dynamic_cast<const Record<ESXRecordT>&> (record);
std::unique_ptr<Record<ESXRecordT> > record2(static_cast<Record<ESXRecordT>*>(record.release()));
std::string lowerId = Misc::StringUtils::lowerCase(IdAccessorT().getId(record2->get()));
mRecords.insert (mRecords.begin()+index, record2);
mRecords.insert (mRecords.begin()+index, std::move(record2));
if (index<static_cast<int> (mRecords.size())-1)
{
@ -564,18 +567,18 @@ namespace CSMWorld
++(iter->second);
}
mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId (
record2.get())), index));
mIndex.insert (std::make_pair (lowerId, index));
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::setRecord (int index, const Record<ESXRecordT>& record)
void Collection<ESXRecordT, IdAccessorT>::setRecord (int index,
std::unique_ptr<Record<ESXRecordT> > record)
{
if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index).get()))!=
Misc::StringUtils::lowerCase (IdAccessorT().getId (record.get())))
if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index)->get())) !=
Misc::StringUtils::lowerCase (IdAccessorT().getId (record->get())))
throw std::runtime_error ("attempt to change the ID of a record");
mRecords.at (index) = record;
mRecords.at (index) = std::move(record);
}
template<typename ESXRecordT, typename IdAccessorT>

@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include <memory>
#include "universalid.hpp"
#include "columns.hpp"
@ -64,13 +65,13 @@ namespace CSMWorld
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace (int index, const RecordBase& record) = 0;
virtual void replace (int index, std::unique_ptr<RecordBase> record) = 0;
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
///< \param type Will be ignored, unless the collection supports multiple record types
virtual void appendRecord (const RecordBase& record,
virtual void appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type = UniversalId::Type_None) = 0;
///< If the record type does not match, an exception is thrown.

@ -24,7 +24,7 @@ CSMWorld::TouchCommand::TouchCommand(IdTable& table, const std::string& id, QUnd
, mChanged(false)
{
setText(("Touch " + mId).c_str());
mOld.reset(mTable.getRecord(mId).clone());
mOld.reset(mTable.getRecord(mId).clone().get());
}
void CSMWorld::TouchCommand::redo()
@ -36,7 +36,7 @@ void CSMWorld::TouchCommand::undo()
{
if (mChanged)
{
mTable.setRecord(mId, *mOld);
mTable.setRecord(mId, std::move(mOld));
mChanged = false;
}
}
@ -159,7 +159,7 @@ CSMWorld::TouchLandCommand::TouchLandCommand(IdTable& landTable, IdTable& ltexTa
, mChanged(false)
{
setText(("Touch " + mId).c_str());
mOld.reset(mLands.getRecord(mId).clone());
mOld.reset(mLands.getRecord(mId).clone().get());
}
const std::string& CSMWorld::TouchLandCommand::getOriginId() const
@ -181,7 +181,7 @@ void CSMWorld::TouchLandCommand::onUndo()
{
if (mChanged)
{
mLands.setRecord(mId, *mOld);
mLands.setRecord(mId, std::move(mOld));
mChanged = false;
}
}
@ -291,16 +291,15 @@ void CSMWorld::CreateCommand::undo()
}
CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand* parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (nullptr)
: QUndoCommand (parent), mModel (model), mId (id)
{
setText (("Revert record " + id).c_str());
mOld = model.getRecord (id).clone();
mOld = std::move(model.getRecord (id).clone());
}
CSMWorld::RevertCommand::~RevertCommand()
{
delete mOld;
}
void CSMWorld::RevertCommand::redo()
@ -322,21 +321,20 @@ void CSMWorld::RevertCommand::redo()
void CSMWorld::RevertCommand::undo()
{
mModel.setRecord (mId, *mOld);
mModel.setRecord (mId, std::move(mOld));
}
CSMWorld::DeleteCommand::DeleteCommand (IdTable& model,
const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (nullptr), mType(type)
: QUndoCommand (parent), mModel (model), mId (id), mType(type)
{
setText (("Delete record " + id).c_str());
mOld = model.getRecord (id).clone();
mOld = std::move(model.getRecord (id).clone());
}
CSMWorld::DeleteCommand::~DeleteCommand()
{
delete mOld;
}
void CSMWorld::DeleteCommand::redo()
@ -358,7 +356,7 @@ void CSMWorld::DeleteCommand::redo()
void CSMWorld::DeleteCommand::undo()
{
mModel.setRecord (mId, *mOld, mType);
mModel.setRecord (mId, std::move(mOld), mType);
}
@ -424,18 +422,19 @@ void CSMWorld::CreatePathgridCommand::redo()
{
CreateCommand::redo();
Record<Pathgrid> record = static_cast<const Record<Pathgrid>& >(mModel.getRecord(mId));
record.get().blank();
record.get().mCell = mId;
std::unique_ptr<Record<Pathgrid> > record
= std::make_unique<Record<Pathgrid> >(static_cast<const Record<Pathgrid>& >(mModel.getRecord(mId)));
record->get().blank();
record->get().mCell = mId;
std::pair<CellCoordinates, bool> coords = CellCoordinates::fromId(mId);
if (coords.second)
{
record.get().mData.mX = coords.first.getX();
record.get().mData.mY = coords.first.getY();
record->get().mData.mX = coords.first.getX();
record->get().mData.mY = coords.first.getY();
}
mModel.setRecord(mId, record, mType);
mModel.setRecord(mId, std::move(record), mType);
}
CSMWorld::UpdateCellCommand::UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent)

@ -203,7 +203,7 @@ namespace CSMWorld
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
std::unique_ptr<RecordBase> mOld;
// not implemented
RevertCommand (const RevertCommand&);
@ -224,7 +224,7 @@ namespace CSMWorld
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
std::unique_ptr<RecordBase> mOld;
UniversalId::Type mType;
// not implemented

@ -917,8 +917,8 @@ const CSMWorld::MetaData& CSMWorld::Data::getMetaData() const
void CSMWorld::Data::setMetaData (const MetaData& metaData)
{
Record<MetaData> record (RecordBase::State_ModifiedOnly, nullptr, &metaData);
mMetaData.setRecord (0, record);
mMetaData.setRecord (0, std::make_unique<Record<MetaData> >(
Record<MetaData>(RecordBase::State_ModifiedOnly, nullptr, &metaData)));
}
QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
@ -983,7 +983,8 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
metaData.mId = "sys::meta";
metaData.load (*mReader);
mMetaData.setRecord (0, Record<MetaData> (RecordBase::State_ModifiedOnly, nullptr, &metaData));
mMetaData.setRecord (0, std::make_unique<Record<MetaData> >(
Record<MetaData> (RecordBase::State_ModifiedOnly, nullptr, &metaData)));
}
return mReader->getRecordCount();
@ -1011,10 +1012,10 @@ void CSMWorld::Data::loadFallbackEntries()
ESM::Static newMarker;
newMarker.mId = marker.first;
newMarker.mModel = marker.second;
CSMWorld::Record<ESM::Static> record;
record.mBase = newMarker;
record.mState = CSMWorld::RecordBase::State_BaseOnly;
mReferenceables.appendRecord (record, CSMWorld::UniversalId::Type_Static);
std::unique_ptr<CSMWorld::Record<ESM::Static> > record(new CSMWorld::Record<ESM::Static>);
record->mBase = newMarker;
record->mState = CSMWorld::RecordBase::State_BaseOnly;
mReferenceables.appendRecord (std::move(record), CSMWorld::UniversalId::Type_Static);
}
}
@ -1025,10 +1026,10 @@ void CSMWorld::Data::loadFallbackEntries()
ESM::Door newMarker;
newMarker.mId = marker.first;
newMarker.mModel = marker.second;
CSMWorld::Record<ESM::Door> record;
record.mBase = newMarker;
record.mState = CSMWorld::RecordBase::State_BaseOnly;
mReferenceables.appendRecord (record, CSMWorld::UniversalId::Type_Door);
std::unique_ptr<CSMWorld::Record<ESM::Door> > record(new CSMWorld::Record<ESM::Door>);
record->mBase = newMarker;
record->mState = CSMWorld::RecordBase::State_BaseOnly;
mReferenceables.appendRecord (std::move(record), CSMWorld::UniversalId::Type_Door);
}
}
}

@ -83,9 +83,9 @@ namespace CSMWorld
return -1;
}
Record<ESXRecordT> baseRecord = this->getRecord (index);
baseRecord.mState = RecordBase::State_Deleted;
this->setRecord (index, baseRecord);
std::unique_ptr<Record<ESXRecordT> > baseRecord(new Record<ESXRecordT>(this->getRecord(index)));
baseRecord->mState = RecordBase::State_Deleted;
this->setRecord(index, std::move(baseRecord));
return index;
}
@ -96,30 +96,31 @@ namespace CSMWorld
int IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
int index)
{
if (index==-2)
if (index==-2) // index unknown
index = this->searchId (IdAccessorT().getId (record));
if (index==-1)
{
// new record
Record<ESXRecordT> record2;
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2.mBase : record2.mModified) = record;
std::unique_ptr<Record<ESXRecordT> > record2(new Record<ESXRecordT>);
record2->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2->mBase : record2->mModified) = record;
index = this->getSize();
this->appendRecord (record2);
this->appendRecord(std::move(record2));
}
else
{
// old record
Record<ESXRecordT> record2 = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
std::unique_ptr<Record<ESXRecordT> > record2(
new Record<ESXRecordT>(Collection<ESXRecordT, IdAccessorT>::getRecord(index)));
if (base)
record2.mBase = record;
record2->mBase = record;
else
record2.setModified (record);
record2->setModified(record);
this->setRecord (index, record2);
this->setRecord(index, std::move(record2));
}
return index;
@ -133,7 +134,7 @@ namespace CSMWorld
if (index==-1)
return false;
Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
const Record<ESXRecordT>& record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
if (record.isDeleted())
return false;
@ -144,8 +145,10 @@ namespace CSMWorld
}
else
{
record.mState = RecordBase::State_Deleted;
this->setRecord (index, record);
std::unique_ptr<Record<ESXRecordT> > record2(
new Record<ESXRecordT>(Collection<ESXRecordT, IdAccessorT>::getRecord(index)));
record2->mState = RecordBase::State_Deleted;
this->setRecord(index, std::move(record2));
}
return true;

@ -228,23 +228,24 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column)
return QModelIndex();
}
void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record, CSMWorld::UniversalId::Type type)
void CSMWorld::IdTable::setRecord (const std::string& id,
std::unique_ptr<RecordBase> record, CSMWorld::UniversalId::Type type)
{
int index = mIdCollection->searchId (id);
if (index==-1)
{
index = mIdCollection->getAppendIndex (id, type);
int index2 = mIdCollection->getAppendIndex (id, type);
beginInsertRows (QModelIndex(), index, index);
beginInsertRows (QModelIndex(), index2, index2);
mIdCollection->appendRecord (record, type);
mIdCollection->appendRecord (std::move(record), type);
endInsertRows();
}
else
{
mIdCollection->replace (index, record);
mIdCollection->replace (index, std::move(record));
emit dataChanged (CSMWorld::IdTable::index (index, 0),
CSMWorld::IdTable::index (index, mIdCollection->getColumns()-1));
}

@ -2,6 +2,7 @@
#define CSM_WOLRD_IDTABLE_H
#include <vector>
#include <memory>
#include "idtablebase.hpp"
#include "universalid.hpp"
@ -67,7 +68,7 @@ namespace CSMWorld
QModelIndex getModelIndex (const std::string& id, int column) const override;
void setRecord (const std::string& id, const RecordBase& record,
void setRecord (const std::string& id, std::unique_ptr<RecordBase> record,
UniversalId::Type type = UniversalId::Type_None);
///< Add record or overwrite existing record.

@ -15,23 +15,23 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
if (index==-1)
{
// new record
Record<Info> record2;
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2.mBase : record2.mModified) = record;
std::unique_ptr<Record<Info> > record2(new Record<Info>);
record2->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2->mBase : record2->mModified) = record;
std::string topic = Misc::StringUtils::lowerCase (record2.get().mTopicId);
std::string topic = Misc::StringUtils::lowerCase (record2->get().mTopicId);
if (!record2.get().mPrev.empty())
if (!record2->get().mPrev.empty())
{
index = getInfoIndex (record2.get().mPrev, topic);
index = getInfoIndex (record2->get().mPrev, topic); // WARN: index repurposed
if (index!=-1)
++index;
}
if (index==-1 && !record2.get().mNext.empty())
if (index==-1 && !record2->get().mNext.empty())
{
index = getInfoIndex (record2.get().mNext, topic);
index = getInfoIndex (record2->get().mNext, topic);
}
if (index==-1)
@ -41,19 +41,19 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base)
index = std::distance (getRecords().begin(), range.second);
}
insertRecord (record2, index);
insertRecord (std::move(record2), index);
}
else
{
// old record
Record<Info> record2 = getRecord (index);
std::unique_ptr<Record<Info> > record2(new Record<Info>(getRecord(index)));
if (base)
record2.mBase = record;
record2->mBase = record;
else
record2.setModified (record);
record2->setModified (record);
setRecord (index, record2);
setRecord (index, std::move(record2));
}
}
@ -64,7 +64,7 @@ int CSMWorld::InfoCollection::getInfoIndex (const std::string& id, const std::st
std::pair<RecordConstIterator, RecordConstIterator> range = getTopicRange (topic);
for (; range.first!=range.second; ++range.first)
if (Misc::StringUtils::ciEqual(range.first->get().mId, fullId))
if (Misc::StringUtils::ciEqual((*range.first).get()->get().mId, fullId))
return std::distance (getRecords().begin(), range.first);
return -1;
@ -126,9 +126,9 @@ void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ES
}
else
{
Record<Info> record = getRecord (index);
record.mState = RecordBase::State_Deleted;
setRecord (index, record);
std::unique_ptr<Record<Info> > record(new Record<Info>(getRecord(index)));
record->mState = RecordBase::State_Deleted;
setRecord (index, std::move(record));
}
}
else
@ -169,7 +169,7 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
while (begin != getRecords().begin())
{
if (!Misc::StringUtils::ciEqual(begin->get().mTopicId, topic2))
if (!Misc::StringUtils::ciEqual((*begin)->get().mTopicId, topic2))
{
// we've gone one too far, go back
++begin;
@ -182,7 +182,7 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
RecordConstIterator end = begin;
for (; end!=getRecords().end(); ++end)
if (!Misc::StringUtils::ciEqual(end->get().mTopicId, topic2))
if (!Misc::StringUtils::ciEqual((*end)->get().mTopicId, topic2))
break;
return Range (begin, end);
@ -197,7 +197,7 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId
std::map<std::string, int>::const_iterator end = getIdMap().end();
for (; current != end; ++current)
{
Record<Info> record = getRecord(current->second);
const Record<Info>& record = getRecord(current->second);
if (Misc::StringUtils::ciEqual(dialogueId, record.get().mTopicId))
{
@ -207,8 +207,9 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId
}
else
{
record.mState = RecordBase::State_Deleted;
setRecord(current->second, record);
std::unique_ptr<Record<Info> > record2(new Record<Info>(record));
record2->mState = RecordBase::State_Deleted;
setRecord(current->second, std::move(record2));
}
}
else

@ -15,7 +15,7 @@ namespace CSMWorld
{
public:
typedef std::vector<Record<Info> >::const_iterator RecordConstIterator;
typedef std::vector<std::unique_ptr<Record<Info> > >::const_iterator RecordConstIterator;
typedef std::pair<RecordConstIterator, RecordConstIterator> Range;
private:

@ -90,23 +90,23 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT>
void NestedIdCollection<ESXRecordT, IdAccessorT>::addNestedRow(int row, int column, int position)
{
Record<ESXRecordT> record;
record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
std::unique_ptr<Record<ESXRecordT> > record(new Record<ESXRecordT>);
record->assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).addRow(record, position);
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).addRow(*record, position);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, record);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, std::move(record));
}
template<typename ESXRecordT, typename IdAccessorT>
void NestedIdCollection<ESXRecordT, IdAccessorT>::removeNestedRows(int row, int column, int subRow)
{
Record<ESXRecordT> record;
record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
std::unique_ptr<Record<ESXRecordT> > record(new Record<ESXRecordT>);
record->assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).removeRow(record, subRow);
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).removeRow(*record, subRow);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, record);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, std::move(record));
}
template<typename ESXRecordT, typename IdAccessorT>
@ -121,13 +121,13 @@ namespace CSMWorld
void NestedIdCollection<ESXRecordT, IdAccessorT>::setNestedData(int row,
int column, const QVariant& data, int subRow, int subColumn)
{
Record<ESXRecordT> record;
record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
std::unique_ptr<Record<ESXRecordT> > record(new Record<ESXRecordT>);
record->assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).setData(
record, data, subRow, subColumn);
*record, data, subRow, subColumn);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, record);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, std::move(record));
}
template<typename ESXRecordT, typename IdAccessorT>
@ -142,13 +142,13 @@ namespace CSMWorld
void NestedIdCollection<ESXRecordT, IdAccessorT>::setNestedTable(int row,
int column, const CSMWorld::NestedTableWrapperBase& nestedTable)
{
Record<ESXRecordT> record;
record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
std::unique_ptr<Record<ESXRecordT> > record(new Record<ESXRecordT>);
record->assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row));
getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).setTable(
record, nestedTable);
*record, nestedTable);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, record);
Collection<ESXRecordT, IdAccessorT>::setRecord(row, std::move(record));
}
template<typename ESXRecordT, typename IdAccessorT>

@ -35,22 +35,22 @@ namespace CSMWorld
void NestedInfoCollection::addNestedRow(int row, int column, int position)
{
Record<Info> record;
record.assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
std::unique_ptr<Record<Info> > record(new Record<Info>);
record->assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).addRow(record, position);
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).addRow(*record, position);
Collection<Info, IdAccessor<Info> >::setRecord(row, record);
Collection<Info, IdAccessor<Info> >::setRecord(row, std::move(record));
}
void NestedInfoCollection::removeNestedRows(int row, int column, int subRow)
{
Record<Info> record;
record.assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
std::unique_ptr<Record<Info> > record(new Record<Info>);
record->assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).removeRow(record, subRow);
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).removeRow(*record, subRow);
Collection<Info, IdAccessor<Info> >::setRecord(row, record);
Collection<Info, IdAccessor<Info> >::setRecord(row, std::move(record));
}
QVariant NestedInfoCollection::getNestedData (int row,
@ -63,13 +63,13 @@ namespace CSMWorld
void NestedInfoCollection::setNestedData(int row,
int column, const QVariant& data, int subRow, int subColumn)
{
Record<Info> record;
record.assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
std::unique_ptr<Record<Info> > record(new Record<Info>);
record->assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).setData(
record, data, subRow, subColumn);
*record, data, subRow, subColumn);
Collection<Info, IdAccessor<Info> >::setRecord(row, record);
Collection<Info, IdAccessor<Info> >::setRecord(row, std::move(record));
}
CSMWorld::NestedTableWrapperBase* NestedInfoCollection::nestedTable(int row,
@ -82,13 +82,13 @@ namespace CSMWorld
void NestedInfoCollection::setNestedTable(int row,
int column, const CSMWorld::NestedTableWrapperBase& nestedTable)
{
Record<Info> record;
record.assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
std::unique_ptr<Record<Info> > record(new Record<Info>);
record->assign(Collection<Info, IdAccessor<Info> >::getRecord(row));
getAdapter(Collection<Info, IdAccessor<Info> >::getColumn(column)).setTable(
record, nestedTable);
*record, nestedTable);
Collection<Info, IdAccessor<Info> >::setRecord(row, record);
Collection<Info, IdAccessor<Info> >::setRecord(row, std::move(record));
}
int NestedInfoCollection::getNestedRowsCount(int row, int column) const

@ -1,6 +1,7 @@
#ifndef CSM_WOLRD_RECORD_H
#define CSM_WOLRD_RECORD_H
#include <memory>
#include <stdexcept>
namespace CSMWorld
@ -20,9 +21,9 @@ namespace CSMWorld
virtual ~RecordBase();
virtual RecordBase *clone() const = 0;
virtual std::unique_ptr<RecordBase> clone() const = 0;
virtual RecordBase *modifiedCopy() const = 0;
virtual std::unique_ptr<RecordBase> modifiedCopy() const = 0;
virtual void assign (const RecordBase& record) = 0;
///< Will throw an exception if the types don't match.
@ -45,9 +46,9 @@ namespace CSMWorld
Record(State state,
const ESXRecordT *base = 0, const ESXRecordT *modified = 0);
RecordBase *clone() const override;
std::unique_ptr<RecordBase> clone() const;
RecordBase *modifiedCopy() const override;
std::unique_ptr<RecordBase> modifiedCopy() const;
void assign (const RecordBase& record) override;
@ -85,15 +86,16 @@ namespace CSMWorld
}
template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::modifiedCopy() const
std::unique_ptr<RecordBase> Record<ESXRecordT>::modifiedCopy() const
{
return new Record<ESXRecordT> (State_ModifiedOnly, nullptr, &(this->get()));
return std::make_unique<Record<ESXRecordT> >(
Record<ESXRecordT>(State_ModifiedOnly, nullptr, &(this->get())));
}
template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::clone() const
std::unique_ptr<RecordBase> Record<ESXRecordT>::clone() const
{
return new Record<ESXRecordT> (*this);
return std::make_unique<Record<ESXRecordT> >(Record<ESXRecordT>(*this));
}
template <typename ESXRecordT>

@ -84,8 +84,6 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
int index = getIndex (iter->second);
Record<CellRef> record = getRecord (index);
if (base)
{
removeRows (index, 1);
@ -93,8 +91,9 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
}
else
{
record.mState = RecordBase::State_Deleted;
setRecord (index, record);
std::unique_ptr<Record<CellRef> > record2(new Record<CellRef>(getRecord(index)));
record2->mState = RecordBase::State_Deleted;
setRecord(index, std::move(record2));
}
continue;
@ -105,13 +104,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
// new reference
ref.mId = getNewId();
Record<CellRef> record;
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
std::unique_ptr<Record<CellRef> > record(new Record<CellRef>);
record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
const ESM::RefNum refNum = ref.mRefNum;
std::string refId = ref.mId;
(base ? record.mBase : record.mModified) = std::move(ref);
(base ? record->mBase : record->mModified) = std::move(ref);
appendRecord (record);
appendRecord(std::move(record));
cache.emplace(refNum, std::move(refId));
}
@ -122,11 +121,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
int index = getIndex (ref.mId);
Record<CellRef> record = getRecord (index);
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
(base ? record.mBase : record.mModified) = std::move(ref);
std::unique_ptr<Record<CellRef> > record(new Record<CellRef>(getRecord(index)));
record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
(base ? record->mBase : record->mModified) = std::move(ref);
setRecord (index, record);
setRecord(index, std::move(record));
}
}
}

@ -796,18 +796,19 @@ int CSMWorld::RefIdCollection::searchId (const std::string& id) const
return mData.localToGlobalIndex (localIndex);
}
void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record)
void CSMWorld::RefIdCollection::replace (int index, std::unique_ptr<RecordBase> record)
{
mData.getRecord (mData.globalToLocalIndex (index)).assign (record);
mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release());
}
void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin,
const std::string& destination,
const CSMWorld::UniversalId::Type type)
{
std::unique_ptr<RecordBase> newRecord(mData.getRecord(mData.searchId(origin)).modifiedCopy());
std::unique_ptr<RecordBase> newRecord =
std::move(mData.getRecord(mData.searchId(origin)).modifiedCopy());
mAdapters.find(type)->second->setId(*newRecord, destination);
mData.insertRecord(*newRecord, type, destination);
mData.insertRecord(std::move(newRecord), type, destination);
}
bool CSMWorld::RefIdCollection::touchRecord(const std::string& id)
@ -816,16 +817,16 @@ bool CSMWorld::RefIdCollection::touchRecord(const std::string& id)
return false;
}
void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record,
void CSMWorld::RefIdCollection::appendRecord (std::unique_ptr<RecordBase> record,
UniversalId::Type type)
{
std::string id = findAdapter (type).getId (record);
std::string id = findAdapter (type).getId (*record.get());
int index = mData.getAppendIndex (type);
mData.appendRecord (type, id, false);
mData.getRecord (mData.globalToLocalIndex (index)).assign (record);
mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release());
}
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const

@ -89,12 +89,12 @@ namespace CSMWorld
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
void replace (int index, const RecordBase& record) override;
void replace (int index, std::unique_ptr<RecordBase> record) override;
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
void appendRecord (const RecordBase& record, UniversalId::Type type) override;
void appendRecord (std::unique_ptr<RecordBase> record, UniversalId::Type type) override;
///< If the record type does not match, an exception is thrown.
///
///< \param type Will be ignored, unless the collection supports multiple record types

@ -400,7 +400,7 @@ const CSMWorld::RefIdDataContainer< ESM::Static >& CSMWorld::RefIdData::getStati
return mStatics;
}
void CSMWorld::RefIdData::insertRecord (CSMWorld::RecordBase& record, CSMWorld::UniversalId::Type type, const std::string& id)
void CSMWorld::RefIdData::insertRecord (std::unique_ptr<CSMWorld::RecordBase> record, CSMWorld::UniversalId::Type type, const std::string& id)
{
std::map<UniversalId::Type, RefIdDataContainerBase *>::iterator iter =
mRecordContainers.find (type);
@ -408,7 +408,7 @@ void CSMWorld::RefIdData::insertRecord (CSMWorld::RecordBase& record, CSMWorld::
if (iter==mRecordContainers.end())
throw std::logic_error ("invalid local index type");
iter->second->insertRecord(record);
iter->second->insertRecord(std::move(record));
mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id),
LocalIndex (iter->second->getSize()-1, type)));
@ -420,9 +420,7 @@ void CSMWorld::RefIdData::copyTo (int index, RefIdData& target) const
RefIdDataContainerBase *source = mRecordContainers.find (localIndex.second)->second;
std::string id = source->getId (localIndex.first);
std::unique_ptr<CSMWorld::RecordBase> newRecord (source->getRecord (localIndex.first).modifiedCopy());
target.insertRecord (*newRecord, localIndex.second, id);
target.insertRecord(source->getRecord(localIndex.first).modifiedCopy(),
localIndex.second,
source->getId(localIndex.first));
}

@ -3,6 +3,7 @@
#include <vector>
#include <map>
#include <memory>
#include <components/esm/loadacti.hpp>
#include <components/esm/loadalch.hpp>
@ -51,7 +52,7 @@ namespace CSMWorld
virtual void appendRecord (const std::string& id, bool base) = 0;
virtual void insertRecord (RecordBase& record) = 0;
virtual void insertRecord (std::unique_ptr<RecordBase> record) = 0;
virtual int load (ESM::ESMReader& reader, bool base) = 0;
///< \return index of a loaded record or -1 if no record was loaded
@ -66,7 +67,7 @@ namespace CSMWorld
template<typename RecordT>
struct RefIdDataContainer : public RefIdDataContainerBase
{
std::vector<Record<RecordT> > mContainer;
std::vector<std::unique_ptr<Record<RecordT> > > mContainer;
int getSize() const override;
@ -78,7 +79,7 @@ namespace CSMWorld
void appendRecord (const std::string& id, bool base) override;
void insertRecord (RecordBase& record) override;
void insertRecord (std::unique_ptr<RecordBase> record) override;
int load (ESM::ESMReader& reader, bool base) override;
///< \return index of a loaded record or -1 if no record was loaded
@ -91,10 +92,18 @@ namespace CSMWorld
};
template<typename RecordT>
void RefIdDataContainer<RecordT>::insertRecord(RecordBase& record)
void RefIdDataContainer<RecordT>::insertRecord(std::unique_ptr<RecordBase> record)
{
Record<RecordT>& newRecord = dynamic_cast<Record<RecordT>& >(record);
mContainer.push_back(newRecord);
Record<RecordT> *tmp = dynamic_cast<Record<RecordT>*>(record.get());
if(tmp != nullptr)
{
record.release();
std::unique_ptr<Record<RecordT> > newRecord;
newRecord.reset(tmp);
mContainer.push_back(std::move(newRecord));
}
else
throw std::runtime_error ("invalid record for RefIdDataContainer");
}
template<typename RecordT>
@ -106,33 +115,33 @@ namespace CSMWorld
template<typename RecordT>
const RecordBase& RefIdDataContainer<RecordT>::getRecord (int index) const
{
return mContainer.at (index);
return *mContainer.at (index);
}
template<typename RecordT>
RecordBase& RefIdDataContainer<RecordT>::getRecord (int index)
{
return mContainer.at (index);
return *mContainer.at (index);
}
template<typename RecordT>
unsigned int RefIdDataContainer<RecordT>::getRecordFlags (int index) const
{
return mContainer.at (index).get().mRecordFlags;
return mContainer.at (index)->get().mRecordFlags;
}
template<typename RecordT>
void RefIdDataContainer<RecordT>::appendRecord (const std::string& id, bool base)
{
Record<RecordT> record;
std::unique_ptr<Record<RecordT> > record(new Record<RecordT>);
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
record.mBase.mId = id;
record.mModified.mId = id;
(base ? record.mBase : record.mModified).blank();
record->mBase.mId = id;
record->mModified.mId = id;
(base ? record->mBase : record->mModified).blank();
mContainer.push_back (record);
mContainer.push_back (std::move(record));
}
template<typename RecordT>
@ -147,7 +156,7 @@ namespace CSMWorld
int numRecords = static_cast<int>(mContainer.size());
for (; index < numRecords; ++index)
{
if (Misc::StringUtils::ciEqual(mContainer[index].get().mId, record.mId))
if (Misc::StringUtils::ciEqual(mContainer[index]->get().mId, record.mId))
{
break;
}
@ -165,7 +174,7 @@ namespace CSMWorld
// Flag the record as Deleted even for a base content file.
// RefIdData is responsible for its erasure.
mContainer[index].mState = RecordBase::State_Deleted;
mContainer[index]->mState = RecordBase::State_Deleted;
}
else
{
@ -174,22 +183,22 @@ namespace CSMWorld
appendRecord(record.mId, base);
if (base)
{
mContainer.back().mBase = record;
mContainer.back()->mBase = record;
}
else
{
mContainer.back().mModified = record;
mContainer.back()->mModified = record;
}
}
else if (!base)
{
mContainer[index].setModified(record);
mContainer[index]->setModified(record);
}
else
{
// Overwrite
mContainer[index].setModified(record);
mContainer[index].merge();
mContainer[index]->setModified(record);
mContainer[index]->merge();
}
}
@ -208,13 +217,13 @@ namespace CSMWorld
template<typename RecordT>
std::string RefIdDataContainer<RecordT>::getId (int index) const
{
return mContainer.at (index).get().mId;
return mContainer.at (index)->get().mId;
}
template<typename RecordT>
void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
{
Record<RecordT> record = mContainer.at(index);
const Record<RecordT>& record = *mContainer.at(index);
if (record.isModified() || record.mState == RecordBase::State_Deleted)
{
@ -276,7 +285,7 @@ namespace CSMWorld
void erase (int index, int count);
void insertRecord (CSMWorld::RecordBase& record, CSMWorld::UniversalId::Type type,
void insertRecord (std::unique_ptr<RecordBase> record, CSMWorld::UniversalId::Type type,
const std::string& id);
const RecordBase& getRecord (const LocalIndex& index) const;

Loading…
Cancel
Save