1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-28 21:36:43 +00:00

stores for records indexed with int, basic resolving

This commit is contained in:
greye 2012-10-30 16:14:03 +04:00
parent ce91c5636d
commit dd8f5e1a91

View file

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