From 7cf0b8a680e7a88a82c2863050c8ab972dedbc20 Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 5 Nov 2012 18:09:14 +0400 Subject: [PATCH] just replace esmstore, inconsistent --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwworld/esmstore.cpp | 108 ++- apps/openmw/mwworld/esmstore.hpp | 479 ++++++++++---- apps/openmw/mwworld/reclists.hpp | 620 ------------------ .../mwworld/{storedevel => }/recordcmp.hpp | 0 .../openmw/mwworld/{storedevel => }/store.hpp | 0 apps/openmw/mwworld/storedevel/esmstore.cpp | 100 --- apps/openmw/mwworld/storedevel/esmstore.hpp | 362 ---------- 8 files changed, 398 insertions(+), 1273 deletions(-) delete mode 100644 apps/openmw/mwworld/reclists.hpp rename apps/openmw/mwworld/{storedevel => }/recordcmp.hpp (100%) rename apps/openmw/mwworld/{storedevel => }/store.hpp (100%) delete mode 100644 apps/openmw/mwworld/storedevel/esmstore.cpp delete mode 100644 apps/openmw/mwworld/storedevel/esmstore.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 07d27553d..b9ce26a66 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -53,7 +53,7 @@ add_openmw_dir (mwworld containerstore actiontalk actiontake manualref player cellfunctors cells localscripts customdata weather inventorystore ptr actionopen actionread actionequip timestamp actionalchemy cellstore actionapply actioneat - esmstore reclists + esmstore store recordcmp ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index c145fb3da..eb236d1bc 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -6,6 +6,19 @@ namespace MWWorld { +static bool isCacheableRecord(int id) +{ + if (id == ESM::REC_ACTI || id == ESM::REC_ALCH || id == ESM::REC_APPA || id == ESM::REC_ARMO || + id == ESM::REC_BOOK || id == ESM::REC_CLOT || id == ESM::REC_CONT || id == ESM::REC_CREA || + id == ESM::REC_DOOR || id == ESM::REC_INGR || id == ESM::REC_LEVC || id == ESM::REC_LEVI || + id == ESM::REC_LIGH || id == ESM::REC_LOCK || id == ESM::REC_MISC || id == ESM::REC_NPC_ || + id == ESM::REC_PROB || id == ESM::REC_REPA || id == ESM::REC_STAT || id == ESM::REC_WEAP) + { + return true; + } + return false; +} + void ESMStore::load(ESM::ESMReader &esm) { std::set missing; @@ -19,85 +32,51 @@ void ESMStore::load(ESM::ESMReader &esm) esm.getRecHeader(); // Look up the record type. - RecListList::iterator it = recLists.find(n.val); + std::map::iterator it = mStores.find(n.val); - if(it == recLists.end()) - { - if (n.val==ESM::REC_INFO) - { - if (dialogue) - { - ESM::DialInfo info; - info.load (esm); - - dialogue->mInfo.push_back (info); - } - else - { + if (it == mStores.end()) { + if (n.val == ESM::REC_INFO) { + if (dialogue) { + dialogue->mInfo.push_back(ESM::DialInfo()); + dialogue->mInfo.back().load(esm); + } else { std::cerr << "error: info record without dialog" << std::endl; esm.skipRecord(); } - } - else if (n.val==ESM::REC_MGEF) - { - magicEffects.load (esm); - } - else if (n.val==ESM::REC_SKIL) - { - skills.load (esm); - } - else - { + } else if (n.val == ESM::REC_MGEF) { + mMagicEffects.load (esm); + } else if (n.val == ESM::REC_SKIL) { + mSkills.load (esm); + } else { // Not found (this would be an error later) esm.skipRecord(); missing.insert(n.toString()); } - } - else - { + } else { // Load it std::string id = esm.getHNOString("NAME"); it->second->load(esm, id); - if (n.val==ESM::REC_DIAL) - { - RecListCaseT& recList = - static_cast& > (*it->second); - - ESM::Dialogue* d = recList.search (id); - - assert (d != NULL); - - dialogue = d; - } - else + if (n.val==ESM::REC_DIAL) { + // dirty hack, but it is better than non-const search() + // or friends + dialogue = const_cast(mDialogs.search(id)); + assert (dialogue != NULL); + } else { dialogue = 0; - + } // Insert the reference into the global lookup - if(!id.empty() && - (n.val==ESM::REC_ACTI || n.val==ESM::REC_ALCH || n.val==ESM::REC_APPA || n.val==ESM::REC_ARMO || - n.val==ESM::REC_BOOK || n.val==ESM::REC_CLOT || n.val==ESM::REC_CONT || n.val==ESM::REC_CREA || - n.val==ESM::REC_DOOR || n.val==ESM::REC_INGR || n.val==ESM::REC_LEVC || n.val==ESM::REC_LEVI || - n.val==ESM::REC_LIGH || n.val==ESM::REC_LOCK || n.val==ESM::REC_MISC || n.val==ESM::REC_NPC_ || - n.val==ESM::REC_PROB || n.val==ESM::REC_REPA || n.val==ESM::REC_STAT || n.val==ESM::REC_WEAP) - ) - all[id] = n.val; + if (!id.empty() && isCacheableRecord(n.val)) { + mIds[id] = n.val; + } } } - for (int i = 0; i < ESM::Attribute::Length; ++i) - { - typedef ESM::Attribute EsmAttr; - - EsmAttr::AttributeID id = EsmAttr::sAttributeIds[i]; - attributes.list.insert(std::make_pair(id, ESM::Attribute(id, EsmAttr::sGmstAttributeIds[i], EsmAttr::sGmstAttributeDescIds[i]))); - } - /* This information isn't needed on screen. But keep the code around for debugging purposes later. - cout << "\n" << recLists.size() << " record types:\n"; - for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++) + cout << "\n" << mStores.size() << " record types:\n"; + for(RecListList::iterator it = mStores.begin(); it != mStores.end(); it++) cout << " " << toStr(it->first) << ": " << it->second->getSize() << endl; cout << "\nNot implemented yet: "; for(set::iterator it = missing.begin(); @@ -107,4 +86,15 @@ void ESMStore::load(ESM::ESMReader &esm) */ } +void ESMStore::setUp() +{ + std::map::iterator it = mStores.begin(); + for (; it != mStores.end(); ++it) { + it->second->setUp(); + } + mSkills.setUp(); + mMagicEffects.setUp(); + mAttributes.setUp(); +} + } // end namespace diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 226b758dc..525341a30 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -1,145 +1,362 @@ -#ifndef OPENMW_MWWORLD_STORE_H -#define OPENMW_MWWORLD_STORE_H +#ifndef OPENMW_MWWORLD_ESMSTORE_H +#define OPENMW_MWWORLD_ESMSTORE_H -/* - The ESM storage module. - - This is separate from the ESM loader module, located in esm/. It is - also unaware of the cell loading and storage module. - - The advantage of this, as with all other modularizations, is that - you can replace the storage method later without touching the - loading code. Cutting down dependencies also help on the general - maintainability. - */ +#include #include -#include "reclists.hpp" +#include "store.hpp" namespace MWWorld { - - struct ESMStore - { - /* Lists all the list types. Mostly used for quick lookup on - loading. The key is the record name (4 chars) parsed as a 32 - bit int. See esm/records.hpp for the complete list. - */ - RecListList recLists; - - // Each individual list - RecListT activators; - RecListWithIDT potions; - RecListT appas; - RecListT armors; - RecListT bodyParts; - RecListWithIDT books; - RecListT birthSigns; - RecListT classes; - RecListT clothes; - RecListT contChange; - RecListT containers; - RecListWithIDT creatures; - RecListT creaChange; - RecListCaseT dialogs; - RecListT doors; - RecListT enchants; - RecListT factions; - RecListT globals; - RecListWithIDT ingreds; - RecListT creatureLists; - RecListT itemLists; - RecListT lights; - RecListT lockpicks; - RecListT miscItems; - RecListWithIDT npcs; - RecListT npcChange; - RecListT probes; - RecListT races; - RecListT regions; - RecListT repairs; - RecListT soundGens; - RecListT sounds; - RecListT spells; - RecListT startScripts; - RecListT statics; - RecListT weapons; - - // Lists that need special rules - CellList cells; - RecListWithIDT gameSettings; - LandList lands; - LTexList landTexts; - ScriptListT scripts; - IndexListT magicEffects; - IndexListT skills; - //RecListT pathgrids; - PathgridList pathgrids; - - // Special entry which is hardcoded and not loaded from an ESM - IndexListT attributes; - - // Lookup of all IDs. Makes looking up references faster. Just - // maps the id name to the record type. - typedef std::map AllMap; - AllMap all; - - // Look up the given ID in 'all'. Returns 0 if not found. - int find(const std::string &id) const + class ESMStore { - AllMap::const_iterator it = all.find(id); - if(it == all.end()) return 0; - return it->second; + Store mActivators; + Store mPotions; + Store mAppas; + Store mArmors; + Store mBodyParts; + Store mBooks; + Store mBirthSigns; + Store mClasses; + Store mClothes; + Store mContChange; + Store mContainers; + Store mCreatures; + Store mCreaChange; + Store mDialogs; + Store mDoors; + Store mEnchants; + Store mFactions; + Store mGlobals; + Store mIngreds; + Store mCreatureLists; + Store mItemLists; + Store mLights; + Store mLockpicks; + Store mMiscItems; + Store mNpcs; + Store mNpcChange; + Store mProbes; + Store mRaces; + Store mRegions; + Store mRepairs; + Store mSoundGens; + Store mSounds; + Store mSpells; + Store mStartScripts; + Store mStatics; + Store mWeapons; + + Store mGameSettings; + Store mScripts; + + // Lists that need special rules + Store mCells; + Store mLands; + Store mLandTextures; + Store mPathgrids; + + Store mMagicEffects; + Store mSkills; + + // Special entry which is hardcoded and not loaded from an ESM + Store mAttributes; + + // Lookup of all IDs. Makes looking up references faster. Just + // maps the id name to the record type. + std::map mIds; + std::map mStores; + + public: + // Look up the given ID in 'all'. Returns 0 if not found. + int find(const std::string &id) const + { + std::map::const_iterator it = mIds.find(id); + if (it == mIds.end()) { + return 0; + } + return it->second; + } + + ESMStore() + { + mStores[ESM::REC_ACTI] = &mActivators; + mStores[ESM::REC_ALCH] = &mPotions; + mStores[ESM::REC_APPA] = &mAppas; + mStores[ESM::REC_ARMO] = &mArmors; + mStores[ESM::REC_BODY] = &mBodyParts; + mStores[ESM::REC_BOOK] = &mBooks; + mStores[ESM::REC_BSGN] = &mBirthSigns; + mStores[ESM::REC_CELL] = &mCells; + mStores[ESM::REC_CLAS] = &mClasses; + mStores[ESM::REC_CLOT] = &mClothes; + mStores[ESM::REC_CNTC] = &mContChange; + mStores[ESM::REC_CONT] = &mContainers; + mStores[ESM::REC_CREA] = &mCreatures; + mStores[ESM::REC_CREC] = &mCreaChange; + mStores[ESM::REC_DIAL] = &mDialogs; + mStores[ESM::REC_DOOR] = &mDoors; + mStores[ESM::REC_ENCH] = &mEnchants; + mStores[ESM::REC_FACT] = &mFactions; + mStores[ESM::REC_GLOB] = &mGlobals; + mStores[ESM::REC_GMST] = &mGameSettings; + mStores[ESM::REC_INGR] = &mIngreds; + mStores[ESM::REC_LAND] = &mLands; + mStores[ESM::REC_LEVC] = &mCreatureLists; + mStores[ESM::REC_LEVI] = &mItemLists; + mStores[ESM::REC_LIGH] = &mLights; + mStores[ESM::REC_LOCK] = &mLockpicks; + mStores[ESM::REC_LTEX] = &mLandTextures; + mStores[ESM::REC_MISC] = &mMiscItems; + mStores[ESM::REC_NPC_] = &mNpcs; + mStores[ESM::REC_NPCC] = &mNpcChange; + mStores[ESM::REC_PGRD] = &mPathgrids; + mStores[ESM::REC_PROB] = &mProbes; + mStores[ESM::REC_RACE] = &mRaces; + mStores[ESM::REC_REGN] = &mRegions; + mStores[ESM::REC_REPA] = &mRepairs; + mStores[ESM::REC_SCPT] = &mScripts; + mStores[ESM::REC_SNDG] = &mSoundGens; + mStores[ESM::REC_SOUN] = &mSounds; + mStores[ESM::REC_SPEL] = &mSpells; + mStores[ESM::REC_SSCR] = &mStartScripts; + mStores[ESM::REC_STAT] = &mStatics; + mStores[ESM::REC_WEAP] = &mWeapons; + } + + void load(ESM::ESMReader &esm); + void setUp(); + + template + const Store &get() const { + throw std::runtime_error("Storage for this type not exist"); + } + }; + + template <> + const Store &ESMStore::get() const { + return mActivators; } - ESMStore() - { - recLists[ESM::REC_ACTI] = &activators; - recLists[ESM::REC_ALCH] = &potions; - recLists[ESM::REC_APPA] = &appas; - recLists[ESM::REC_ARMO] = &armors; - recLists[ESM::REC_BODY] = &bodyParts; - recLists[ESM::REC_BOOK] = &books; - recLists[ESM::REC_BSGN] = &birthSigns; - recLists[ESM::REC_CELL] = &cells; - recLists[ESM::REC_CLAS] = &classes; - recLists[ESM::REC_CLOT] = &clothes; - recLists[ESM::REC_CNTC] = &contChange; - recLists[ESM::REC_CONT] = &containers; - recLists[ESM::REC_CREA] = &creatures; - recLists[ESM::REC_CREC] = &creaChange; - recLists[ESM::REC_DIAL] = &dialogs; - recLists[ESM::REC_DOOR] = &doors; - recLists[ESM::REC_ENCH] = &enchants; - recLists[ESM::REC_FACT] = &factions; - recLists[ESM::REC_GLOB] = &globals; - recLists[ESM::REC_GMST] = &gameSettings; - recLists[ESM::REC_INGR] = &ingreds; - recLists[ESM::REC_LAND] = &lands; - recLists[ESM::REC_LEVC] = &creatureLists; - recLists[ESM::REC_LEVI] = &itemLists; - recLists[ESM::REC_LIGH] = &lights; - recLists[ESM::REC_LOCK] = &lockpicks; - recLists[ESM::REC_LTEX] = &landTexts; - recLists[ESM::REC_MISC] = &miscItems; - recLists[ESM::REC_NPC_] = &npcs; - recLists[ESM::REC_NPCC] = &npcChange; - recLists[ESM::REC_PGRD] = &pathgrids; - recLists[ESM::REC_PROB] = &probes; - recLists[ESM::REC_RACE] = &races; - recLists[ESM::REC_REGN] = ®ions; - recLists[ESM::REC_REPA] = &repairs; - recLists[ESM::REC_SCPT] = &scripts; - recLists[ESM::REC_SNDG] = &soundGens; - recLists[ESM::REC_SOUN] = &sounds; - recLists[ESM::REC_SPEL] = &spells; - recLists[ESM::REC_SSCR] = &startScripts; - recLists[ESM::REC_STAT] = &statics; - recLists[ESM::REC_WEAP] = &weapons; + template <> + const Store &ESMStore::get() const { + return mPotions; } - void load(ESM::ESMReader &esm); - }; + template <> + const Store &ESMStore::get() const { + return mAppas; + } + + template <> + const Store &ESMStore::get() const { + return mArmors; + } + + template <> + const Store &ESMStore::get() const { + return mBodyParts; + } + + template <> + const Store &ESMStore::get() const { + return mBooks; + } + + template <> + const Store &ESMStore::get() const { + return mBirthSigns; + } + + template <> + const Store &ESMStore::get() const { + return mClasses; + } + + template <> + const Store &ESMStore::get() const { + return mClothes; + } + + template <> + const Store &ESMStore::get() const { + return mContChange; + } + + template <> + const Store &ESMStore::get() const { + return mContainers; + } + + template <> + const Store &ESMStore::get() const { + return mCreatures; + } + + template <> + const Store &ESMStore::get() const { + return mCreaChange; + } + + template <> + const Store &ESMStore::get() const { + return mDialogs; + } + + template <> + const Store &ESMStore::get() const { + return mDoors; + } + + template <> + const Store &ESMStore::get() const { + return mEnchants; + } + + template <> + const Store &ESMStore::get() const { + return mFactions; + } + + template <> + const Store &ESMStore::get() const { + return mGlobals; + } + + template <> + const Store &ESMStore::get() const { + return mIngreds; + } + + template <> + const Store &ESMStore::get() const { + return mCreatureLists; + } + + template <> + const Store &ESMStore::get() const { + return mItemLists; + } + + template <> + const Store &ESMStore::get() const { + return mLights; + } + + template <> + const Store &ESMStore::get() const { + return mLockpicks; + } + + template <> + const Store &ESMStore::get() const { + return mMiscItems; + } + + template <> + const Store &ESMStore::get() const { + return mNpcs; + } + + template <> + const Store &ESMStore::get() const { + return mNpcChange; + } + + template <> + const Store &ESMStore::get() const { + return mProbes; + } + + template <> + const Store &ESMStore::get() const { + return mRaces; + } + + template <> + const Store &ESMStore::get() const { + return mRegions; + } + + template <> + const Store &ESMStore::get() const { + return mRepairs; + } + + template <> + const Store &ESMStore::get() const { + return mSoundGens; + } + + template <> + const Store &ESMStore::get() const { + return mSounds; + } + + template <> + const Store &ESMStore::get() const { + return mSpells; + } + + template <> + const Store &ESMStore::get() const { + return mStartScripts; + } + + template <> + const Store &ESMStore::get() const { + return mStatics; + } + + template <> + const Store &ESMStore::get() const { + return mWeapons; + } + + template <> + const Store &ESMStore::get() const { + return mGameSettings; + } + + template <> + const Store &ESMStore::get() const { + return mScripts; + } + + template <> + const Store &ESMStore::get() const { + return mCells; + } + + template <> + const Store &ESMStore::get() const { + return mLands; + } + + template <> + const Store &ESMStore::get() const { + return mLandTextures; + } + + template <> + const Store &ESMStore::get() const { + return mPathgrids; + } + + template <> + const Store &ESMStore::get() const { + return mMagicEffects; + } + + template <> + const Store &ESMStore::get() const { + return mSkills; + } + + template <> + const Store &ESMStore::get() const { + return mAttributes; + } } #endif diff --git a/apps/openmw/mwworld/reclists.hpp b/apps/openmw/mwworld/reclists.hpp deleted file mode 100644 index 179a7ac7c..000000000 --- a/apps/openmw/mwworld/reclists.hpp +++ /dev/null @@ -1,620 +0,0 @@ -#ifndef OPENMW_MWWORLD_RECLISTS_H -#define OPENMW_MWWORLD_RECLISTS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::algorithm; - -namespace MWWorld -{ - struct RecList - { - virtual ~RecList() {} - - virtual void load(ESM::ESMReader &esm, const std::string &id) = 0; - virtual int getSize() = 0; - virtual void listIdentifier (std::vector& identifier) const = 0; - - static std::string toLower (const std::string& name) - { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); - - return lowerCase; - } - }; - - typedef std::map RecListList; - - template - struct RecListT : RecList - { - virtual ~RecListT() {} - - typedef std::map MapType; - - MapType list; - - // Load one object of this type - void load(ESM::ESMReader &esm, const std::string &id) - { - std::string id2 = toLower (id); - list[id2].load(esm); - } - - // Find the given object ID, or return NULL if not found. - const X* search(const std::string &id) const - { - std::string id2 = toLower (id); - - typename MapType::const_iterator iter = list.find (id2); - - if (iter == list.end()) - return NULL; - - return &iter->second; - } - - // Find the given object ID (throws an exception if not found) - const X* find(const std::string &id) const - { - const X *object = search (id); - - if (!object) - throw std::runtime_error ("object " + id + " not found"); - - return object; - } - - int getSize() { return list.size(); } - - virtual void listIdentifier (std::vector& identifier) const - { - for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) - identifier.push_back (iter->first); - } - }; - - // Same as RecListT, but does not case-smash the IDs - // Note that lookups (search or find) are still case insensitive - template - struct RecListCaseT : RecList - { - virtual ~RecListCaseT() {} - - typedef std::map MapType; - - MapType list; - - // Load one object of this type - void load(ESM::ESMReader &esm, const std::string &id) - { - //std::string id2 = toLower (id); - - list[id].load(esm); - } - - // Find the given object ID, or return NULL if not found. - const X* search(const std::string &id) const - { - std::string id2 = toLower (id); - - for (typename MapType::const_iterator iter = list.begin(); - iter != list.end(); ++iter) - { - if (toLower(iter->first) == id2) - return &iter->second; - } - - return NULL; - } - - // non-const version - X* search(const std::string &id) - { - std::string id2 = toLower (id); - - for (typename MapType::iterator iter = list.begin(); - iter != list.end(); ++iter) - { - if (toLower(iter->first) == id2) - return &iter->second; - } - - return NULL; - } - - // Find the given object ID (throws an exception if not found) - const X* find(const std::string &id) const - { - const X *object = search (id); - - if (!object) - throw std::runtime_error ("object " + id + " not found"); - - return object; - } - - int getSize() { return list.size(); } - - virtual void listIdentifier (std::vector& identifier) const - { - for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) - identifier.push_back (iter->first); - } - }; - - /// Modified version of RecListT for records, that need to store their own ID - template - struct RecListWithIDT : RecList - { - virtual ~RecListWithIDT() {} - - typedef std::map MapType; - - MapType list; - - // Load one object of this type - void load(ESM::ESMReader &esm, const std::string &id) - { - std::string id2 = toLower (id); - list[id2].mId = id2; - list[id2].load(esm); - } - - // Find the given object ID, or return NULL if not found. - const X* search(const std::string &id) const - { - std::string id2 = toLower (id); - - typename MapType::const_iterator iter = list.find (id2); - - if (iter == list.end()) - return NULL; - return &iter->second; - } - - // Find the given object ID (throws an exception if not found) - const X* find(const std::string &id) const - { - const X *object = search (id); - - if (!object) - throw std::runtime_error ("object " + id + " not found"); - - return object; - } - - int getSize() { return list.size(); } - - virtual void listIdentifier (std::vector& identifier) const - { - for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) - identifier.push_back (iter->first); - } - }; - - /* Land textures are indexed by an integer number - */ - struct LTexList : RecList - { - virtual ~LTexList() {} - - // TODO: For multiple ESM/ESP files we need one list per file. - std::vector ltex; - - LTexList() - { - // More than enough to hold Morrowind.esm. - ltex.reserve(128); - } - - const ESM::LandTexture* search(size_t index) const - { - assert(index < ltex.size()); - return <ex.at(index); - } - - int getSize() { return ltex.size(); } - int getSize() const { return ltex.size(); } - - virtual void listIdentifier (std::vector& identifier) const {} - - void load(ESM::ESMReader &esm, const std::string &id) - { - ESM::LandTexture lt; - lt.load(esm); - lt.mId = id; - - // Make sure we have room for the structure - if(lt.mIndex + 1 > (int)ltex.size()) - ltex.resize(lt.mIndex+1); - - // Store it - ltex[lt.mIndex] = lt; - } - }; - - /* Landscapes are indexed by the X,Y coordinates of the exterior - cell they belong to. - */ - struct LandList : RecList - { - virtual ~LandList() - { - for ( LandMap::iterator itr = lands.begin(); itr != lands.end(); ++itr ) - { - delete itr->second; - } - } - - // Map containing all landscapes - typedef std::pair LandCoord; - typedef std::map LandMap; - LandMap lands; - - int count; - LandList() : count(0) {} - int getSize() { return count; } - - virtual void listIdentifier (std::vector& identifier) const {} - - // Find land for the given coordinates. Return null if no mData. - ESM::Land *search(int x, int y) const - { - LandMap::const_iterator itr = lands.find(std::make_pair (x, y)); - if ( itr == lands.end() ) - { - return NULL; - } - - return itr->second; - } - - void load(ESM::ESMReader &esm, const std::string &id) - { - count++; - - // Create the structure and load it. This actually skips the - // landscape data and remembers the file position for later. - ESM::Land *land = new ESM::Land(); - land->load(esm); - - // Store the structure - lands[std::make_pair (land->mX, land->mY)] = land; - } - }; - - struct ciLessBoost : std::binary_function -{ - bool operator() (const std::string & s1, const std::string & s2) const { - //case insensitive version of is_less - return lexicographical_compare(s1, s2, is_iless()); - } -}; - - - // Cells aren't simply indexed by name. Exterior cells are treated - // separately. - // TODO: case handling (cell names are case-insensitive, but they are also showen to the - // player, so we can't simply smash case. - struct CellList : RecList - { - // Total cell count. Used for statistics. - int count; - CellList() : count(0) {} - int getSize() { return count; } - - // List of interior cells. Indexed by cell name. - typedef std::map IntCells; - IntCells intCells; - - // List of exterior cells. Indexed as extCells[mX][mY]. - typedef std::map, ESM::Cell*> ExtCells; - ExtCells extCells; - - virtual void listIdentifier (std::vector& identifier) const - { - for (IntCells::const_iterator iter (intCells.begin()); iter!=intCells.end(); ++iter) - identifier.push_back (iter->first); - } - - virtual ~CellList() - { - for (IntCells::iterator it = intCells.begin(); it!=intCells.end(); ++it) - delete it->second; - - for (ExtCells::iterator it = extCells.begin(); it!=extCells.end(); ++it) - delete it->second; - } - - const ESM::Cell* searchInt(const std::string &id) const - { - IntCells::const_iterator iter = intCells.find(id); - - if (iter!=intCells.end()) - return iter->second; - - return 0; - } - - const ESM::Cell* findInt(const std::string &id) const - { - const ESM::Cell *cell = searchInt (id); - - if (!cell) - throw std::runtime_error ("Interior cell not found - " + id); - - return cell; - } - - const ESM::Cell *searchExt (int x, int y) const - { - ExtCells::const_iterator it = extCells.find (std::make_pair (x, y)); - - if (it==extCells.end()) - return 0; - - return it->second; - } - - const ESM::Cell *findExt (int x, int y) const - { - const ESM::Cell *cell = searchExt (x, y); - - if (!cell) - throw std::runtime_error ("Exterior cell not found"); - - return cell; - } - const ESM::Cell *searchExtByName (const std::string& id) const - { - for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) - { - if (toLower (iter->second->mName) == toLower (id)) - return iter->second; - } - - return 0; - } - - const ESM::Cell *searchExtByRegion (const std::string& id) const - { - std::string id2 = toLower (id); - - for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) - if (toLower (iter->second->mRegion)==id) - return iter->second; - - return 0; - } - - void load(ESM::ESMReader &esm, const std::string &id) - { - count++; - - // All cells have a name record, even nameless exterior cells. - ESM::Cell *cell = new ESM::Cell; - cell->mName = id; - - // The cell itself takes care of all the hairy details - cell->load(esm); - - if(cell->mData.mFlags & ESM::Cell::Interior) - { - // Store interior cell by name - intCells[id] = cell; - } - else - { - // Store exterior cells by grid position - extCells[std::make_pair (cell->mData.mX, cell->mData.mY)] = cell; - } - } - }; - - struct PathgridList : RecList - { - int count; - - // List of grids for interior cells. Indexed by cell name. - typedef std::map IntGrids; - IntGrids intGrids; - - // List of grids for exterior cells. Indexed as extCells[mX][mY]. - typedef std::map, ESM::Pathgrid*> ExtGrids; - ExtGrids extGrids; - - PathgridList() : count(0) {} - - virtual ~PathgridList() - { - for (IntGrids::iterator it = intGrids.begin(); it!=intGrids.end(); ++it) - delete it->second; - - for (ExtGrids::iterator it = extGrids.begin(); it!=extGrids.end(); ++it) - delete it->second; - } - - int getSize() { return count; } - - virtual void listIdentifier (std::vector& identifier) const - { - // do nothing - } - - void load(ESM::ESMReader &esm, const std::string &id) - { - count++; - ESM::Pathgrid *grid = new ESM::Pathgrid; - grid->load(esm); - if (grid->mData.mX == 0 && grid->mData.mY == 0) - { - intGrids[grid->mCell] = grid; - } - else - { - extGrids[std::make_pair(grid->mData.mX, grid->mData.mY)] = grid; - } - } - - ESM::Pathgrid *find(int cellX, int cellY, const std::string &cellName) const - { - ESM::Pathgrid *result = search(cellX, cellY, cellName); - if (!result) - { - throw std::runtime_error("no pathgrid found for cell " + cellName); - } - return result; - } - - ESM::Pathgrid *search(int cellX, int cellY, const std::string &cellName) const - { - ESM::Pathgrid *result = NULL; - if (cellX == 0 && cellY == 0) // possibly interior - { - IntGrids::const_iterator it = intGrids.find(cellName); - if (it != intGrids.end()) - result = it->second; - } - else - { - ExtGrids::const_iterator it = extGrids.find(std::make_pair(cellX, cellY)); - if (it != extGrids.end()) - result = it->second; - } - return result; - } - - ESM::Pathgrid *search(const ESM::Cell &cell) const - { - int cellX, cellY; - if (cell.mData.mFlags & ESM::Cell::Interior) - { - cellX = cellY = 0; - } - else - { - cellX = cell.mData.mX; - cellY = cell.mData.mY; - } - return search(cellX, cellY, cell.mName); - } - }; - - template - struct ScriptListT : RecList - { - virtual ~ScriptListT() {} - - typedef std::map MapType; - - MapType list; - - // Load one object of this type - void load(ESM::ESMReader &esm, const std::string &id) - { - X ref; - ref.load (esm); - - std::string realId = toLower (ref.mId); - - std::swap (list[realId], ref); - } - - // Find the given object ID, or return NULL if not found. - const X* search(const std::string &id) const - { - std::string id2 = toLower (id); - - typename MapType::const_iterator iter = list.find (id2); - - if (iter == list.end()) - return NULL; - - return &iter->second; - } - - // Find the given object ID (throws an exception if not found) - const X* find(const std::string &id) const - { - const X *object = search (id); - - if (!object) - throw std::runtime_error ("object " + id + " not found"); - - return object; - } - - int getSize() { return list.size(); } - - virtual void listIdentifier (std::vector& identifier) const - { - for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) - identifier.push_back (iter->first); - } - }; - - template - struct IndexListT - { - virtual ~IndexListT() {} - - typedef std::map MapType; - - MapType list; - - void load(ESM::ESMReader &esm) - { - X ref; - ref.load (esm); - int index = ref.mIndex; - list[index] = ref; - } - - int getSize() - { - return list.size(); - } - - virtual void listIdentifier (std::vector& identifier) const {} - - // Find the given object ID, or return NULL if not found. - const X* search (int id) const - { - typename MapType::const_iterator iter = list.find (id); - - if (iter == list.end()) - return NULL; - - return &iter->second; - } - - // Find the given object ID (throws an exception if not found) - const X* find (int id) const - { - const X *object = search (id); - - if (!object) - { - std::ostringstream error; - error << "object " << id << " not found"; - throw std::runtime_error (error.str()); - } - - return object; - } - }; -} -#endif diff --git a/apps/openmw/mwworld/storedevel/recordcmp.hpp b/apps/openmw/mwworld/recordcmp.hpp similarity index 100% rename from apps/openmw/mwworld/storedevel/recordcmp.hpp rename to apps/openmw/mwworld/recordcmp.hpp diff --git a/apps/openmw/mwworld/storedevel/store.hpp b/apps/openmw/mwworld/store.hpp similarity index 100% rename from apps/openmw/mwworld/storedevel/store.hpp rename to apps/openmw/mwworld/store.hpp diff --git a/apps/openmw/mwworld/storedevel/esmstore.cpp b/apps/openmw/mwworld/storedevel/esmstore.cpp deleted file mode 100644 index eb236d1bc..000000000 --- a/apps/openmw/mwworld/storedevel/esmstore.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "esmstore.hpp" - -#include -#include - -namespace MWWorld -{ - -static bool isCacheableRecord(int id) -{ - if (id == ESM::REC_ACTI || id == ESM::REC_ALCH || id == ESM::REC_APPA || id == ESM::REC_ARMO || - id == ESM::REC_BOOK || id == ESM::REC_CLOT || id == ESM::REC_CONT || id == ESM::REC_CREA || - id == ESM::REC_DOOR || id == ESM::REC_INGR || id == ESM::REC_LEVC || id == ESM::REC_LEVI || - id == ESM::REC_LIGH || id == ESM::REC_LOCK || id == ESM::REC_MISC || id == ESM::REC_NPC_ || - id == ESM::REC_PROB || id == ESM::REC_REPA || id == ESM::REC_STAT || id == ESM::REC_WEAP) - { - return true; - } - return false; -} - -void ESMStore::load(ESM::ESMReader &esm) -{ - std::set missing; - - ESM::Dialogue *dialogue = 0; - - // Loop through all records - while(esm.hasMoreRecs()) - { - ESM::NAME n = esm.getRecName(); - esm.getRecHeader(); - - // Look up the record type. - std::map::iterator it = mStores.find(n.val); - - if (it == mStores.end()) { - if (n.val == ESM::REC_INFO) { - if (dialogue) { - dialogue->mInfo.push_back(ESM::DialInfo()); - dialogue->mInfo.back().load(esm); - } else { - std::cerr << "error: info record without dialog" << std::endl; - esm.skipRecord(); - } - } else if (n.val == ESM::REC_MGEF) { - mMagicEffects.load (esm); - } else if (n.val == ESM::REC_SKIL) { - mSkills.load (esm); - } else { - // Not found (this would be an error later) - esm.skipRecord(); - missing.insert(n.toString()); - } - } else { - // Load it - std::string id = esm.getHNOString("NAME"); - it->second->load(esm, id); - - if (n.val==ESM::REC_DIAL) { - // dirty hack, but it is better than non-const search() - // or friends - dialogue = const_cast(mDialogs.search(id)); - assert (dialogue != NULL); - } else { - dialogue = 0; - } - // Insert the reference into the global lookup - if (!id.empty() && isCacheableRecord(n.val)) { - mIds[id] = n.val; - } - } - } - - /* This information isn't needed on screen. But keep the code around - for debugging purposes later. - - cout << "\n" << mStores.size() << " record types:\n"; - for(RecListList::iterator it = mStores.begin(); it != mStores.end(); it++) - cout << " " << toStr(it->first) << ": " << it->second->getSize() << endl; - cout << "\nNot implemented yet: "; - for(set::iterator it = missing.begin(); - it != missing.end(); it++ ) - cout << *it << " "; - cout << endl; - */ -} - -void ESMStore::setUp() -{ - std::map::iterator it = mStores.begin(); - for (; it != mStores.end(); ++it) { - it->second->setUp(); - } - mSkills.setUp(); - mMagicEffects.setUp(); - mAttributes.setUp(); -} - -} // end namespace diff --git a/apps/openmw/mwworld/storedevel/esmstore.hpp b/apps/openmw/mwworld/storedevel/esmstore.hpp deleted file mode 100644 index 525341a30..000000000 --- a/apps/openmw/mwworld/storedevel/esmstore.hpp +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef OPENMW_MWWORLD_ESMSTORE_H -#define OPENMW_MWWORLD_ESMSTORE_H - -#include - -#include -#include "store.hpp" - -namespace MWWorld -{ - class ESMStore - { - Store mActivators; - Store mPotions; - Store mAppas; - Store mArmors; - Store mBodyParts; - Store mBooks; - Store mBirthSigns; - Store mClasses; - Store mClothes; - Store mContChange; - Store mContainers; - Store mCreatures; - Store mCreaChange; - Store mDialogs; - Store mDoors; - Store mEnchants; - Store mFactions; - Store mGlobals; - Store mIngreds; - Store mCreatureLists; - Store mItemLists; - Store mLights; - Store mLockpicks; - Store mMiscItems; - Store mNpcs; - Store mNpcChange; - Store mProbes; - Store mRaces; - Store mRegions; - Store mRepairs; - Store mSoundGens; - Store mSounds; - Store mSpells; - Store mStartScripts; - Store mStatics; - Store mWeapons; - - Store mGameSettings; - Store mScripts; - - // Lists that need special rules - Store mCells; - Store mLands; - Store mLandTextures; - Store mPathgrids; - - Store mMagicEffects; - Store mSkills; - - // Special entry which is hardcoded and not loaded from an ESM - Store mAttributes; - - // Lookup of all IDs. Makes looking up references faster. Just - // maps the id name to the record type. - std::map mIds; - std::map mStores; - - public: - // Look up the given ID in 'all'. Returns 0 if not found. - int find(const std::string &id) const - { - std::map::const_iterator it = mIds.find(id); - if (it == mIds.end()) { - return 0; - } - return it->second; - } - - ESMStore() - { - mStores[ESM::REC_ACTI] = &mActivators; - mStores[ESM::REC_ALCH] = &mPotions; - mStores[ESM::REC_APPA] = &mAppas; - mStores[ESM::REC_ARMO] = &mArmors; - mStores[ESM::REC_BODY] = &mBodyParts; - mStores[ESM::REC_BOOK] = &mBooks; - mStores[ESM::REC_BSGN] = &mBirthSigns; - mStores[ESM::REC_CELL] = &mCells; - mStores[ESM::REC_CLAS] = &mClasses; - mStores[ESM::REC_CLOT] = &mClothes; - mStores[ESM::REC_CNTC] = &mContChange; - mStores[ESM::REC_CONT] = &mContainers; - mStores[ESM::REC_CREA] = &mCreatures; - mStores[ESM::REC_CREC] = &mCreaChange; - mStores[ESM::REC_DIAL] = &mDialogs; - mStores[ESM::REC_DOOR] = &mDoors; - mStores[ESM::REC_ENCH] = &mEnchants; - mStores[ESM::REC_FACT] = &mFactions; - mStores[ESM::REC_GLOB] = &mGlobals; - mStores[ESM::REC_GMST] = &mGameSettings; - mStores[ESM::REC_INGR] = &mIngreds; - mStores[ESM::REC_LAND] = &mLands; - mStores[ESM::REC_LEVC] = &mCreatureLists; - mStores[ESM::REC_LEVI] = &mItemLists; - mStores[ESM::REC_LIGH] = &mLights; - mStores[ESM::REC_LOCK] = &mLockpicks; - mStores[ESM::REC_LTEX] = &mLandTextures; - mStores[ESM::REC_MISC] = &mMiscItems; - mStores[ESM::REC_NPC_] = &mNpcs; - mStores[ESM::REC_NPCC] = &mNpcChange; - mStores[ESM::REC_PGRD] = &mPathgrids; - mStores[ESM::REC_PROB] = &mProbes; - mStores[ESM::REC_RACE] = &mRaces; - mStores[ESM::REC_REGN] = &mRegions; - mStores[ESM::REC_REPA] = &mRepairs; - mStores[ESM::REC_SCPT] = &mScripts; - mStores[ESM::REC_SNDG] = &mSoundGens; - mStores[ESM::REC_SOUN] = &mSounds; - mStores[ESM::REC_SPEL] = &mSpells; - mStores[ESM::REC_SSCR] = &mStartScripts; - mStores[ESM::REC_STAT] = &mStatics; - mStores[ESM::REC_WEAP] = &mWeapons; - } - - void load(ESM::ESMReader &esm); - void setUp(); - - template - const Store &get() const { - throw std::runtime_error("Storage for this type not exist"); - } - }; - - template <> - const Store &ESMStore::get() const { - return mActivators; - } - - template <> - const Store &ESMStore::get() const { - return mPotions; - } - - template <> - const Store &ESMStore::get() const { - return mAppas; - } - - template <> - const Store &ESMStore::get() const { - return mArmors; - } - - template <> - const Store &ESMStore::get() const { - return mBodyParts; - } - - template <> - const Store &ESMStore::get() const { - return mBooks; - } - - template <> - const Store &ESMStore::get() const { - return mBirthSigns; - } - - template <> - const Store &ESMStore::get() const { - return mClasses; - } - - template <> - const Store &ESMStore::get() const { - return mClothes; - } - - template <> - const Store &ESMStore::get() const { - return mContChange; - } - - template <> - const Store &ESMStore::get() const { - return mContainers; - } - - template <> - const Store &ESMStore::get() const { - return mCreatures; - } - - template <> - const Store &ESMStore::get() const { - return mCreaChange; - } - - template <> - const Store &ESMStore::get() const { - return mDialogs; - } - - template <> - const Store &ESMStore::get() const { - return mDoors; - } - - template <> - const Store &ESMStore::get() const { - return mEnchants; - } - - template <> - const Store &ESMStore::get() const { - return mFactions; - } - - template <> - const Store &ESMStore::get() const { - return mGlobals; - } - - template <> - const Store &ESMStore::get() const { - return mIngreds; - } - - template <> - const Store &ESMStore::get() const { - return mCreatureLists; - } - - template <> - const Store &ESMStore::get() const { - return mItemLists; - } - - template <> - const Store &ESMStore::get() const { - return mLights; - } - - template <> - const Store &ESMStore::get() const { - return mLockpicks; - } - - template <> - const Store &ESMStore::get() const { - return mMiscItems; - } - - template <> - const Store &ESMStore::get() const { - return mNpcs; - } - - template <> - const Store &ESMStore::get() const { - return mNpcChange; - } - - template <> - const Store &ESMStore::get() const { - return mProbes; - } - - template <> - const Store &ESMStore::get() const { - return mRaces; - } - - template <> - const Store &ESMStore::get() const { - return mRegions; - } - - template <> - const Store &ESMStore::get() const { - return mRepairs; - } - - template <> - const Store &ESMStore::get() const { - return mSoundGens; - } - - template <> - const Store &ESMStore::get() const { - return mSounds; - } - - template <> - const Store &ESMStore::get() const { - return mSpells; - } - - template <> - const Store &ESMStore::get() const { - return mStartScripts; - } - - template <> - const Store &ESMStore::get() const { - return mStatics; - } - - template <> - const Store &ESMStore::get() const { - return mWeapons; - } - - template <> - const Store &ESMStore::get() const { - return mGameSettings; - } - - template <> - const Store &ESMStore::get() const { - return mScripts; - } - - template <> - const Store &ESMStore::get() const { - return mCells; - } - - template <> - const Store &ESMStore::get() const { - return mLands; - } - - template <> - const Store &ESMStore::get() const { - return mLandTextures; - } - - template <> - const Store &ESMStore::get() const { - return mPathgrids; - } - - template <> - const Store &ESMStore::get() const { - return mMagicEffects; - } - - template <> - const Store &ESMStore::get() const { - return mSkills; - } - - template <> - const Store &ESMStore::get() const { - return mAttributes; - } -} - -#endif