OpenMW
apps/opencs/model/world/refiddata.hpp
Go to the documentation of this file.
00001 #ifndef CSM_WOLRD_REFIDDATA_H
00002 #define CSM_WOLRD_REFIDDATA_H
00003 
00004 #include <vector>
00005 #include <map>
00006 
00007 #include <components/esm/loadacti.hpp>
00008 #include <components/esm/loadalch.hpp>
00009 #include <components/esm/loadappa.hpp>
00010 #include <components/esm/loadarmo.hpp>
00011 #include <components/esm/loadbook.hpp>
00012 #include <components/esm/loadclot.hpp>
00013 #include <components/esm/loadcont.hpp>
00014 #include <components/esm/loadcrea.hpp>
00015 #include <components/esm/loaddoor.hpp>
00016 #include <components/esm/loadingr.hpp>
00017 #include <components/esm/loadlevlist.hpp>
00018 #include <components/esm/loadligh.hpp>
00019 #include <components/esm/loadlock.hpp>
00020 #include <components/esm/loadprob.hpp>
00021 #include <components/esm/loadrepa.hpp>
00022 #include <components/esm/loadstat.hpp>
00023 #include <components/esm/loadweap.hpp>
00024 #include <components/esm/loadnpc.hpp>
00025 #include <components/esm/loadmisc.hpp>
00026 #include <components/esm/esmwriter.hpp>
00027 
00028 #include "record.hpp"
00029 #include "universalid.hpp"
00030 
00031 namespace ESM
00032 {
00033     class ESMReader;
00034 }
00035 
00036 namespace CSMWorld
00037 {
00038     struct RefIdDataContainerBase
00039     {
00040         virtual ~RefIdDataContainerBase();
00041 
00042         virtual int getSize() const = 0;
00043 
00044         virtual const RecordBase& getRecord (int index) const = 0;
00045 
00046         virtual RecordBase& getRecord (int index)= 0;
00047 
00048         virtual void appendRecord (const std::string& id) = 0;
00049 
00050         virtual void load (int index,  ESM::ESMReader& reader, bool base) = 0;
00051 
00052         virtual void erase (int index, int count) = 0;
00053 
00054         virtual std::string getId (int index) const = 0;
00055 
00056         virtual void save (int index, ESM::ESMWriter& writer) const = 0;
00057     };
00058 
00059     template<typename RecordT>
00060     struct RefIdDataContainer : public RefIdDataContainerBase
00061     {
00062         std::vector<Record<RecordT> > mContainer;
00063 
00064         virtual int getSize() const;
00065 
00066         virtual const RecordBase& getRecord (int index) const;
00067 
00068         virtual RecordBase& getRecord (int index);
00069 
00070         virtual void appendRecord (const std::string& id);
00071 
00072         virtual void load (int index,  ESM::ESMReader& reader, bool base);
00073 
00074         virtual void erase (int index, int count);
00075 
00076         virtual std::string getId (int index) const;
00077 
00078         virtual void save (int index, ESM::ESMWriter& writer) const;
00079     };
00080 
00081     template<typename RecordT>
00082     int RefIdDataContainer<RecordT>::getSize() const
00083     {
00084         return static_cast<int> (mContainer.size());
00085     }
00086 
00087     template<typename RecordT>
00088     const RecordBase& RefIdDataContainer<RecordT>::getRecord (int index) const
00089     {
00090         return mContainer.at (index);
00091     }
00092 
00093     template<typename RecordT>
00094     RecordBase& RefIdDataContainer<RecordT>::getRecord (int index)
00095     {
00096         return mContainer.at (index);
00097     }
00098 
00099     template<typename RecordT>
00100     void RefIdDataContainer<RecordT>::appendRecord (const std::string& id)
00101     {
00102         Record<RecordT> record;
00103         record.mModified.mId = id;
00104         record.mModified.blank();
00105         record.mState = RecordBase::State_ModifiedOnly;
00106 
00107         mContainer.push_back (record);
00108     }
00109 
00110     template<typename RecordT>
00111     void RefIdDataContainer<RecordT>::load (int index,  ESM::ESMReader& reader, bool base)
00112     {
00113         (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader);
00114     }
00115 
00116     template<typename RecordT>
00117     void RefIdDataContainer<RecordT>::erase (int index, int count)
00118     {
00119         if (index<0 || index+count>=getSize())
00120             throw std::runtime_error ("invalid RefIdDataContainer index");
00121 
00122         mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count);
00123     }
00124 
00125     template<typename RecordT>
00126     std::string RefIdDataContainer<RecordT>::getId (int index) const
00127     {
00128         return mContainer.at (index).get().mId;
00129     }
00130 
00131     template<typename RecordT>
00132     void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
00133     {
00134         CSMWorld::RecordBase::State state = mContainer.at (index).mState;
00135 
00136         if (state==CSMWorld::RecordBase::State_Modified ||
00137             state==CSMWorld::RecordBase::State_ModifiedOnly)
00138         {
00139             std::string type;
00140             for (int i=0; i<4; ++i)
00142                 type += reinterpret_cast<const char *> (&mContainer.at (index).mModified.sRecordId)[i];
00143 
00144             writer.startRecord (type);
00145             writer.writeHNCString ("NAME", getId (index));
00146             mContainer.at (index).mModified.save (writer);
00147             writer.endRecord (type);
00148         }
00149         else if (state==CSMWorld::RecordBase::State_Deleted)
00150         {
00152         }
00153     }
00154 
00155 
00156     class RefIdData
00157     {
00158         public:
00159 
00160             typedef std::pair<int, UniversalId::Type> LocalIndex;
00161 
00162         private:
00163 
00164             RefIdDataContainer<ESM::Activator> mActivators;
00165             RefIdDataContainer<ESM::Potion> mPotions;
00166             RefIdDataContainer<ESM::Apparatus> mApparati;
00167             RefIdDataContainer<ESM::Armor> mArmors;
00168             RefIdDataContainer<ESM::Book> mBooks;
00169             RefIdDataContainer<ESM::Clothing> mClothing;
00170             RefIdDataContainer<ESM::Container> mContainers;
00171             RefIdDataContainer<ESM::Creature> mCreatures;
00172             RefIdDataContainer<ESM::Door> mDoors;
00173             RefIdDataContainer<ESM::Ingredient> mIngredients;
00174             RefIdDataContainer<ESM::CreatureLevList> mCreatureLevelledLists;
00175             RefIdDataContainer<ESM::ItemLevList> mItemLevelledLists;
00176             RefIdDataContainer<ESM::Light> mLights;
00177             RefIdDataContainer<ESM::Lockpick> mLockpicks;
00178             RefIdDataContainer<ESM::Miscellaneous> mMiscellaneous;
00179             RefIdDataContainer<ESM::NPC> mNpcs;
00180             RefIdDataContainer<ESM::Probe> mProbes;
00181             RefIdDataContainer<ESM::Repair> mRepairs;
00182             RefIdDataContainer<ESM::Static> mStatics;
00183             RefIdDataContainer<ESM::Weapon> mWeapons;
00184 
00185             std::map<std::string, LocalIndex> mIndex;
00186 
00187             std::map<UniversalId::Type, RefIdDataContainerBase *> mRecordContainers;
00188 
00189             void erase (const LocalIndex& index, int count);
00191 
00192         public:
00193 
00194             RefIdData();
00195 
00196             LocalIndex globalToLocalIndex (int index) const;
00197 
00198             int localToGlobalIndex (const LocalIndex& index) const;
00199 
00200             LocalIndex searchId (const std::string& id) const;
00201 
00202             void erase (int index, int count);
00203 
00204             const RecordBase& getRecord (const LocalIndex& index) const;
00205 
00206             RecordBase& getRecord (const LocalIndex& index);
00207 
00208             void appendRecord (UniversalId::Type type, const std::string& id);
00209 
00210             int getAppendIndex (UniversalId::Type type) const;
00211 
00212             void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
00213 
00214             int getSize() const;
00215 
00216             std::vector<std::string> getIds (bool listDeleted = true) const;
00220 
00221             void save (int index, ESM::ESMWriter& writer) const;
00222     };
00223 }
00224 
00225 #endif