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 
77  public:
79  typedef std::map<int, StoreBase *>::const_iterator iterator;
80 
81  iterator begin() const {
82  return mStores.begin();
83  }
84 
85  iterator end() const {
86  return mStores.end();
87  }
88 
91  int find(const std::string &id) const
92  {
93  std::map<std::string, int>::const_iterator it = mIds.find(id);
94  if (it == mIds.end()) {
95  return 0;
96  }
97  return it->second;
98  }
99 
101  : mDynamicCount(0)
102  {
142 
144  }
145 
146  void clearDynamic ()
147  {
148  for (std::map<int, StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it)
149  it->second->clearDynamic();
150 
152  }
153 
155  {
156  mPlayerTemplate = *mNpcs.find("player");
159  }
160 
161  void load(ESM::ESMReader &esm, Loading::Listener* listener);
162 
163  template <class T>
164  const Store<T> &get() const {
165  throw std::runtime_error("Storage for this type not exist");
166  }
167 
169  template <class T>
170  const T *insert(const T &x) {
171  std::ostringstream id;
172  id << "$dynamic" << mDynamicCount++;
173 
174  Store<T> &store = const_cast<Store<T> &>(get<T>());
175  if (store.search(id.str()) != 0) {
176  std::ostringstream msg;
177  msg << "Try to override existing record '" << id.str() << "'";
178  throw std::runtime_error(msg.str());
179  }
180  T record = x;
181 
182  record.mId = id.str();
183 
184  T *ptr = store.insert(record);
185  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
186  if (it->second == &store) {
187  mIds[ptr->mId] = it->first;
188  }
189  }
190  return ptr;
191  }
192 
194  template <class T>
195  const T *overrideRecord(const T &x) {
196  Store<T> &store = const_cast<Store<T> &>(get<T>());
197 
198  T *ptr = store.insert(x);
199  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
200  if (it->second == &store) {
201  mIds[ptr->mId] = it->first;
202  }
203  }
204  return ptr;
205  }
206 
207  template <class T>
208  const T *insertStatic(const T &x) {
209  std::ostringstream id;
210  id << "$dynamic" << mDynamicCount++;
211 
212  Store<T> &store = const_cast<Store<T> &>(get<T>());
213  if (store.search(id.str()) != 0) {
214  std::ostringstream msg;
215  msg << "Try to override existing record '" << id.str() << "'";
216  throw std::runtime_error(msg.str());
217  }
218  T record = x;
219 
220  T *ptr = store.insertStatic(record);
221  for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
222  if (it->second == &store) {
223  mIds[ptr->mId] = it->first;
224  }
225  }
226  return ptr;
227  }
228 
229  // This method must be called once, after loading all master/plugin files. This can only be done
230  // from the outside, so it must be public.
231  void setUp();
232 
233  int countSavedGameRecords() const;
234 
235  void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
236 
237  bool readRecord (ESM::ESMReader& reader, uint32_t type);
239  };
240 
241  template <>
242  inline const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
243  return mCells.insert(cell);
244  }
245 
246  template <>
247  inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
248  std::ostringstream id;
249  id << "$dynamic" << mDynamicCount++;
250 
251  if (Misc::StringUtils::ciEqual(npc.mId, "player")) {
252  return mNpcs.insert(npc);
253  } else if (mNpcs.search(id.str()) != 0) {
254  std::ostringstream msg;
255  msg << "Try to override existing record '" << id.str() << "'";
256  throw std::runtime_error(msg.str());
257  }
258  ESM::NPC record = npc;
259 
260  record.mId = id.str();
261 
262  ESM::NPC *ptr = mNpcs.insert(record);
263  mIds[ptr->mId] = ESM::REC_NPC_;
264  return ptr;
265  }
266 
267  template <>
268  inline const Store<ESM::Activator> &ESMStore::get<ESM::Activator>() const {
269  return mActivators;
270  }
271 
272  template <>
273  inline const Store<ESM::Potion> &ESMStore::get<ESM::Potion>() const {
274  return mPotions;
275  }
276 
277  template <>
278  inline const Store<ESM::Apparatus> &ESMStore::get<ESM::Apparatus>() const {
279  return mAppas;
280  }
281 
282  template <>
283  inline const Store<ESM::Armor> &ESMStore::get<ESM::Armor>() const {
284  return mArmors;
285  }
286 
287  template <>
288  inline const Store<ESM::BodyPart> &ESMStore::get<ESM::BodyPart>() const {
289  return mBodyParts;
290  }
291 
292  template <>
293  inline const Store<ESM::Book> &ESMStore::get<ESM::Book>() const {
294  return mBooks;
295  }
296 
297  template <>
298  inline const Store<ESM::BirthSign> &ESMStore::get<ESM::BirthSign>() const {
299  return mBirthSigns;
300  }
301 
302  template <>
303  inline const Store<ESM::Class> &ESMStore::get<ESM::Class>() const {
304  return mClasses;
305  }
306 
307  template <>
308  inline const Store<ESM::Clothing> &ESMStore::get<ESM::Clothing>() const {
309  return mClothes;
310  }
311 
312  template <>
313  inline const Store<ESM::Container> &ESMStore::get<ESM::Container>() const {
314  return mContainers;
315  }
316 
317  template <>
318  inline const Store<ESM::Creature> &ESMStore::get<ESM::Creature>() const {
319  return mCreatures;
320  }
321 
322  template <>
323  inline const Store<ESM::Dialogue> &ESMStore::get<ESM::Dialogue>() const {
324  return mDialogs;
325  }
326 
327  template <>
328  inline const Store<ESM::Door> &ESMStore::get<ESM::Door>() const {
329  return mDoors;
330  }
331 
332  template <>
333  inline const Store<ESM::Enchantment> &ESMStore::get<ESM::Enchantment>() const {
334  return mEnchants;
335  }
336 
337  template <>
338  inline const Store<ESM::Faction> &ESMStore::get<ESM::Faction>() const {
339  return mFactions;
340  }
341 
342  template <>
343  inline const Store<ESM::Global> &ESMStore::get<ESM::Global>() const {
344  return mGlobals;
345  }
346 
347  template <>
348  inline const Store<ESM::Ingredient> &ESMStore::get<ESM::Ingredient>() const {
349  return mIngreds;
350  }
351 
352  template <>
353  inline const Store<ESM::CreatureLevList> &ESMStore::get<ESM::CreatureLevList>() const {
354  return mCreatureLists;
355  }
356 
357  template <>
358  inline const Store<ESM::ItemLevList> &ESMStore::get<ESM::ItemLevList>() const {
359  return mItemLists;
360  }
361 
362  template <>
363  inline const Store<ESM::Light> &ESMStore::get<ESM::Light>() const {
364  return mLights;
365  }
366 
367  template <>
368  inline const Store<ESM::Lockpick> &ESMStore::get<ESM::Lockpick>() const {
369  return mLockpicks;
370  }
371 
372  template <>
373  inline const Store<ESM::Miscellaneous> &ESMStore::get<ESM::Miscellaneous>() const {
374  return mMiscItems;
375  }
376 
377  template <>
378  inline const Store<ESM::NPC> &ESMStore::get<ESM::NPC>() const {
379  return mNpcs;
380  }
381 
382  template <>
383  inline const Store<ESM::Probe> &ESMStore::get<ESM::Probe>() const {
384  return mProbes;
385  }
386 
387  template <>
388  inline const Store<ESM::Race> &ESMStore::get<ESM::Race>() const {
389  return mRaces;
390  }
391 
392  template <>
393  inline const Store<ESM::Region> &ESMStore::get<ESM::Region>() const {
394  return mRegions;
395  }
396 
397  template <>
398  inline const Store<ESM::Repair> &ESMStore::get<ESM::Repair>() const {
399  return mRepairs;
400  }
401 
402  template <>
403  inline const Store<ESM::SoundGenerator> &ESMStore::get<ESM::SoundGenerator>() const {
404  return mSoundGens;
405  }
406 
407  template <>
408  inline const Store<ESM::Sound> &ESMStore::get<ESM::Sound>() const {
409  return mSounds;
410  }
411 
412  template <>
413  inline const Store<ESM::Spell> &ESMStore::get<ESM::Spell>() const {
414  return mSpells;
415  }
416 
417  template <>
418  inline const Store<ESM::StartScript> &ESMStore::get<ESM::StartScript>() const {
419  return mStartScripts;
420  }
421 
422  template <>
423  inline const Store<ESM::Static> &ESMStore::get<ESM::Static>() const {
424  return mStatics;
425  }
426 
427  template <>
428  inline const Store<ESM::Weapon> &ESMStore::get<ESM::Weapon>() const {
429  return mWeapons;
430  }
431 
432  template <>
433  inline const Store<ESM::GameSetting> &ESMStore::get<ESM::GameSetting>() const {
434  return mGameSettings;
435  }
436 
437  template <>
438  inline const Store<ESM::Script> &ESMStore::get<ESM::Script>() const {
439  return mScripts;
440  }
441 
442  template <>
443  inline const Store<ESM::Cell> &ESMStore::get<ESM::Cell>() const {
444  return mCells;
445  }
446 
447  template <>
448  inline const Store<ESM::Land> &ESMStore::get<ESM::Land>() const {
449  return mLands;
450  }
451 
452  template <>
453  inline const Store<ESM::LandTexture> &ESMStore::get<ESM::LandTexture>() const {
454  return mLandTextures;
455  }
456 
457  template <>
458  inline const Store<ESM::Pathgrid> &ESMStore::get<ESM::Pathgrid>() const {
459  return mPathgrids;
460  }
461 
462  template <>
463  inline const Store<ESM::MagicEffect> &ESMStore::get<ESM::MagicEffect>() const {
464  return mMagicEffects;
465  }
466 
467  template <>
468  inline const Store<ESM::Skill> &ESMStore::get<ESM::Skill>() const {
469  return mSkills;
470  }
471 
472  template <>
473  inline const Store<ESM::Attribute> &ESMStore::get<ESM::Attribute>() const {
474  return mAttributes;
475  }
476 }
477 
478 #endif
void clearDynamic()
Definition: esmstore.hpp:146
Definition: store.hpp:324
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:165
static bool ciEqual(const std::string &x, const std::string &y)
Definition: stringops.hpp:62
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:85
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:30
Definition: store.hpp:355
int countSavedGameRecords() const
Definition: esmstore.cpp:146
Definition: defs.hpp:93
Definition: defs.hpp:76
Definition: store.hpp:253
const T * search(const std::string &id) const
Definition: store.cpp:131
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:362
Definition: defs.hpp:86
T * insertStatic(const T &item)
Definition: store.cpp:255
void movePlayerRecord()
Definition: esmstore.hpp:154
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
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:128
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:91
Definition: defs.hpp:83
Store< ESM::Cell > mCells
Definition: esmstore.hpp:57
bool eraseStatic(const std::string &id)
Definition: store.cpp:269
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:81
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:100
Definition: loadcell.hpp:64
Definition: defs.hpp:65
Definition: defs.hpp:79
bool readRecord(ESM::ESMReader &reader, uint32_t type)
Definition: esmstore.cpp:183
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:195
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:241
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:162
void setUp()
Definition: esmstore.cpp:123
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:865
std::map< int, StoreBase * >::const_iterator iterator
Definition: esmstore.hpp:79
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:208
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:170
Store< ESM::GameSetting > mGameSettings
Definition: esmstore.hpp:53
Definition: defs.hpp:75
Store< ESM::Probe > mProbes
Definition: esmstore.hpp:42
Definition: store.hpp:369
Store< ESM::Activator > mActivators
Definition: esmstore.hpp:19