OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
esmstore.hpp
Go to the documentation of this file.
1 #ifndef OPENMW_MWWORLD_ESMSTORE_H
2 #define OPENMW_MWWORLD_ESMSTORE_H
3 
4 #include <sstream>
5 #include <stdexcept>
6 
8 #include "store.hpp"
9 
10 namespace Loading
11 {
12  class Listener;
13 }
14 
15 namespace MWWorld
16 {
17  class ESMStore
18  {
52 
55 
56  // Lists that need special rules
61 
64 
65  // Special entry which is hardcoded and not loaded from an ESM
67 
68  // Lookup of all IDs. Makes looking up references faster. Just
69  // maps the id name to the record type.
70  std::map<std::string, int> mIds;
71  std::map<int, StoreBase *> mStores;
72 
74 
75  unsigned int mDynamicCount;
76 
78  void validate();
79 
80  public:
82  typedef std::map<int, StoreBase *>::const_iterator iterator;
83 
84  iterator begin() const {
85  return mStores.begin();
86  }
87 
88  iterator end() const {
89  return mStores.end();
90  }
91 
94  int find(const std::string &id) const
95  {
96  std::map<std::string, int>::const_iterator it = mIds.find(id);
97  if (it == mIds.end()) {
98  return 0;
99  }
100  return it->second;
101  }
102 
104  : mDynamicCount(0)
105  {
145 
147  }
148 
149  void clearDynamic ()
150  {
151  for (std::map<int, StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it)
152  it->second->clearDynamic();
153 
155  }
156 
158  {
159  mPlayerTemplate = *mNpcs.find("player");
162  }
163 
164  void load(ESM::ESMReader &esm, Loading::Listener* listener);
165 
166  template <class T>
167  const Store<T> &get() const {
168  throw std::runtime_error("Storage for this type not exist");
169  }
170 
172  template <class T>
173  const T *insert(const T &x) {
174  std::ostringstream id;
175  id << "$dynamic" << mDynamicCount++;
176 
177  Store<T> &store = const_cast<Store<T> &>(get<T>());
178  if (store.search(id.str()) != 0) {
179  std::ostringstream msg;
180  msg << "Try to override existing record '" << id.str() << "'";
181  throw std::runtime_error(msg.str());
182  }
183  T record = x;
184 
185  record.mId = id.str();
186 
187  T *ptr = store.insert(record);
188  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
189  if (it->second == &store) {
190  mIds[ptr->mId] = it->first;
191  }
192  }
193  return ptr;
194  }
195 
197  template <class T>
198  const T *overrideRecord(const T &x) {
199  Store<T> &store = const_cast<Store<T> &>(get<T>());
200 
201  T *ptr = store.insert(x);
202  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
203  if (it->second == &store) {
204  mIds[ptr->mId] = it->first;
205  }
206  }
207  return ptr;
208  }
209 
210  template <class T>
211  const T *insertStatic(const T &x) {
212  std::ostringstream id;
213  id << "$dynamic" << mDynamicCount++;
214 
215  Store<T> &store = const_cast<Store<T> &>(get<T>());
216  if (store.search(id.str()) != 0) {
217  std::ostringstream msg;
218  msg << "Try to override existing record '" << id.str() << "'";
219  throw std::runtime_error(msg.str());
220  }
221  T record = x;
222 
223  T *ptr = store.insertStatic(record);
224  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
225  if (it->second == &store) {
226  mIds[ptr->mId] = it->first;
227  }
228  }
229  return ptr;
230  }
231 
232  // This method must be called once, after loading all master/plugin files. This can only be done
233  // from the outside, so it must be public.
234  void setUp(bool validateRecords = false);
235 
236  int countSavedGameRecords() const;
237 
238  void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
239 
240  bool readRecord (ESM::ESMReader& reader, uint32_t type);
242  };
243 
244  template <>
245  inline const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
246  return mCells.insert(cell);
247  }
248 
249  template <>
250  inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
251  std::ostringstream id;
252  id << "$dynamic" << mDynamicCount++;
253 
254  if (Misc::StringUtils::ciEqual(npc.mId, "player")) {
255  return mNpcs.insert(npc);
256  } else if (mNpcs.search(id.str()) != 0) {
257  std::ostringstream msg;
258  msg << "Try to override existing record '" << id.str() << "'";
259  throw std::runtime_error(msg.str());
260  }
261  ESM::NPC record = npc;
262 
263  record.mId = id.str();
264 
265  ESM::NPC *ptr = mNpcs.insert(record);
266  mIds[ptr->mId] = ESM::REC_NPC_;
267  return ptr;
268  }
269 
270  template <>
271  inline const Store<ESM::Activator> &ESMStore::get<ESM::Activator>() const {
272  return mActivators;
273  }
274 
275  template <>
276  inline const Store<ESM::Potion> &ESMStore::get<ESM::Potion>() const {
277  return mPotions;
278  }
279 
280  template <>
281  inline const Store<ESM::Apparatus> &ESMStore::get<ESM::Apparatus>() const {
282  return mAppas;
283  }
284 
285  template <>
286  inline const Store<ESM::Armor> &ESMStore::get<ESM::Armor>() const {
287  return mArmors;
288  }
289 
290  template <>
291  inline const Store<ESM::BodyPart> &ESMStore::get<ESM::BodyPart>() const {
292  return mBodyParts;
293  }
294 
295  template <>
296  inline const Store<ESM::Book> &ESMStore::get<ESM::Book>() const {
297  return mBooks;
298  }
299 
300  template <>
301  inline const Store<ESM::BirthSign> &ESMStore::get<ESM::BirthSign>() const {
302  return mBirthSigns;
303  }
304 
305  template <>
306  inline const Store<ESM::Class> &ESMStore::get<ESM::Class>() const {
307  return mClasses;
308  }
309 
310  template <>
311  inline const Store<ESM::Clothing> &ESMStore::get<ESM::Clothing>() const {
312  return mClothes;
313  }
314 
315  template <>
316  inline const Store<ESM::Container> &ESMStore::get<ESM::Container>() const {
317  return mContainers;
318  }
319 
320  template <>
321  inline const Store<ESM::Creature> &ESMStore::get<ESM::Creature>() const {
322  return mCreatures;
323  }
324 
325  template <>
326  inline const Store<ESM::Dialogue> &ESMStore::get<ESM::Dialogue>() const {
327  return mDialogs;
328  }
329 
330  template <>
331  inline const Store<ESM::Door> &ESMStore::get<ESM::Door>() const {
332  return mDoors;
333  }
334 
335  template <>
336  inline const Store<ESM::Enchantment> &ESMStore::get<ESM::Enchantment>() const {
337  return mEnchants;
338  }
339 
340  template <>
341  inline const Store<ESM::Faction> &ESMStore::get<ESM::Faction>() const {
342  return mFactions;
343  }
344 
345  template <>
346  inline const Store<ESM::Global> &ESMStore::get<ESM::Global>() const {
347  return mGlobals;
348  }
349 
350  template <>
351  inline const Store<ESM::Ingredient> &ESMStore::get<ESM::Ingredient>() const {
352  return mIngreds;
353  }
354 
355  template <>
356  inline const Store<ESM::CreatureLevList> &ESMStore::get<ESM::CreatureLevList>() const {
357  return mCreatureLists;
358  }
359 
360  template <>
361  inline const Store<ESM::ItemLevList> &ESMStore::get<ESM::ItemLevList>() const {
362  return mItemLists;
363  }
364 
365  template <>
366  inline const Store<ESM::Light> &ESMStore::get<ESM::Light>() const {
367  return mLights;
368  }
369 
370  template <>
371  inline const Store<ESM::Lockpick> &ESMStore::get<ESM::Lockpick>() const {
372  return mLockpicks;
373  }
374 
375  template <>
376  inline const Store<ESM::Miscellaneous> &ESMStore::get<ESM::Miscellaneous>() const {
377  return mMiscItems;
378  }
379 
380  template <>
381  inline const Store<ESM::NPC> &ESMStore::get<ESM::NPC>() const {
382  return mNpcs;
383  }
384 
385  template <>
386  inline const Store<ESM::Probe> &ESMStore::get<ESM::Probe>() const {
387  return mProbes;
388  }
389 
390  template <>
391  inline const Store<ESM::Race> &ESMStore::get<ESM::Race>() const {
392  return mRaces;
393  }
394 
395  template <>
396  inline const Store<ESM::Region> &ESMStore::get<ESM::Region>() const {
397  return mRegions;
398  }
399 
400  template <>
401  inline const Store<ESM::Repair> &ESMStore::get<ESM::Repair>() const {
402  return mRepairs;
403  }
404 
405  template <>
406  inline const Store<ESM::SoundGenerator> &ESMStore::get<ESM::SoundGenerator>() const {
407  return mSoundGens;
408  }
409 
410  template <>
411  inline const Store<ESM::Sound> &ESMStore::get<ESM::Sound>() const {
412  return mSounds;
413  }
414 
415  template <>
416  inline const Store<ESM::Spell> &ESMStore::get<ESM::Spell>() const {
417  return mSpells;
418  }
419 
420  template <>
421  inline const Store<ESM::StartScript> &ESMStore::get<ESM::StartScript>() const {
422  return mStartScripts;
423  }
424 
425  template <>
426  inline const Store<ESM::Static> &ESMStore::get<ESM::Static>() const {
427  return mStatics;
428  }
429 
430  template <>
431  inline const Store<ESM::Weapon> &ESMStore::get<ESM::Weapon>() const {
432  return mWeapons;
433  }
434 
435  template <>
436  inline const Store<ESM::GameSetting> &ESMStore::get<ESM::GameSetting>() const {
437  return mGameSettings;
438  }
439 
440  template <>
441  inline const Store<ESM::Script> &ESMStore::get<ESM::Script>() const {
442  return mScripts;
443  }
444 
445  template <>
446  inline const Store<ESM::Cell> &ESMStore::get<ESM::Cell>() const {
447  return mCells;
448  }
449 
450  template <>
451  inline const Store<ESM::Land> &ESMStore::get<ESM::Land>() const {
452  return mLands;
453  }
454 
455  template <>
456  inline const Store<ESM::LandTexture> &ESMStore::get<ESM::LandTexture>() const {
457  return mLandTextures;
458  }
459 
460  template <>
461  inline const Store<ESM::Pathgrid> &ESMStore::get<ESM::Pathgrid>() const {
462  return mPathgrids;
463  }
464 
465  template <>
466  inline const Store<ESM::MagicEffect> &ESMStore::get<ESM::MagicEffect>() const {
467  return mMagicEffects;
468  }
469 
470  template <>
471  inline const Store<ESM::Skill> &ESMStore::get<ESM::Skill>() const {
472  return mSkills;
473  }
474 
475  template <>
476  inline const Store<ESM::Attribute> &ESMStore::get<ESM::Attribute>() const {
477  return mAttributes;
478  }
479 }
480 
481 #endif
void clearDynamic()
Definition: esmstore.hpp:149
Definition: store.hpp:325
Store< ESM::Dialogue > mDialogs
Definition: esmstore.hpp:30
Definition: defs.hpp:64
Definition: store.hpp:200
Store< ESM::StartScript > mStartScripts
Definition: esmstore.hpp:49
const T * find(const std::string &id) const
Definition: store.cpp:171
static bool ciEqual(const std::string &x, const std::string &y)
Definition: stringops.hpp:129
Definition: defs.hpp:77
Store< ESM::Sound > mSounds
Definition: esmstore.hpp:47
Store< ESM::Door > mDoors
Definition: esmstore.hpp:31
unsigned int mDynamicCount
Definition: esmstore.hpp:75
Store< ESM::Repair > mRepairs
Definition: esmstore.hpp:45
Store< ESM::Pathgrid > mPathgrids
Definition: esmstore.hpp:60
ESM::NPC mPlayerTemplate
Definition: esmstore.hpp:73
std::map< int, StoreBase * > mStores
Definition: esmstore.hpp:71
iterator end() const
Definition: esmstore.hpp:88
Definition: defs.hpp:105
Definition: defs.hpp:103
Definition: defs.hpp:78
Store< ESM::CreatureLevList > mCreatureLists
Definition: esmstore.hpp:36
Definition: esmreader.hpp:21
Store< ESM::NPC > mNpcs
Definition: esmstore.hpp:41
Store< ESM::MagicEffect > mMagicEffects
Definition: esmstore.hpp:62
Definition: defs.hpp:85
Definition: defs.hpp:84
Definition: defs.hpp:90
Store< ESM::Land > mLands
Definition: esmstore.hpp:58
void load(ESM::ESMReader &esm, Loading::Listener *listener)
Definition: esmstore.cpp:29
Definition: store.hpp:356
int countSavedGameRecords() const
Definition: esmstore.cpp:202
Definition: defs.hpp:93
Definition: defs.hpp:76
void validate()
Validate entries in store after setup.
Definition: esmstore.cpp:149
Definition: store.hpp:253
const T * search(const std::string &id) const
Definition: store.cpp:138
Store< ESM::Creature > mCreatures
Definition: esmstore.hpp:29
Definition: store.hpp:230
Definition: loadinglistener.hpp:8
Definition: defs.hpp:67
Store< ESM::BodyPart > mBodyParts
Definition: esmstore.hpp:23
Definition: defs.hpp:95
Definition: defs.hpp:80
Definition: defs.hpp:104
Definition: defs.hpp:73
Definition: esmwriter.hpp:17
Definition: store.hpp:363
Definition: defs.hpp:86
T * insertStatic(const T &item)
Definition: store.cpp:261
void movePlayerRecord()
Definition: esmstore.hpp:157
Definition: esmstore.hpp:17
Store< ESM::Script > mScripts
Definition: esmstore.hpp:54
Store< ESM::Region > mRegions
Definition: esmstore.hpp:44
std::map< std::string, int > mIds
Definition: esmstore.hpp:70
void setUp(bool validateRecords=false)
Definition: esmstore.cpp:122
Definition: defs.hpp:96
Store< ESM::Weapon > mWeapons
Definition: esmstore.hpp:51
Definition: loadnpc.hpp:23
Definition: defs.hpp:101
Definition: defs.hpp:88
std::string mId
Definition: loadnpc.hpp:133
Store< ESM::Skill > mSkills
Definition: esmstore.hpp:63
Store< ESM::Ingredient > mIngreds
Definition: esmstore.hpp:35
Store< ESM::Apparatus > mAppas
Definition: esmstore.hpp:21
int find(const std::string &id) const
Definition: esmstore.hpp:94
Definition: defs.hpp:83
Store< ESM::Cell > mCells
Definition: esmstore.hpp:57
bool eraseStatic(const std::string &id)
Definition: store.cpp:275
Store< ESM::SoundGenerator > mSoundGens
Definition: esmstore.hpp:46
Definition: defs.hpp:97
Definition: defs.hpp:63
Store< ESM::Enchantment > mEnchants
Definition: esmstore.hpp:32
Store< ESM::Lockpick > mLockpicks
Definition: esmstore.hpp:39
iterator begin() const
Definition: esmstore.hpp:84
Store< ESM::Spell > mSpells
Definition: esmstore.hpp:48
Store< ESM::BirthSign > mBirthSigns
Definition: esmstore.hpp:25
Definition: defs.hpp:69
Definition: defs.hpp:102
ESMStore()
Definition: esmstore.hpp:103
Definition: loadcell.hpp:64
Definition: defs.hpp:65
Definition: defs.hpp:79
bool readRecord(ESM::ESMReader &reader, uint32_t type)
Definition: esmstore.cpp:239
const T * overrideRecord(const T &x)
Insert a record with set ID, and allow it to override a pre-existing static record.
Definition: esmstore.hpp:198
Store< ESM::Race > mRaces
Definition: esmstore.hpp:43
Store< ESM::Light > mLights
Definition: esmstore.hpp:38
Definition: defs.hpp:82
Definition: defs.hpp:94
Definition: defs.hpp:100
Definition: defs.hpp:61
Store< ESM::Clothing > mClothes
Definition: esmstore.hpp:27
T * insert(const T &item)
Definition: store.cpp:247
Definition: defs.hpp:98
Store< ESM::Miscellaneous > mMiscItems
Definition: esmstore.hpp:40
Store< ESM::Attribute > mAttributes
Definition: esmstore.hpp:66
void write(ESM::ESMWriter &writer, Loading::Listener &progress) const
Definition: esmstore.cpp:218
Store< ESM::Static > mStatics
Definition: esmstore.hpp:50
Store< ESM::Armor > mArmors
Definition: esmstore.hpp:22
Definition: defs.hpp:62
Definition: defs.hpp:66
Store< ESM::Class > mClasses
Definition: esmstore.hpp:26
Store< ESM::Global > mGlobals
Definition: esmstore.hpp:34
Definition: defs.hpp:68
void setCells(Store< ESM::Cell > &cells)
Definition: store.cpp:874
std::map< int, StoreBase * >::const_iterator iterator
Definition: esmstore.hpp:82
Store< ESM::Book > mBooks
Definition: esmstore.hpp:24
Store< ESM::Potion > mPotions
Definition: esmstore.hpp:20
const T * insertStatic(const T &x)
Definition: esmstore.hpp:211
Store< ESM::ItemLevList > mItemLists
Definition: esmstore.hpp:37
Definition: defs.hpp:72
Store< ESM::LandTexture > mLandTextures
Definition: esmstore.hpp:59
Definition: defs.hpp:87
Definition: defs.hpp:91
Definition: defs.hpp:70
Store< ESM::Container > mContainers
Definition: esmstore.hpp:28
Store< ESM::Faction > mFactions
Definition: esmstore.hpp:33
const T * insert(const T &x)
Insert a custom record (i.e. with a generated ID that will not clash will pre-existing records) ...
Definition: esmstore.hpp:173
Store< ESM::GameSetting > mGameSettings
Definition: esmstore.hpp:53
Definition: defs.hpp:75
Store< ESM::Probe > mProbes
Definition: esmstore.hpp:42
Definition: store.hpp:370
Store< ESM::Activator > mActivators
Definition: esmstore.hpp:19