OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
refiddata.hpp
Go to the documentation of this file.
1 #ifndef CSM_WOLRD_REFIDDATA_H
2 #define CSM_WOLRD_REFIDDATA_H
3 
4 #include <vector>
5 #include <map>
6 
27 
29 
30 #include "record.hpp"
31 #include "universalid.hpp"
32 
33 namespace ESM
34 {
35  class ESMReader;
36 }
37 
38 namespace CSMWorld
39 {
41  {
42  virtual ~RefIdDataContainerBase();
43 
44  virtual int getSize() const = 0;
45 
46  virtual const RecordBase& getRecord (int index) const = 0;
47 
48  virtual RecordBase& getRecord (int index)= 0;
49 
50  virtual void appendRecord (const std::string& id, bool base) = 0;
51 
52  virtual void insertRecord (RecordBase& record) = 0;
53 
54  virtual int load (ESM::ESMReader& reader, bool base) = 0;
56 
57  virtual void erase (int index, int count) = 0;
58 
59  virtual std::string getId (int index) const = 0;
60 
61  virtual void save (int index, ESM::ESMWriter& writer) const = 0;
62  };
63 
64  template<typename RecordT>
66  {
67  std::vector<Record<RecordT> > mContainer;
68 
69  virtual int getSize() const;
70 
71  virtual const RecordBase& getRecord (int index) const;
72 
73  virtual RecordBase& getRecord (int index);
74 
75  virtual void appendRecord (const std::string& id, bool base);
76 
77  virtual void insertRecord (RecordBase& record);
78 
79  virtual int load (ESM::ESMReader& reader, bool base);
81 
82  virtual void erase (int index, int count);
83 
84  virtual std::string getId (int index) const;
85 
86  virtual void save (int index, ESM::ESMWriter& writer) const;
87  };
88 
89  template<typename RecordT>
91  {
92  Record<RecordT>& newRecord = dynamic_cast<Record<RecordT>& >(record);
93  mContainer.push_back(newRecord);
94  }
95 
96  template<typename RecordT>
98  {
99  return static_cast<int> (mContainer.size());
100  }
101 
102  template<typename RecordT>
104  {
105  return mContainer.at (index);
106  }
107 
108  template<typename RecordT>
110  {
111  return mContainer.at (index);
112  }
113 
114  template<typename RecordT>
115  void RefIdDataContainer<RecordT>::appendRecord (const std::string& id, bool base)
116  {
117  Record<RecordT> record;
118 
120 
121  record.mBase.mId = id;
122  record.mModified.mId = id;
123  (base ? record.mBase : record.mModified).blank();
124 
125  mContainer.push_back (record);
126  }
127 
128  template<typename RecordT>
130  {
131  RecordT record;
132  bool isDeleted = false;
133 
134  record.load(reader, isDeleted);
135 
136  int index = 0;
137  int numRecords = static_cast<int>(mContainer.size());
138  for (; index < numRecords; ++index)
139  {
140  if (Misc::StringUtils::ciEqual(mContainer[index].get().mId, record.mId))
141  {
142  break;
143  }
144  }
145 
146  if (isDeleted)
147  {
148  if (index == numRecords)
149  {
150  // deleting a record that does not exist
151  // ignore it for now
153  return -1;
154  }
155 
156  // Flag the record as Deleted even for a base content file.
157  // RefIdData is responsible for its erasure.
158  mContainer[index].mState = RecordBase::State_Deleted;
159  }
160  else
161  {
162  if (index == numRecords)
163  {
164  appendRecord(record.mId, base);
165  if (base)
166  {
167  mContainer.back().mBase = record;
168  }
169  else
170  {
171  mContainer.back().mModified = record;
172  }
173  }
174  else if (!base)
175  {
176  mContainer[index].setModified(record);
177  }
178  else
179  {
180  // Overwrite
181  mContainer[index].setModified(record);
182  mContainer[index].merge();
183  }
184  }
185 
186  return index;
187  }
188 
189  template<typename RecordT>
190  void RefIdDataContainer<RecordT>::erase (int index, int count)
191  {
192  if (index<0 || index+count>getSize())
193  throw std::runtime_error ("invalid RefIdDataContainer index");
194 
195  mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count);
196  }
197 
198  template<typename RecordT>
199  std::string RefIdDataContainer<RecordT>::getId (int index) const
200  {
201  return mContainer.at (index).get().mId;
202  }
203 
204  template<typename RecordT>
205  void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
206  {
207  Record<RecordT> record = mContainer.at(index);
208 
209  if (record.isModified() || record.mState == RecordBase::State_Deleted)
210  {
211  RecordT esmRecord = record.get();
212  writer.startRecord(esmRecord.sRecordId);
213  esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
214  writer.endRecord(esmRecord.sRecordId);
215  }
216  }
217 
218 
219  class RefIdData
220  {
221  public:
222 
223  typedef std::pair<int, UniversalId::Type> LocalIndex;
224 
225  private:
226 
247 
248  std::map<std::string, LocalIndex> mIndex;
249 
250  std::map<UniversalId::Type, RefIdDataContainerBase *> mRecordContainers;
251 
252  void erase (const LocalIndex& index, int count);
254 
255  std::string getRecordId(const LocalIndex &index) const;
256 
257  public:
258 
259  RefIdData();
260 
261  LocalIndex globalToLocalIndex (int index) const;
262 
263  int localToGlobalIndex (const LocalIndex& index) const;
264 
265  LocalIndex searchId (const std::string& id) const;
266 
267  void erase (int index, int count);
268 
270  const std::string& id);
271 
272  const RecordBase& getRecord (const LocalIndex& index) const;
273 
274  RecordBase& getRecord (const LocalIndex& index);
275 
276  void appendRecord (UniversalId::Type type, const std::string& id, bool base);
277 
278  int getAppendIndex (UniversalId::Type type) const;
279 
280  void load (ESM::ESMReader& reader, bool base, UniversalId::Type type);
281 
282  int getSize() const;
283 
284  std::vector<std::string> getIds (bool listDeleted = true) const;
288 
289  void save (int index, ESM::ESMWriter& writer) const;
290 
291  //RECORD CONTAINERS ACCESS METHODS
307  const RefIdDataContainer<ESM::NPC>& getNPCs() const;
312 
313  void copyTo (int index, RefIdData& target) const;
314  };
315 }
316 
317 #endif
const RefIdDataContainer< ESM::CreatureLevList > & getCreatureLevelledLists() const
Definition: refiddata.cpp:320
virtual void appendRecord(const std::string &id, bool base)=0
virtual void erase(int index, int count)=0
virtual int load(ESM::ESMReader &reader, bool base)=0
const RefIdDataContainer< ESM::Container > & getContainers() const
Definition: refiddata.cpp:300
static bool ciEqual(const std::string &x, const std::string &y)
Definition: stringops.hpp:62
std::string getRecordId(const LocalIndex &index) const
Definition: refiddata.cpp:9
Definition: refiddata.hpp:65
std::map< UniversalId::Type, RefIdDataContainerBase * > mRecordContainers
Definition: refiddata.hpp:250
RefIdDataContainer< ESM::Creature > mCreatures
Definition: refiddata.hpp:234
State mState
Definition: record.hpp:19
Definition: esmreader.hpp:21
void startRecord(const std::string &name, uint32_t flags=0)
Definition: esmwriter.cpp:89
virtual int getSize() const
Definition: refiddata.hpp:97
RefIdDataContainer< ESM::Apparatus > mApparati
Definition: refiddata.hpp:229
Type
Definition: universalid.hpp:40
const RefIdDataContainer< ESM::Light > & getLights() const
Definition: refiddata.cpp:330
const RefIdDataContainer< ESM::Repair > & getRepairs() const
Definition: refiddata.cpp:360
Definition: refiddata.hpp:219
void copyTo(int index, RefIdData &target) const
Definition: refiddata.cpp:384
const RefIdDataContainer< ESM::Clothing > & getClothing() const
Definition: refiddata.cpp:295
const RefIdDataContainer< ESM::NPC > & getNPCs() const
Definition: refiddata.cpp:345
void appendRecord(UniversalId::Type type, const std::string &id, bool base)
Definition: refiddata.cpp:144
const RefIdDataContainer< ESM::Static > & getStatics() const
Definition: refiddata.cpp:365
RefIdDataContainer< ESM::Lockpick > mLockpicks
Definition: refiddata.hpp:240
RefIdDataContainer< ESM::Weapon > mWeapons
Definition: refiddata.hpp:246
const RefIdDataContainer< ESM::ItemLevList > & getItemLevelledList() const
Definition: refiddata.cpp:325
std::vector< std::string > getIds(bool listDeleted=true) const
Definition: refiddata.cpp:235
int getAppendIndex(UniversalId::Type type) const
Definition: refiddata.cpp:158
LocalIndex searchId(const std::string &id) const
Definition: refiddata.cpp:77
const RefIdDataContainer< ESM::Weapon > & getWeapons() const
Definition: refiddata.cpp:350
RefIdDataContainer< ESM::CreatureLevList > mCreatureLevelledLists
Definition: refiddata.hpp:237
void load(ESM::ESMReader &reader, bool base, UniversalId::Type type)
Definition: refiddata.cpp:174
std::map< std::string, LocalIndex > mIndex
Definition: refiddata.hpp:248
RefIdDataContainer< ESM::Door > mDoors
Definition: refiddata.hpp:235
const RefIdDataContainer< ESM::Lockpick > & getLocpicks() const
Definition: refiddata.cpp:335
LocalIndex globalToLocalIndex(int index) const
Definition: refiddata.cpp:45
const RefIdDataContainer< ESM::Creature > & getCreatures() const
Definition: refiddata.cpp:305
const RecordBase & getRecord(const LocalIndex &index) const
Definition: refiddata.cpp:122
const RefIdDataContainer< ESM::Activator > & getActivators() const
Definition: refiddata.cpp:275
Definition: esmwriter.hpp:17
ESXRecordT mBase
Definition: record.hpp:40
virtual std::string getId(int index) const
Definition: refiddata.hpp:199
RefIdDataContainer< ESM::Ingredient > mIngredients
Definition: refiddata.hpp:236
RefIdDataContainer< ESM::Container > mContainers
Definition: refiddata.hpp:233
RefIdDataContainer< ESM::Potion > mPotions
Definition: refiddata.hpp:228
void erase(const LocalIndex &index, int count)
Must not spill over into another type.
Definition: refiddata.cpp:197
RefIdDataContainer< ESM::NPC > mNpcs
Definition: refiddata.hpp:242
virtual const RecordBase & getRecord(int index) const =0
const RefIdDataContainer< ESM::Door > & getDoors() const
Definition: refiddata.cpp:310
RefIdDataContainer< ESM::Clothing > mClothing
Definition: refiddata.hpp:232
RefIdData()
Definition: refiddata.cpp:20
const RefIdDataContainer< ESM::Armor > & getArmors() const
Definition: refiddata.cpp:290
Definition: record.hpp:12
Definition: record.hpp:15
RefIdDataContainer< ESM::Armor > mArmors
Definition: refiddata.hpp:230
const RefIdDataContainer< ESM::Miscellaneous > & getMiscellaneous() const
Definition: refiddata.cpp:340
virtual void save(int index, ESM::ESMWriter &writer) const
Definition: refiddata.hpp:205
ESXRecordT mModified
Definition: record.hpp:41
void save(int index, ESM::ESMWriter &writer) const
Definition: refiddata.cpp:257
const RefIdDataContainer< ESM::Ingredient > & getIngredients() const
Definition: refiddata.cpp:315
virtual const RecordBase & getRecord(int index) const
Definition: refiddata.hpp:103
const RefIdDataContainer< ESM::Probe > & getProbes() const
Definition: refiddata.cpp:355
const ESXRecordT & get() const
Throws an exception, if the record is deleted.
Definition: record.hpp:106
virtual void save(int index, ESM::ESMWriter &writer) const =0
const RefIdDataContainer< ESM::Apparatus > & getApparati() const
Definition: refiddata.cpp:285
virtual void insertRecord(RecordBase &record)
Definition: refiddata.hpp:90
virtual int getSize() const =0
Definition: refiddata.hpp:40
int getSize() const
Definition: refiddata.cpp:230
virtual void appendRecord(const std::string &id, bool base)
Definition: refiddata.hpp:115
Definition: record.hpp:8
RefIdDataContainer< ESM::ItemLevList > mItemLevelledLists
Definition: refiddata.hpp:238
void endRecord(const std::string &name)
Definition: esmwriter.cpp:132
RefIdDataContainer< ESM::Book > mBooks
Definition: refiddata.hpp:231
void insertRecord(CSMWorld::RecordBase &record, CSMWorld::UniversalId::Type type, const std::string &id)
Definition: refiddata.cpp:370
RefIdDataContainer< ESM::Static > mStatics
Definition: refiddata.hpp:245
virtual std::string getId(int index) const =0
virtual int load(ESM::ESMReader &reader, bool base)
Definition: refiddata.hpp:129
RefIdDataContainer< ESM::Activator > mActivators
Definition: refiddata.hpp:227
virtual void insertRecord(RecordBase &record)=0
RefIdDataContainer< ESM::Repair > mRepairs
Definition: refiddata.hpp:244
const RefIdDataContainer< ESM::Book > & getBooks() const
Definition: refiddata.cpp:270
virtual void erase(int index, int count)
Definition: refiddata.hpp:190
RefIdDataContainer< ESM::Light > mLights
Definition: refiddata.hpp:239
bool isModified() const
Definition: record.cpp:17
std::pair< int, UniversalId::Type > LocalIndex
Definition: refiddata.hpp:223
RefIdDataContainer< ESM::Miscellaneous > mMiscellaneous
Definition: refiddata.hpp:241
const RefIdDataContainer< ESM::Potion > & getPotions() const
Definition: refiddata.cpp:280
std::vector< Record< RecordT > > mContainer
Definition: refiddata.hpp:67
virtual ~RefIdDataContainerBase()
Definition: refiddata.cpp:6
RefIdDataContainer< ESM::Probe > mProbes
Definition: refiddata.hpp:243
int localToGlobalIndex(const LocalIndex &index) const
Definition: refiddata.cpp:59