OpenMW
apps/opencs/model/world/idcollection.hpp
Go to the documentation of this file.
00001 #ifndef CSM_WOLRD_IDCOLLECTION_H
00002 #define CSM_WOLRD_IDCOLLECTION_H
00003 
00004 #include <components/esm/esmreader.hpp>
00005 
00006 #include "collection.hpp"
00007 
00008 namespace CSMWorld
00009 {
00011     template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
00012     class IdCollection : public Collection<ESXRecordT, IdAccessorT>
00013     {
00014         public:
00015 
00016             void load (ESM::ESMReader& reader, bool base);
00017 
00018             void load (const ESXRecordT& record, bool base);
00019 
00020             bool tryDelete (const std::string& id);
00024     };
00025 
00026     template<typename ESXRecordT, typename IdAccessorT>
00027     void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
00028     {
00029         std::string id = reader.getHNOString ("NAME");
00030 
00031         if (reader.isNextSub ("DELE"))
00032         {
00033             int index = Collection<ESXRecordT, IdAccessorT>::searchId (id);
00034 
00035             reader.skipRecord();
00036 
00037             if (index==-1)
00038             {
00039                 // deleting a record that does not exist
00040 
00041                 // ignore it for now
00042 
00044             }
00045             else if (base)
00046             {
00047                 Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1);
00048             }
00049             else
00050             {
00051                 Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
00052                 record.mState = RecordBase::State_Deleted;
00053                 this->setRecord (index, record);
00054             }
00055         }
00056         else
00057         {
00058             ESXRecordT record;
00059             IdAccessorT().getId (record) = id;
00060             record.load (reader);
00061 
00062             load (record, base);
00063         }
00064     }
00065 
00066     template<typename ESXRecordT, typename IdAccessorT>
00067     void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base)
00068     {
00069         int index = this->searchId (IdAccessorT().getId (record));
00070 
00071         if (index==-1)
00072         {
00073             // new record
00074             Record<ESXRecordT> record2;
00075             record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
00076             (base ? record2.mBase : record2.mModified) = record;
00077 
00078             this->appendRecord (record2);
00079         }
00080         else
00081         {
00082             // old record
00083             Record<ESXRecordT> record2 = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
00084 
00085             if (base)
00086                 record2.mBase = record;
00087             else
00088                 record2.setModified (record);
00089 
00090             this->setRecord (index, record2);
00091         }
00092     }
00093 
00094     template<typename ESXRecordT, typename IdAccessorT>
00095     bool IdCollection<ESXRecordT, IdAccessorT>::tryDelete (const std::string& id)
00096     {
00097         int index = this->searchId (id);
00098 
00099         if (index==-1)
00100             return false;
00101 
00102         Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
00103 
00104         if (record.isDeleted())
00105             return false;
00106 
00107         if (record.mState==RecordBase::State_ModifiedOnly)
00108         {
00109             Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1);
00110         }
00111         else
00112         {
00113             record.mState = RecordBase::State_Deleted;
00114             this->setRecord (index, record);
00115         }
00116 
00117         return true;
00118     }
00119 }
00120 
00121 #endif