OpenMW
|
00001 #ifndef CSM_WOLRD_RECORD_H 00002 #define CSM_WOLRD_RECORD_H 00003 00004 #include <stdexcept> 00005 00006 namespace CSMWorld 00007 { 00008 struct RecordBase 00009 { 00010 enum State 00011 { 00012 State_BaseOnly = 0, // defined in base only 00013 State_Modified = 1, // exists in base, but has been modified 00014 State_ModifiedOnly = 2, // newly created in modified 00015 State_Deleted = 3, // exists in base, but has been deleted 00016 State_Erased = 4 // does not exist at all (we mostly treat that the same way as deleted) 00017 }; 00018 00019 State mState; 00020 00021 virtual ~RecordBase(); 00022 00023 virtual RecordBase *clone() const = 0; 00024 00025 virtual void assign (const RecordBase& record) = 0; 00027 00028 bool isDeleted() const; 00029 00030 bool isErased() const; 00031 00032 bool isModified() const; 00033 }; 00034 00035 template <typename ESXRecordT> 00036 struct Record : public RecordBase 00037 { 00038 ESXRecordT mBase; 00039 ESXRecordT mModified; 00040 00041 virtual RecordBase *clone() const; 00042 00043 virtual void assign (const RecordBase& record); 00044 00045 const ESXRecordT& get() const; 00047 00048 ESXRecordT& get(); 00050 00051 const ESXRecordT& getBase() const; 00053 00054 void setModified (const ESXRecordT& modified); 00056 00057 void merge(); 00059 }; 00060 00061 template <typename ESXRecordT> 00062 RecordBase *Record<ESXRecordT>::clone() const 00063 { 00064 return new Record<ESXRecordT> (*this); 00065 } 00066 00067 template <typename ESXRecordT> 00068 void Record<ESXRecordT>::assign (const RecordBase& record) 00069 { 00070 *this = dynamic_cast<const Record<ESXRecordT>& > (record); 00071 } 00072 00073 template <typename ESXRecordT> 00074 const ESXRecordT& Record<ESXRecordT>::get() const 00075 { 00076 if (mState==State_Erased) 00077 throw std::logic_error ("attempt to access a deleted record"); 00078 00079 return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; 00080 } 00081 00082 template <typename ESXRecordT> 00083 ESXRecordT& Record<ESXRecordT>::get() 00084 { 00085 if (mState==State_Erased) 00086 throw std::logic_error ("attempt to access a deleted record"); 00087 00088 return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; 00089 } 00090 00091 template <typename ESXRecordT> 00092 const ESXRecordT& Record<ESXRecordT>::getBase() const 00093 { 00094 if (mState==State_Erased) 00095 throw std::logic_error ("attempt to access a deleted record"); 00096 00097 return mState==State_ModifiedOnly ? mModified : mBase; 00098 } 00099 00100 template <typename ESXRecordT> 00101 void Record<ESXRecordT>::setModified (const ESXRecordT& modified) 00102 { 00103 if (mState==State_Erased) 00104 throw std::logic_error ("attempt to modify a deleted record"); 00105 00106 mModified = modified; 00107 00108 if (mState!=State_ModifiedOnly) 00109 mState = State_Modified; 00110 } 00111 00112 template <typename ESXRecordT> 00113 void Record<ESXRecordT>::merge() 00114 { 00115 if (isModified()) 00116 { 00117 mBase = mModified; 00118 mState = State_BaseOnly; 00119 } 00120 else if (mState==State_Deleted) 00121 { 00122 mState = State_Erased; 00123 } 00124 } 00125 } 00126 00127 #endif