1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 17:11:33 +00:00

Merge branch 'SortedStaticLands' into 'master'

Replace land static container from vector to flat_set

See merge request OpenMW/openmw!853
This commit is contained in:
psi29a 2021-07-26 18:29:07 +00:00
commit 5a434aebe0
2 changed files with 29 additions and 50 deletions

View file

@ -11,25 +11,6 @@
#include <iterator> #include <iterator>
#include <stdexcept> #include <stdexcept>
namespace
{
struct Compare
{
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;
}
bool operator()(const ESM::Land *x, const std::pair<int, int>& y) {
if (x->mX == y.first) {
return x->mY < y.second;
}
return x->mX < y.first;
}
};
}
namespace MWWorld namespace MWWorld
{ {
RecordId::RecordId(const std::string &id, bool isDeleted) RecordId::RecordId(const std::string &id, bool isDeleted)
@ -412,11 +393,6 @@ namespace MWWorld
//========================================================================= //=========================================================================
Store<ESM::Land>::~Store() Store<ESM::Land>::~Store()
{ {
for (const ESM::Land* staticLand : mStatic)
{
delete staticLand;
}
} }
size_t Store<ESM::Land>::getSize() const size_t Store<ESM::Land>::getSize() const
{ {
@ -433,13 +409,8 @@ namespace MWWorld
const ESM::Land *Store<ESM::Land>::search(int x, int y) const const ESM::Land *Store<ESM::Land>::search(int x, int y) const
{ {
std::pair<int, int> comp(x,y); std::pair<int, int> comp(x,y);
if (auto it = mStatic.find(comp); it != mStatic.end() && it->mX == x && it->mY == y)
std::vector<ESM::Land *>::const_iterator it = return &*it;
std::lower_bound(mStatic.begin(), mStatic.end(), comp, Compare());
if (it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) {
return *it;
}
return nullptr; return nullptr;
} }
const ESM::Land *Store<ESM::Land>::find(int x, int y) const const ESM::Land *Store<ESM::Land>::find(int x, int y) const
@ -454,24 +425,13 @@ namespace MWWorld
} }
RecordId Store<ESM::Land>::load(ESM::ESMReader &esm) RecordId Store<ESM::Land>::load(ESM::ESMReader &esm)
{ {
ESM::Land *ptr = new ESM::Land(); ESM::Land land;
bool isDeleted = false; bool isDeleted = false;
ptr->load(esm, isDeleted); land.load(esm, isDeleted);
// Same area defined in multiple plugins? -> last plugin wins // Same area defined in multiple plugins? -> last plugin wins
// Can't use search() because we aren't sorted yet - is there any other way to speed this up? mStatic.insert(std::move(land));
for (std::vector<ESM::Land*>::iterator it = mStatic.begin(); it != mStatic.end(); ++it)
{
if ((*it)->mX == ptr->mX && (*it)->mY == ptr->mY)
{
delete *it;
mStatic.erase(it);
break;
}
}
mStatic.push_back(ptr);
return RecordId("", isDeleted); return RecordId("", isDeleted);
} }
@ -481,7 +441,6 @@ namespace MWWorld
if (mBuilt) if (mBuilt)
return; return;
std::sort(mStatic.begin(), mStatic.end(), Compare());
mBuilt = true; mBuilt = true;
} }

View file

@ -3,7 +3,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include <map> #include <map>
#include <set>
#include "recordcmp.hpp" #include "recordcmp.hpp"
@ -74,10 +76,10 @@ namespace MWWorld
const T *find(int index) const; const T *find(int index) const;
}; };
template <class T> template <class T, class Container=std::vector<T*>>
class SharedIterator class SharedIterator
{ {
typedef typename std::vector<T *>::const_iterator Iter; typedef typename Container::const_iterator Iter;
Iter mIter; Iter mIter;
@ -233,10 +235,28 @@ namespace MWWorld
template <> template <>
class Store<ESM::Land> : public StoreBase class Store<ESM::Land> : public StoreBase
{ {
std::vector<ESM::Land *> mStatic; struct SpatialComparator
{
using is_transparent = void;
bool operator()(const ESM::Land& x, const ESM::Land& y) const
{
return std::tie(x.mX, x.mY) < std::tie(y.mX, y.mY);
}
bool operator()(const ESM::Land& x, const std::pair<int, int>& y) const
{
return std::tie(x.mX, x.mY) < std::tie(y.first, y.second);
}
bool operator()(const std::pair<int, int>& x, const ESM::Land& y) const
{
return std::tie(x.first, x.second) < std::tie(y.mX, y.mY);
}
};
using Statics = std::set<ESM::Land, SpatialComparator>;
Statics mStatic;
public: public:
typedef SharedIterator<ESM::Land> iterator; typedef typename Statics::iterator iterator;
virtual ~Store(); virtual ~Store();