mirror of
https://github.com/OpenMW/openmw.git
synced 2025-12-14 19:43:05 +00:00
refactors MWWorld::Store maps (#3197)
With this PR we clean up `MWWorld::Store` maps according to the approach of PR #3184.
This commit is contained in:
parent
7d34149adc
commit
1329f22186
4 changed files with 57 additions and 107 deletions
|
|
@ -61,7 +61,7 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ESM::NPC> getNPCsToReplace(const MWWorld::Store<ESM::Faction>& factions, const MWWorld::Store<ESM::Class>& classes, const std::map<std::string, ESM::NPC>& npcs)
|
std::vector<ESM::NPC> getNPCsToReplace(const MWWorld::Store<ESM::Faction>& factions, const MWWorld::Store<ESM::Class>& classes, const std::unordered_map<std::string, ESM::NPC, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual>& npcs)
|
||||||
{
|
{
|
||||||
// Cache first class from store - we will use it if current class is not found
|
// Cache first class from store - we will use it if current class is not found
|
||||||
std::string defaultCls;
|
std::string defaultCls;
|
||||||
|
|
@ -114,8 +114,8 @@ namespace
|
||||||
|
|
||||||
// Custom enchanted items can reference scripts that no longer exist, this doesn't necessarily mean the base item no longer exists however.
|
// Custom enchanted items can reference scripts that no longer exist, this doesn't necessarily mean the base item no longer exists however.
|
||||||
// So instead of removing the item altogether, we're only removing the script.
|
// So instead of removing the item altogether, we're only removing the script.
|
||||||
template<class T>
|
template<class MapT>
|
||||||
void removeMissingScripts(const MWWorld::Store<ESM::Script>& scripts, std::map<std::string, T>& items)
|
void removeMissingScripts(const MWWorld::Store<ESM::Script>& scripts, MapT& items)
|
||||||
{
|
{
|
||||||
for(auto& [id, item] : items)
|
for(auto& [id, item] : items)
|
||||||
{
|
{
|
||||||
|
|
@ -324,7 +324,6 @@ void ESMStore::countRecords()
|
||||||
if (value.mRefID != deletedRefID)
|
if (value.mRefID != deletedRefID)
|
||||||
{
|
{
|
||||||
std::string& refId = refIDs[value.mRefID];
|
std::string& refId = refIDs[value.mRefID];
|
||||||
Misc::StringUtils::lowerCaseInPlace(refId);
|
|
||||||
++mRefCount[std::move(refId)];
|
++mRefCount[std::move(refId)];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -333,8 +332,7 @@ void ESMStore::countRecords()
|
||||||
|
|
||||||
int ESMStore::getRefCount(const std::string& id) const
|
int ESMStore::getRefCount(const std::string& id) const
|
||||||
{
|
{
|
||||||
const std::string lowerId = Misc::StringUtils::lowerCase(id);
|
auto it = mRefCount.find(id);
|
||||||
auto it = mRefCount.find(lowerId);
|
|
||||||
if(it == mRefCount.end())
|
if(it == mRefCount.end())
|
||||||
return 0;
|
return 0;
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
@ -533,9 +531,8 @@ void ESMStore::removeMissingObjects(Store<T>& store)
|
||||||
throw std::runtime_error ("Invalid player record (race or class unavailable");
|
throw std::runtime_error ("Invalid player record (race or class unavailable");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::shared_ptr<MWMechanics::SpellList>, bool> ESMStore::getSpellList(const std::string& originalId) const
|
std::pair<std::shared_ptr<MWMechanics::SpellList>, bool> ESMStore::getSpellList(const std::string& id) const
|
||||||
{
|
{
|
||||||
const std::string id = Misc::StringUtils::lowerCase(originalId);
|
|
||||||
auto result = mSpellListCache.find(id);
|
auto result = mSpellListCache.find(id);
|
||||||
std::shared_ptr<MWMechanics::SpellList> ptr;
|
std::shared_ptr<MWMechanics::SpellList> ptr;
|
||||||
if (result != mSpellListCache.end())
|
if (result != mSpellListCache.end())
|
||||||
|
|
|
||||||
|
|
@ -75,16 +75,17 @@ namespace MWWorld
|
||||||
|
|
||||||
// Lookup of all IDs. Makes looking up references faster. Just
|
// Lookup of all IDs. Makes looking up references faster. Just
|
||||||
// maps the id name to the record type.
|
// maps the id name to the record type.
|
||||||
std::map<std::string, int> mIds;
|
using IDMap = std::unordered_map<std::string, int, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual>;
|
||||||
std::map<std::string, int> mStaticIds;
|
IDMap mIds;
|
||||||
|
IDMap mStaticIds;
|
||||||
|
|
||||||
std::unordered_map<std::string, int> mRefCount;
|
IDMap mRefCount;
|
||||||
|
|
||||||
std::map<int, StoreBase *> mStores;
|
std::map<int, StoreBase *> mStores;
|
||||||
|
|
||||||
unsigned int mDynamicCount;
|
unsigned int mDynamicCount;
|
||||||
|
|
||||||
mutable std::map<std::string, std::weak_ptr<MWMechanics::SpellList> > mSpellListCache;
|
mutable std::unordered_map<std::string, std::weak_ptr<MWMechanics::SpellList>, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache;
|
||||||
|
|
||||||
/// Validate entries in store after setup
|
/// Validate entries in store after setup
|
||||||
void validate();
|
void validate();
|
||||||
|
|
@ -115,10 +116,9 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the given ID in 'all'. Returns 0 if not found.
|
/// Look up the given ID in 'all'. Returns 0 if not found.
|
||||||
/// \note id must be in lower case.
|
|
||||||
int find(const std::string &id) const
|
int find(const std::string &id) const
|
||||||
{
|
{
|
||||||
std::map<std::string, int>::const_iterator it = mIds.find(id);
|
IDMap::const_iterator it = mIds.find(id);
|
||||||
if (it == mIds.end()) {
|
if (it == mIds.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +126,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
int findStatic(const std::string &id) const
|
int findStatic(const std::string &id) const
|
||||||
{
|
{
|
||||||
std::map<std::string, int>::const_iterator it = mStaticIds.find(id);
|
IDMap::const_iterator it = mStaticIds.find(id);
|
||||||
if (it == mStaticIds.end()) {
|
if (it == mStaticIds.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ namespace MWWorld
|
||||||
bool isDeleted = false;
|
bool isDeleted = false;
|
||||||
|
|
||||||
record.load(esm, isDeleted);
|
record.load(esm, isDeleted);
|
||||||
|
auto idx = record.mIndex;
|
||||||
mStatic.insert_or_assign(record.mIndex, record);
|
mStatic.insert_or_assign(idx, std::move(record));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int IndexedStore<T>::getSize() const
|
int IndexedStore<T>::getSize() const
|
||||||
|
|
@ -98,13 +98,11 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T *Store<T>::search(const std::string &id) const
|
const T *Store<T>::search(const std::string &id) const
|
||||||
{
|
{
|
||||||
std::string idLower = Misc::StringUtils::lowerCase(id);
|
typename Dynamic::const_iterator dit = mDynamic.find(id);
|
||||||
|
|
||||||
typename Dynamic::const_iterator dit = mDynamic.find(idLower);
|
|
||||||
if (dit != mDynamic.end())
|
if (dit != mDynamic.end())
|
||||||
return &dit->second;
|
return &dit->second;
|
||||||
|
|
||||||
typename std::map<std::string, T>::const_iterator it = mStatic.find(idLower);
|
typename Static::const_iterator it = mStatic.find(id);
|
||||||
if (it != mStatic.end())
|
if (it != mStatic.end())
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
|
|
||||||
|
|
@ -113,8 +111,7 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T *Store<T>::searchStatic(const std::string &id) const
|
const T *Store<T>::searchStatic(const std::string &id) const
|
||||||
{
|
{
|
||||||
std::string idLower = Misc::StringUtils::lowerCase(id);
|
typename Static::const_iterator it = mStatic.find(id);
|
||||||
typename std::map<std::string, T>::const_iterator it = mStatic.find(idLower);
|
|
||||||
if (it != mStatic.end())
|
if (it != mStatic.end())
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
|
|
||||||
|
|
@ -159,7 +156,7 @@ namespace MWWorld
|
||||||
bool isDeleted = false;
|
bool isDeleted = false;
|
||||||
|
|
||||||
record.load(esm, isDeleted);
|
record.load(esm, isDeleted);
|
||||||
Misc::StringUtils::lowerCaseInPlace(record.mId);
|
Misc::StringUtils::lowerCaseInPlace(record.mId); // TODO: remove this line once we have ported our remaining code base to lowercase on lookup
|
||||||
|
|
||||||
std::pair<typename Static::iterator, bool> inserted = mStatic.insert_or_assign(record.mId, record);
|
std::pair<typename Static::iterator, bool> inserted = mStatic.insert_or_assign(record.mId, record);
|
||||||
if (inserted.second)
|
if (inserted.second)
|
||||||
|
|
@ -206,14 +203,13 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *Store<T>::insert(const T &item, bool overrideOnly)
|
T *Store<T>::insert(const T &item, bool overrideOnly)
|
||||||
{
|
{
|
||||||
std::string id = Misc::StringUtils::lowerCase(item.mId);
|
|
||||||
if(overrideOnly)
|
if(overrideOnly)
|
||||||
{
|
{
|
||||||
auto it = mStatic.find(id);
|
auto it = mStatic.find(item.mId);
|
||||||
if(it == mStatic.end())
|
if(it == mStatic.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::pair<typename Dynamic::iterator, bool> result = mDynamic.insert_or_assign(id, item);
|
std::pair<typename Dynamic::iterator, bool> result = mDynamic.insert_or_assign(item.mId, item);
|
||||||
T *ptr = &result.first->second;
|
T *ptr = &result.first->second;
|
||||||
if (result.second)
|
if (result.second)
|
||||||
mShared.push_back(ptr);
|
mShared.push_back(ptr);
|
||||||
|
|
@ -222,8 +218,7 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T *Store<T>::insertStatic(const T &item)
|
T *Store<T>::insertStatic(const T &item)
|
||||||
{
|
{
|
||||||
std::string id = Misc::StringUtils::lowerCase(item.mId);
|
std::pair<typename Static::iterator, bool> result = mStatic.insert_or_assign(item.mId, item);
|
||||||
std::pair<typename Static::iterator, bool> result = mStatic.insert_or_assign(id, item);
|
|
||||||
T *ptr = &result.first->second;
|
T *ptr = &result.first->second;
|
||||||
if (result.second)
|
if (result.second)
|
||||||
mShared.push_back(ptr);
|
mShared.push_back(ptr);
|
||||||
|
|
@ -232,9 +227,7 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Store<T>::eraseStatic(const std::string &id)
|
bool Store<T>::eraseStatic(const std::string &id)
|
||||||
{
|
{
|
||||||
std::string idLower = Misc::StringUtils::lowerCase(id);
|
typename Static::iterator it = mStatic.find(id);
|
||||||
|
|
||||||
typename std::map<std::string, T>::iterator it = mStatic.find(idLower);
|
|
||||||
|
|
||||||
if (it != mStatic.end()) {
|
if (it != mStatic.end()) {
|
||||||
// delete from the static part of mShared
|
// delete from the static part of mShared
|
||||||
|
|
@ -242,7 +235,7 @@ namespace MWWorld
|
||||||
typename std::vector<T *>::iterator end = sharedIter + mStatic.size();
|
typename std::vector<T *>::iterator end = sharedIter + mStatic.size();
|
||||||
|
|
||||||
while (sharedIter != mShared.end() && sharedIter != end) {
|
while (sharedIter != mShared.end() && sharedIter != end) {
|
||||||
if((*sharedIter)->mId == idLower) {
|
if(Misc::StringUtils::ciEqual((*sharedIter)->mId, id)) {
|
||||||
mShared.erase(sharedIter);
|
mShared.erase(sharedIter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -257,17 +250,13 @@ namespace MWWorld
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Store<T>::erase(const std::string &id)
|
bool Store<T>::erase(const std::string &id)
|
||||||
{
|
{
|
||||||
std::string key = Misc::StringUtils::lowerCase(id);
|
if (!mDynamic.erase(id))
|
||||||
typename Dynamic::iterator it = mDynamic.find(key);
|
|
||||||
if (it == mDynamic.end()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
mDynamic.erase(it);
|
|
||||||
|
|
||||||
// have to reinit the whole shared part
|
// have to reinit the whole shared part
|
||||||
assert(mShared.size() >= mStatic.size());
|
assert(mShared.size() >= mStatic.size());
|
||||||
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
|
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
|
||||||
for (it = mDynamic.begin(); it != mDynamic.end(); ++it) {
|
for (auto it = mDynamic.begin(); it != mDynamic.end(); ++it) {
|
||||||
mShared.push_back(&it->second);
|
mShared.push_back(&it->second);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -353,23 +342,20 @@ namespace MWWorld
|
||||||
ESM::LandTexture* tex = const_cast<ESM::LandTexture*>(search(lt.mIndex, i));
|
ESM::LandTexture* tex = const_cast<ESM::LandTexture*>(search(lt.mIndex, i));
|
||||||
if (tex)
|
if (tex)
|
||||||
{
|
{
|
||||||
const std::string texId = Misc::StringUtils::lowerCase(tex->mId);
|
if (Misc::StringUtils::ciEqual(tex->mId, lt.mId))
|
||||||
const std::string ltId = Misc::StringUtils::lowerCase(lt.mId);
|
|
||||||
if (texId == ltId)
|
|
||||||
{
|
|
||||||
tex->mTexture = lt.mTexture;
|
tex->mTexture = lt.mTexture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LandTextureList <exl = mStatic[plugin];
|
LandTextureList <exl = mStatic[plugin];
|
||||||
if(lt.mIndex + 1 > (int)ltexl.size())
|
if(lt.mIndex + 1 > (int)ltexl.size())
|
||||||
ltexl.resize(lt.mIndex+1);
|
ltexl.resize(lt.mIndex+1);
|
||||||
|
|
||||||
// Store it
|
// Store it
|
||||||
ltexl[lt.mIndex] = lt;
|
auto idx = lt.mIndex;
|
||||||
|
ltexl[idx] = std::move(lt);
|
||||||
|
|
||||||
return RecordId(lt.mId, isDeleted);
|
return RecordId(ltexl[idx].mId, isDeleted);
|
||||||
}
|
}
|
||||||
RecordId Store<ESM::LandTexture>::load(ESM::ESMReader &esm)
|
RecordId Store<ESM::LandTexture>::load(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
|
@ -503,16 +489,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
const ESM::Cell *Store<ESM::Cell>::search(const std::string &id) const
|
const ESM::Cell *Store<ESM::Cell>::search(const std::string &id) const
|
||||||
{
|
{
|
||||||
ESM::Cell cell;
|
DynamicInt::const_iterator it = mInt.find(id);
|
||||||
cell.mName = Misc::StringUtils::lowerCase(id);
|
|
||||||
|
|
||||||
std::map<std::string, ESM::Cell>::const_iterator it = mInt.find(cell.mName);
|
|
||||||
|
|
||||||
if (it != mInt.end()) {
|
if (it != mInt.end()) {
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicInt::const_iterator dit = mDynamicInt.find(cell.mName);
|
DynamicInt::const_iterator dit = mDynamicInt.find(id);
|
||||||
if (dit != mDynamicInt.end()) {
|
if (dit != mDynamicInt.end()) {
|
||||||
return &dit->second;
|
return &dit->second;
|
||||||
}
|
}
|
||||||
|
|
@ -521,48 +503,34 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
const ESM::Cell *Store<ESM::Cell>::search(int x, int y) const
|
const ESM::Cell *Store<ESM::Cell>::search(int x, int y) const
|
||||||
{
|
{
|
||||||
ESM::Cell cell;
|
|
||||||
cell.mData.mX = x;
|
|
||||||
cell.mData.mY = y;
|
|
||||||
|
|
||||||
std::pair<int, int> key(x, y);
|
std::pair<int, int> key(x, y);
|
||||||
DynamicExt::const_iterator it = mExt.find(key);
|
DynamicExt::const_iterator it = mExt.find(key);
|
||||||
if (it != mExt.end()) {
|
if (it != mExt.end())
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
|
||||||
|
|
||||||
DynamicExt::const_iterator dit = mDynamicExt.find(key);
|
DynamicExt::const_iterator dit = mDynamicExt.find(key);
|
||||||
if (dit != mDynamicExt.end()) {
|
if (dit != mDynamicExt.end())
|
||||||
return &dit->second;
|
return &dit->second;
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const ESM::Cell *Store<ESM::Cell>::searchStatic(int x, int y) const
|
const ESM::Cell *Store<ESM::Cell>::searchStatic(int x, int y) const
|
||||||
{
|
{
|
||||||
ESM::Cell cell;
|
DynamicExt::const_iterator it = mExt.find(std::make_pair(x,y));
|
||||||
cell.mData.mX = x;
|
if (it != mExt.end())
|
||||||
cell.mData.mY = y;
|
|
||||||
|
|
||||||
std::pair<int, int> key(x, y);
|
|
||||||
DynamicExt::const_iterator it = mExt.find(key);
|
|
||||||
if (it != mExt.end()) {
|
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const ESM::Cell *Store<ESM::Cell>::searchOrCreate(int x, int y)
|
const ESM::Cell *Store<ESM::Cell>::searchOrCreate(int x, int y)
|
||||||
{
|
{
|
||||||
std::pair<int, int> key(x, y);
|
std::pair<int, int> key(x, y);
|
||||||
DynamicExt::const_iterator it = mExt.find(key);
|
DynamicExt::const_iterator it = mExt.find(key);
|
||||||
if (it != mExt.end()) {
|
if (it != mExt.end())
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
|
||||||
|
|
||||||
DynamicExt::const_iterator dit = mDynamicExt.find(key);
|
DynamicExt::const_iterator dit = mDynamicExt.find(key);
|
||||||
if (dit != mDynamicExt.end()) {
|
if (dit != mDynamicExt.end())
|
||||||
return &dit->second;
|
return &dit->second;
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Cell newCell;
|
ESM::Cell newCell;
|
||||||
newCell.mData.mX = x;
|
newCell.mData.mX = x;
|
||||||
|
|
@ -625,12 +593,11 @@ namespace MWWorld
|
||||||
// Load the (x,y) coordinates of the cell, if it is an exterior cell,
|
// Load the (x,y) coordinates of the cell, if it is an exterior cell,
|
||||||
// so we can find the cell we need to merge with
|
// so we can find the cell we need to merge with
|
||||||
cell.loadNameAndData(esm, isDeleted);
|
cell.loadNameAndData(esm, isDeleted);
|
||||||
std::string idLower = Misc::StringUtils::lowerCase(cell.mName);
|
|
||||||
|
|
||||||
if(cell.mData.mFlags & ESM::Cell::Interior)
|
if(cell.mData.mFlags & ESM::Cell::Interior)
|
||||||
{
|
{
|
||||||
// Store interior cell by name, try to merge with existing parent data.
|
// Store interior cell by name, try to merge with existing parent data.
|
||||||
ESM::Cell *oldcell = const_cast<ESM::Cell*>(search(idLower));
|
ESM::Cell *oldcell = const_cast<ESM::Cell*>(search(cell.mName));
|
||||||
if (oldcell) {
|
if (oldcell) {
|
||||||
// merge new cell into old cell
|
// merge new cell into old cell
|
||||||
// push the new references on the list of references to manage (saveContext = true)
|
// push the new references on the list of references to manage (saveContext = true)
|
||||||
|
|
@ -642,7 +609,7 @@ namespace MWWorld
|
||||||
// spawn a new cell
|
// spawn a new cell
|
||||||
cell.loadCell(esm, true);
|
cell.loadCell(esm, true);
|
||||||
|
|
||||||
mInt[idLower] = cell;
|
mInt[cell.mName] = cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -780,27 +747,19 @@ namespace MWWorld
|
||||||
const std::string cellType = (cell.isExterior()) ? "exterior" : "interior";
|
const std::string cellType = (cell.isExterior()) ? "exterior" : "interior";
|
||||||
throw std::runtime_error("Failed to create " + cellType + " cell");
|
throw std::runtime_error("Failed to create " + cellType + " cell");
|
||||||
}
|
}
|
||||||
ESM::Cell *ptr;
|
|
||||||
if (cell.isExterior()) {
|
if (cell.isExterior()) {
|
||||||
std::pair<int, int> key(cell.getGridX(), cell.getGridY());
|
std::pair<int, int> key(cell.getGridX(), cell.getGridY());
|
||||||
|
|
||||||
// duplicate insertions are avoided by search(ESM::Cell &)
|
// duplicate insertions are avoided by search(ESM::Cell &)
|
||||||
std::pair<DynamicExt::iterator, bool> result =
|
DynamicExt::iterator result = mDynamicExt.emplace(key, cell).first;
|
||||||
mDynamicExt.insert(std::make_pair(key, cell));
|
mSharedExt.push_back(&result->second);
|
||||||
|
return &result->second;
|
||||||
ptr = &result.first->second;
|
|
||||||
mSharedExt.push_back(ptr);
|
|
||||||
} else {
|
} else {
|
||||||
std::string key = Misc::StringUtils::lowerCase(cell.mName);
|
|
||||||
|
|
||||||
// duplicate insertions are avoided by search(ESM::Cell &)
|
// duplicate insertions are avoided by search(ESM::Cell &)
|
||||||
std::pair<DynamicInt::iterator, bool> result =
|
DynamicInt::iterator result = mDynamicInt.emplace(cell.mName, cell).first;
|
||||||
mDynamicInt.insert(std::make_pair(key, cell));
|
mSharedInt.push_back(&result->second);
|
||||||
|
return &result->second;
|
||||||
ptr = &result.first->second;
|
|
||||||
mSharedInt.push_back(ptr);
|
|
||||||
}
|
}
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
bool Store<ESM::Cell>::erase(const ESM::Cell &cell)
|
bool Store<ESM::Cell>::erase(const ESM::Cell &cell)
|
||||||
{
|
{
|
||||||
|
|
@ -811,8 +770,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
bool Store<ESM::Cell>::erase(const std::string &id)
|
bool Store<ESM::Cell>::erase(const std::string &id)
|
||||||
{
|
{
|
||||||
std::string key = Misc::StringUtils::lowerCase(id);
|
DynamicInt::iterator it = mDynamicInt.find(id);
|
||||||
DynamicInt::iterator it = mDynamicInt.find(key);
|
|
||||||
|
|
||||||
if (it == mDynamicInt.end()) {
|
if (it == mDynamicInt.end()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1062,12 +1020,11 @@ namespace MWWorld
|
||||||
|
|
||||||
dialogue.loadId(esm);
|
dialogue.loadId(esm);
|
||||||
|
|
||||||
std::string idLower = Misc::StringUtils::lowerCase(dialogue.mId);
|
Static::iterator found = mStatic.find(dialogue.mId);
|
||||||
std::map<std::string, ESM::Dialogue>::iterator found = mStatic.find(idLower);
|
|
||||||
if (found == mStatic.end())
|
if (found == mStatic.end())
|
||||||
{
|
{
|
||||||
dialogue.loadData(esm, isDeleted);
|
dialogue.loadData(esm, isDeleted);
|
||||||
mStatic.insert(std::make_pair(idLower, dialogue));
|
mStatic.emplace(dialogue.mId, dialogue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1081,11 +1038,7 @@ namespace MWWorld
|
||||||
template<>
|
template<>
|
||||||
bool Store<ESM::Dialogue>::eraseStatic(const std::string &id)
|
bool Store<ESM::Dialogue>::eraseStatic(const std::string &id)
|
||||||
{
|
{
|
||||||
auto it = mStatic.find(Misc::StringUtils::lowerCase(id));
|
mStatic.erase(id);
|
||||||
|
|
||||||
if (it != mStatic.end())
|
|
||||||
mStatic.erase(it);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "recordcmp.hpp"
|
#include "recordcmp.hpp"
|
||||||
|
|
@ -147,14 +148,13 @@ namespace MWWorld
|
||||||
template <class T>
|
template <class T>
|
||||||
class Store : public StoreBase
|
class Store : public StoreBase
|
||||||
{
|
{
|
||||||
std::map<std::string, T> mStatic;
|
typedef std::unordered_map<std::string, T, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> Static;
|
||||||
std::vector<T *> mShared; // Preserves the record order as it came from the content files (this
|
Static mStatic;
|
||||||
|
std::vector<T*> mShared; // Preserves the record order as it came from the content files (this
|
||||||
// is relevant for the spell autocalc code and selection order
|
// is relevant for the spell autocalc code and selection order
|
||||||
// for heads/hairs in the character creation)
|
// for heads/hairs in the character creation)
|
||||||
std::map<std::string, T> mDynamic;
|
typedef std::unordered_map<std::string, T, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> Dynamic;
|
||||||
|
Dynamic mDynamic;
|
||||||
typedef std::map<std::string, T> Dynamic;
|
|
||||||
typedef std::map<std::string, T> Static;
|
|
||||||
|
|
||||||
friend class ESMStore;
|
friend class ESMStore;
|
||||||
|
|
||||||
|
|
@ -294,7 +294,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, ESM::Cell> DynamicInt;
|
typedef std::unordered_map<std::string, ESM::Cell, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> DynamicInt;
|
||||||
typedef std::map<std::pair<int, int>, ESM::Cell, DynamicExtCmp> DynamicExt;
|
typedef std::map<std::pair<int, int>, ESM::Cell, DynamicExtCmp> DynamicExt;
|
||||||
|
|
||||||
DynamicInt mInt;
|
DynamicInt mInt;
|
||||||
|
|
@ -354,7 +354,7 @@ namespace MWWorld
|
||||||
class Store<ESM::Pathgrid> : public StoreBase
|
class Store<ESM::Pathgrid> : public StoreBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, ESM::Pathgrid> Interior;
|
typedef std::unordered_map<std::string, ESM::Pathgrid, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> Interior;
|
||||||
typedef std::map<std::pair<int, int>, ESM::Pathgrid> Exterior;
|
typedef std::map<std::pair<int, int>, ESM::Pathgrid> Exterior;
|
||||||
|
|
||||||
Interior mInt;
|
Interior mInt;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue