diff --git a/apps/openmw/mwworld/storedevel/store.hpp b/apps/openmw/mwworld/storedevel/store.hpp index c41fbc64c8..14ff11e8a0 100644 --- a/apps/openmw/mwworld/storedevel/store.hpp +++ b/apps/openmw/mwworld/storedevel/store.hpp @@ -70,22 +70,6 @@ namespace MWWorld return x.mId < y.mId; } - template <> - bool operator()(const ESM::Cell &x, const ESM::Cell &y) { - if (mCaseInsensitive) { - return CICompareString()(x.mName, y.mName); - } - return x.mName < y.mName; - } - - template <> - bool operator()(const ESM::Pathgrid &x, const ESM::Pathgrid &x) { - if (mCaseInsensitive) { - return CICompareString()(x.mCell, y.mCell); - } - return x.mCell < y.mCell; - } - bool isCaseInsensitive() const { return mCaseInsensitive; } @@ -97,8 +81,8 @@ namespace MWWorld if (x.length() != y.length()) { return false; } - std::string::iterator xit = x.begin(); - std::string::iterator yit = y.begin(); + std::string::const_iterator xit = x.begin(); + std::string::const_iterator yit = y.begin(); for (; xit != x.end(); ++xit, ++yit) { if (std::tolower(*xit) != std::tolower(*yit)) { return false; @@ -117,6 +101,22 @@ namespace MWWorld virtual void load(ESM::ESMReader &esm, const std::string &id) = 0; }; + template <> + bool StoreBase::Compare::operator()(const ESM::Cell &x, const ESM::Cell &y) { + if (mCaseInsensitive) { + return CICompareString()(x.mName, y.mName); + } + return x.mName < y.mName; + } + + template <> + bool StoreBase::Compare::operator()(const ESM::Pathgrid &x, const ESM::Pathgrid &y) { + if (mCaseInsensitive) { + return CICompareString()(x.mCell, y.mCell); + } + return x.mCell < y.mCell; + } + template class SharedIterator { @@ -214,7 +214,9 @@ namespace MWWorld const T *find(const std::string &id) const { const T *ptr = search(id); if (ptr == 0) { - throw std::runtime_error("object '" + id + "' not found"); + std::ostringstream msg; + msg << "Object '" << id << "' not found"; + throw std::runtime_error(msg.str()); } return ptr; } @@ -268,7 +270,7 @@ namespace MWWorld void listIdentifier(std::vector &list) const { list.reserve(list.size() + getSize()); - typename std::vector::iterator it = mShared.begin(); + typename std::vector::const_iterator it = mShared.begin(); for (; it != mShared.end(); ++it) { list.push_back((*it)->mId); } @@ -295,11 +297,11 @@ namespace MWWorld } const ESM::LandTexture *find(size_t index) const { - ESM::LandTexture *ptr = search(index); + const ESM::LandTexture *ptr = search(index); if (ptr == 0) { - throw std::runtime_error( - "Land texture with index " + index " not found" - ); + std::ostringstream msg; + msg << "Land texture with index " << index << " not found"; + throw std::runtime_error(msg.str()); } return ptr; } @@ -308,7 +310,7 @@ namespace MWWorld return mData.size(); } - int load(ESM::ESMReader &esm, const std::string &id) { + void load(ESM::ESMReader &esm, const std::string &id) { ESM::LandTexture ltex; ltex.load(esm); @@ -331,59 +333,61 @@ namespace MWWorld template <> class Store : public StoreBase { - std::vector mData; + std::vector mData; struct Compare { - bool operator()(const ESM::Land &x, const ESM::Land &y) { - if (x.mX == y.mX) { - return x.mY < y.mY; + bool operator()(const ESM::Land *x, const ESM::Land *y) { + if (x->mX == y->mX) { + return x->mY < y->mY; } - return x.mX < y.mX; + return x->mX < y->mX; } }; public: - typedef typename std::vector::const_iterator iterator; + typedef SharedIterator iterator; int getSize() const { return mData.size(); } iterator begin() { - return mData.begin(); + return iterator(mData.begin()); } iterator end() { - return mData.end(); + return iterator(mData.end()); } - ESM::Land *search(int x, int y) const { + ESM::Land *search(int x, int y) { ESM::Land land; land.mX = x, land.mY = y; - std::vector::iterator it = - std::lower_bound(mData.begin(), mData.end(), land, Compare()); + std::vector::iterator it = + std::lower_bound(mData.begin(), mData.end(), &land, Compare()); - if (it != mData.end() && it->mX == x && it->mY == y) { - return &(*it); + if (it != mData.end() && (*it)->mX == x && (*it)->mY == y) { + return *it; } return 0; } - ESM::Land *find(int x, int y) const { + ESM::Land *find(int x, int y) { ESM::Land *ptr = search(x, y); if (ptr == 0) { - throw std::runtime_error( - "Land at (" + x + ", " + y + ") not found" - ); + std::ostringstream msg; + msg << "Land at (" << x << ", " << y << ") not found"; + throw std::runtime_error(msg.str()); } return ptr; } void load(ESM::ESMReader &esm, const std::string &id) { - mData.push_back(ESM::Land()); - mData.back().load(esm); + ESM::Land *ptr = new ESM::Land(); + ptr->load(esm); + + mData.push_back(ptr); } void setUp() { @@ -423,7 +427,7 @@ namespace MWWorld Compare mIntCmp; std::vector mData; - iterator mIntBegin, mIntEnd, mExtBegin, mExtEnd; + std::vector::iterator mIntBegin, mIntEnd, mExtBegin, mExtEnd; public: Store() @@ -458,21 +462,21 @@ namespace MWWorld } const ESM::Cell *find(const std::string &id) const { - ESM::Cell *ptr = search(id); + const ESM::Cell *ptr = search(id); if (ptr == 0) { - throw std::runtime_error( - "Interior cell '" + id + "' not found" - ); + std::ostringstream msg; + msg << "Interior cell '" << id << "' not found"; + throw std::runtime_error(msg.str()); } return ptr; } const ESM::Cell *find(int x, int y) const { - ESM::Cell *ptr = search(x, y); + const ESM::Cell *ptr = search(x, y); if (ptr == 0) { - throw std::runtime_error( - "Exterior cell at (" + x + ", " + y + ") not found" - ); + std::ostringstream msg; + msg << "Exterior at (" << x << ", " << y << ") not found"; + throw std::runtime_error(msg.str()); } return ptr; } @@ -550,8 +554,7 @@ namespace MWWorld void listIdentifier(std::vector &list) const { list.reserve(list.size() + (mIntEnd - mIntBegin)); - std::vector::iterator it = mIntBegin; - for (; it != mIntEnd; ++it) { + for (iterator it = mIntBegin; it != mIntEnd; ++it) { list.push_back(it->mName); } } @@ -566,7 +569,8 @@ namespace MWWorld private: Compare mIntCmp; std::vector mData; - iterator mIntBegin, mIntEnd, mExtBegin, mExtEnd; + + std::vector::iterator mIntBegin, mIntEnd, mExtBegin, mExtEnd; struct IntExtOrdering { @@ -635,11 +639,11 @@ namespace MWWorld } const ESM::Pathgrid *find(int x, int y) const { - ESM::Pathgrid *ptr = search(x, y); + const ESM::Pathgrid *ptr = search(x, y); if (ptr == 0) { - throw std::runtime_error( - "Pathgrid at (" + x + ", " + y + ") not found" - ); + std::ostringstream msg; + msg << "Pathgrid at (" << x << ", " << y << ") not found"; + throw std::runtime_error(msg.str()); } return ptr; } @@ -656,11 +660,11 @@ namespace MWWorld } const ESM::Pathgrid *find(const std::string &name) const { - ESM::Pathgrid *ptr = search(name); + const ESM::Pathgrid *ptr = search(name); if (ptr == 0) { - throw std::runtime_error( - "Pathgrid in cell '" + name + "' not found" - ); + std::ostringstream msg; + msg << "Pathgrid in cell '" << name << "' not found"; + throw std::runtime_error(msg.str()); } return ptr; } @@ -673,7 +677,7 @@ namespace MWWorld } const ESM::Pathgrid *find(const ESM::Cell &cell) const { - if (cell.mData.mFlags & ESM::Cell:Interior) { + if (cell.mData.mFlags & ESM::Cell::Interior) { return find(cell.mName); } return find(cell.mData.mX, cell.mData.mY); @@ -703,6 +707,145 @@ namespace MWWorld return mExtEnd; } }; + + template + class IndexedStore + { + struct Compare + { + bool operator()(const T &x, const T &y) const { + return x.mIndex < y.mIndex; + } + }; + protected: + std::vector mData; + + public: + typedef typename std::vector::const_iterator iterator; + + IndexedStore() {} + + IndexedStore(unsigned int size) { + mData.reserve(size); + } + + iterator begin() const { + return mData.begin(); + } + + iterator end() const { + return mData.end(); + } + + /// \todo refine loading order + void load(ESM::ESMReader &esm) { + mData.push_back(T()); + mData.back().load(esm); + } + + int getSize() const { + return mData.size(); + } + + void setUp() { + std::sort(mData.begin(), mData.end(), Compare()); + } + + const T *search(int index) const { + T item; + item.mIndex = index; + + iterator it = + std::lower_bound(mData.begin(), mData.end(), item, Compare()); + if (it != mData.end() && it->mIndex == index) { + return &(*it); + } + return 0; + } + + const T *find(int index) const { + T *ptr = search(index); + if (ptr == 0) { + std::ostringstream msg; + msg << "Object with index " << index << " not found"; + throw std::runtime_error(msg.str()); + } + return ptr; + } + }; + + template <> + struct Store : public IndexedStore + { + Store() {} + Store(unsigned int size) + : IndexedStore(size) + {} + }; + + template <> + struct Store : public IndexedStore + { + Store() {} + Store(unsigned int size) + : IndexedStore(size) + {} + }; + + template <> + class Store : public IndexedStore + { + std::vector mData; + + public: + typedef std::vector::const_iterator iterator; + + Store() { + mData.reserve(ESM::Attribute::Length); + } + + const ESM::Attribute *search(int index) const { + if (index < 0 || index >= mData.size()) { + return 0; + } + return &mData.at(index); + } + + const ESM::Attribute *find(int index) const { + const ESM::Attribute *ptr = search(index); + if (ptr == 0) { + std::ostringstream msg; + msg << "Attribute with index " << index << " not found"; + throw std::runtime_error(msg.str()); + } + return ptr; + } + + void setUp() { + for (int i = 0; i < ESM::Attribute::Length; ++i) { + mData.push_back( + ESM::Attribute( + ESM::Attribute::sAttributeIds[i], + ESM::Attribute::sGmstAttributeIds[i], + ESM::Attribute::sGmstAttributeDescIds[i] + ) + ); + } + } + + int getSize() const { + return mData.size(); + } + + iterator begin() const { + return mData.begin(); + } + + iterator end() const { + return mData.end(); + } + }; + } //end namespace #endif