forked from mirror/openmw-tes3mp
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.1 KiB
C++
160 lines
4.1 KiB
C++
#ifndef CSM_WOLRD_RECORD_H
|
|
#define CSM_WOLRD_RECORD_H
|
|
|
|
#include <stdexcept>
|
|
|
|
namespace CSMWorld
|
|
{
|
|
struct RecordBase
|
|
{
|
|
enum State
|
|
{
|
|
State_BaseOnly = 0, // defined in base only
|
|
State_Modified = 1, // exists in base, but has been modified
|
|
State_ModifiedOnly = 2, // newly created in modified
|
|
State_Deleted = 3, // exists in base, but has been deleted
|
|
State_Erased = 4 // does not exist at all (we mostly treat that the same way as deleted)
|
|
};
|
|
|
|
State mState;
|
|
|
|
virtual ~RecordBase();
|
|
|
|
virtual RecordBase *clone() const = 0;
|
|
|
|
virtual RecordBase *modifiedCopy() const = 0;
|
|
|
|
virtual void assign (const RecordBase& record) = 0;
|
|
///< Will throw an exception if the types don't match.
|
|
|
|
bool isDeleted() const;
|
|
|
|
bool isErased() const;
|
|
|
|
bool isModified() const;
|
|
};
|
|
|
|
template <typename ESXRecordT>
|
|
struct Record : public RecordBase
|
|
{
|
|
ESXRecordT mBase;
|
|
ESXRecordT mModified;
|
|
|
|
Record();
|
|
|
|
Record(State state,
|
|
const ESXRecordT *base = 0, const ESXRecordT *modified = 0);
|
|
|
|
virtual RecordBase *clone() const;
|
|
|
|
virtual RecordBase *modifiedCopy() const;
|
|
|
|
virtual void assign (const RecordBase& record);
|
|
|
|
const ESXRecordT& get() const;
|
|
///< Throws an exception, if the record is deleted.
|
|
|
|
ESXRecordT& get();
|
|
///< Throws an exception, if the record is deleted.
|
|
|
|
const ESXRecordT& getBase() const;
|
|
///< Throws an exception, if the record is deleted. Returns modified, if there is no base.
|
|
|
|
void setModified (const ESXRecordT& modified);
|
|
///< Throws an exception, if the record is deleted.
|
|
|
|
void merge();
|
|
///< Merge modified into base.
|
|
};
|
|
|
|
template <typename ESXRecordT>
|
|
Record<ESXRecordT>::Record()
|
|
: mBase(), mModified()
|
|
{ }
|
|
|
|
template <typename ESXRecordT>
|
|
Record<ESXRecordT>::Record(State state, const ESXRecordT *base, const ESXRecordT *modified)
|
|
{
|
|
if(base)
|
|
mBase = *base;
|
|
|
|
if(modified)
|
|
mModified = *modified;
|
|
|
|
this->mState = state;
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
RecordBase *Record<ESXRecordT>::modifiedCopy() const
|
|
{
|
|
return new Record<ESXRecordT> (State_ModifiedOnly, 0, &(this->get()));
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
RecordBase *Record<ESXRecordT>::clone() const
|
|
{
|
|
return new Record<ESXRecordT> (*this);
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
void Record<ESXRecordT>::assign (const RecordBase& record)
|
|
{
|
|
*this = dynamic_cast<const Record<ESXRecordT>& > (record);
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
const ESXRecordT& Record<ESXRecordT>::get() const
|
|
{
|
|
if (mState==State_Erased)
|
|
throw std::logic_error ("attempt to access a deleted record");
|
|
|
|
return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
ESXRecordT& Record<ESXRecordT>::get()
|
|
{
|
|
if (mState==State_Erased)
|
|
throw std::logic_error ("attempt to access a deleted record");
|
|
|
|
return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
const ESXRecordT& Record<ESXRecordT>::getBase() const
|
|
{
|
|
if (mState==State_Erased)
|
|
throw std::logic_error ("attempt to access a deleted record");
|
|
|
|
return mState==State_ModifiedOnly ? mModified : mBase;
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
void Record<ESXRecordT>::setModified (const ESXRecordT& modified)
|
|
{
|
|
if (mState==State_Erased)
|
|
throw std::logic_error ("attempt to modify a deleted record");
|
|
|
|
mModified = modified;
|
|
|
|
if (mState!=State_ModifiedOnly)
|
|
mState = State_Modified;
|
|
}
|
|
|
|
template <typename ESXRecordT>
|
|
void Record<ESXRecordT>::merge()
|
|
{
|
|
if (isModified())
|
|
{
|
|
mBase = mModified;
|
|
mState = State_BaseOnly;
|
|
}
|
|
else if (mState==State_Deleted)
|
|
{
|
|
mState = State_Erased;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|