2012-11-26 12:29:22 +01:00
|
|
|
#ifndef CSM_WOLRD_IDCOLLECTION_H
|
|
|
|
#define CSM_WOLRD_IDCOLLECTION_H
|
|
|
|
|
2013-02-07 12:52:01 +01:00
|
|
|
#include <components/esm/esmreader.hpp>
|
|
|
|
|
2013-06-17 14:28:09 +02:00
|
|
|
#include "collection.hpp"
|
2013-02-07 12:52:01 +01:00
|
|
|
|
2012-11-26 12:29:22 +01:00
|
|
|
namespace CSMWorld
|
|
|
|
{
|
2013-06-17 14:16:26 +02:00
|
|
|
/// \brief Single type collection of top level records
|
|
|
|
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
|
|
|
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2013-10-20 15:48:39 +02:00
|
|
|
void load (ESM::ESMReader& reader, bool base);
|
2013-10-20 17:13:31 +02:00
|
|
|
|
2014-06-30 12:35:34 +02:00
|
|
|
/// \param index Index at which the record can be found.
|
|
|
|
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
|
|
|
|
/// does not have an index
|
|
|
|
void load (const ESXRecordT& record, bool base, int index = -2);
|
2013-10-21 15:38:13 +02:00
|
|
|
|
|
|
|
bool tryDelete (const std::string& id);
|
|
|
|
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
|
|
|
|
///
|
|
|
|
/// \return Has the ID been deleted?
|
2013-06-17 14:16:26 +02:00
|
|
|
};
|
|
|
|
|
2013-04-16 12:12:04 +02:00
|
|
|
template<typename ESXRecordT, typename IdAccessorT>
|
2013-10-20 15:48:39 +02:00
|
|
|
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
2013-02-07 12:52:01 +01:00
|
|
|
{
|
|
|
|
std::string id = reader.getHNOString ("NAME");
|
|
|
|
|
2013-02-07 13:26:00 +01:00
|
|
|
if (reader.isNextSub ("DELE"))
|
2013-02-07 12:52:01 +01:00
|
|
|
{
|
2013-06-17 14:16:26 +02:00
|
|
|
int index = Collection<ESXRecordT, IdAccessorT>::searchId (id);
|
2013-04-14 17:04:55 +02:00
|
|
|
|
2013-02-07 13:26:00 +01:00
|
|
|
reader.skipRecord();
|
2013-02-07 12:52:01 +01:00
|
|
|
|
2013-02-07 13:26:00 +01:00
|
|
|
if (index==-1)
|
|
|
|
{
|
|
|
|
// deleting a record that does not exist
|
|
|
|
|
|
|
|
// ignore it for now
|
|
|
|
|
|
|
|
/// \todo report the problem to the user
|
|
|
|
}
|
|
|
|
else if (base)
|
|
|
|
{
|
2013-06-17 14:16:26 +02:00
|
|
|
Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1);
|
2013-02-07 13:26:00 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-17 14:16:26 +02:00
|
|
|
Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
|
2013-06-17 13:49:32 +02:00
|
|
|
record.mState = RecordBase::State_Deleted;
|
2013-07-12 08:33:02 +04:00
|
|
|
this->setRecord (index, record);
|
2013-02-07 13:26:00 +01:00
|
|
|
}
|
2013-02-07 12:52:01 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-07 13:26:00 +01:00
|
|
|
ESXRecordT record;
|
2014-06-30 12:35:34 +02:00
|
|
|
|
|
|
|
int index = this->searchId (id);
|
|
|
|
|
|
|
|
if (index==-1)
|
|
|
|
IdAccessorT().getId (record) = id;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
record = this->getRecord (index).get();
|
|
|
|
}
|
|
|
|
|
2013-02-07 13:26:00 +01:00
|
|
|
record.load (reader);
|
|
|
|
|
2014-06-30 12:35:34 +02:00
|
|
|
load (record, base, index);
|
2013-10-20 17:13:31 +02:00
|
|
|
}
|
|
|
|
}
|
2013-04-14 17:04:55 +02:00
|
|
|
|
2013-10-20 17:13:31 +02:00
|
|
|
template<typename ESXRecordT, typename IdAccessorT>
|
2014-06-30 12:35:34 +02:00
|
|
|
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
|
|
|
|
int index)
|
2013-10-20 17:13:31 +02:00
|
|
|
{
|
2014-06-30 12:35:34 +02:00
|
|
|
if (index==-2)
|
|
|
|
index = this->searchId (IdAccessorT().getId (record));
|
2013-02-07 12:52:01 +01:00
|
|
|
|
2013-10-20 17:13:31 +02:00
|
|
|
if (index==-1)
|
|
|
|
{
|
|
|
|
// new record
|
|
|
|
Record<ESXRecordT> record2;
|
|
|
|
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
|
|
|
(base ? record2.mBase : record2.mModified) = record;
|
|
|
|
|
|
|
|
this->appendRecord (record2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// old record
|
|
|
|
Record<ESXRecordT> record2 = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
|
2013-02-07 13:26:00 +01:00
|
|
|
|
2013-10-20 17:13:31 +02:00
|
|
|
if (base)
|
|
|
|
record2.mBase = record;
|
|
|
|
else
|
|
|
|
record2.setModified (record);
|
2013-06-17 13:49:32 +02:00
|
|
|
|
2013-10-20 17:13:31 +02:00
|
|
|
this->setRecord (index, record2);
|
2013-02-07 12:52:01 +01:00
|
|
|
}
|
|
|
|
}
|
2013-10-21 15:38:13 +02:00
|
|
|
|
|
|
|
template<typename ESXRecordT, typename IdAccessorT>
|
|
|
|
bool IdCollection<ESXRecordT, IdAccessorT>::tryDelete (const std::string& id)
|
|
|
|
{
|
|
|
|
int index = this->searchId (id);
|
|
|
|
|
|
|
|
if (index==-1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
|
|
|
|
|
|
|
|
if (record.isDeleted())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (record.mState==RecordBase::State_ModifiedOnly)
|
|
|
|
{
|
|
|
|
Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
record.mState = RecordBase::State_Deleted;
|
2013-10-25 19:23:03 -05:00
|
|
|
this->setRecord (index, record);
|
2013-10-21 15:38:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-11-26 12:29:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|