1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-10 15:45:37 +00:00

Cellstore uses RefId.

This commit is contained in:
florent.teppe 2023-02-18 23:42:20 +01:00
parent 36502eaf75
commit 96e42d1666
3 changed files with 34 additions and 57 deletions

View File

@ -1122,21 +1122,9 @@ namespace MWWorld
} }
} }
struct IsEqualVisitor
{
bool operator()(const ESM::Cell& a, const ESM::Cell& b) const { return a.getCellId() == b.getCellId(); }
bool operator()(const ESM4::Cell& a, const ESM4::Cell& b) const { return a.mId == b.mId; }
template <class L, class R>
bool operator()(const L&, const R&) const
{
return false;
}
};
bool CellStore::operator==(const CellStore& right) const bool CellStore::operator==(const CellStore& right) const
{ {
return ESM::visit(IsEqualVisitor(), this->mCellVariant, right.mCellVariant); return right.mCellVariant.getId() == mCellVariant.getId();
} }
void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog) void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog)

View File

@ -20,7 +20,8 @@
namespace namespace
{ {
template <class Visitor, class Key, class Comp> template <class Visitor, class Key, class Comp>
bool forEachInStore(const ESM::RefId& id, Visitor&& visitor, std::map<Key, MWWorld::CellStore, Comp>& cellStore) bool forEachInStore(
const ESM::RefId& id, Visitor&& visitor, std::unordered_map<Key, MWWorld::CellStore, Comp>& cellStore)
{ {
for (auto& cell : cellStore) for (auto& cell : cellStore)
{ {
@ -62,27 +63,25 @@ namespace
MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell) MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
{ {
CellStore* cellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
if (cell->mData.mFlags & ESM::Cell::Interior) if (cell->mData.mFlags & ESM::Cell::Interior)
{ {
auto result = mInteriors.find(cell->mName); auto result = mInteriors.find(cell->mName);
if (result == mInteriors.end()) if (result == mInteriors.end())
result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; result = mInteriors.emplace(cell->mName, cellStore).first;
return &result->second; return result->second;
} }
else else
{ {
std::map<std::pair<int, int>, CellStore>::iterator result std::map<std::pair<int, int>, CellStore*>::iterator result
= mExteriors.find(std::make_pair(cell->getGridX(), cell->getGridY())); = mExteriors.find(std::make_pair(cell->getGridX(), cell->getGridY()));
if (result == mExteriors.end()) if (result == mExteriors.end())
result = mExteriors result = mExteriors.emplace(std::make_pair(cell->getGridX(), cell->getGridY()), cellStore).first;
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
CellStore(MWWorld::Cell(*cell), mStore, mReaders))
.first;
return &result->second; return result->second;
} }
} }
@ -160,7 +159,7 @@ MWWorld::WorldModel::WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCach
MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y) MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
{ {
std::map<std::pair<int, int>, CellStore>::iterator result = mExteriors.find(std::make_pair(x, y)); std::map<std::pair<int, int>, CellStore*>::iterator result = mExteriors.find(std::make_pair(x, y));
if (result == mExteriors.end()) if (result == mExteriors.end())
{ {
@ -185,15 +184,17 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
cell = MWBase::Environment::get().getWorld()->createRecord(record); cell = MWBase::Environment::get().getWorld()->createRecord(record);
} }
result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; CellStore* cellStore
= &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
result = mExteriors.emplace(std::make_pair(x, y), cellStore).first;
} }
if (result->second.getState() != CellStore::State_Loaded) if (result->second->getState() != CellStore::State_Loaded)
{ {
result->second.load(); result->second->load();
} }
return &result->second; return result->second;
} }
MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name) MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
@ -203,24 +204,26 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
if (result == mInteriors.end()) if (result == mInteriors.end())
{ {
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().searchCellName(name); const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().searchCellName(name);
CellStore* newCellStore = nullptr;
if (!cell4) if (!cell4)
{ {
const ESM::Cell* cell = mStore.get<ESM::Cell>().find(name); const ESM::Cell* cell = mStore.get<ESM::Cell>().find(name);
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; newCellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
} }
else else
{ {
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first; newCellStore
= &mCells.emplace(cell4->mId, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first->second;
} }
result = mInteriors.emplace(name, newCellStore).first;
} }
if (result->second.getState() != CellStore::State_Loaded) if (result->second->getState() != CellStore::State_Loaded)
{ {
result->second.load(); result->second->load();
} }
return &result->second; return result->second;
} }
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id) MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id)
@ -330,17 +333,17 @@ MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name)
// Then check cells that are already listed // Then check cells that are already listed
// Search in reverse, this is a workaround for an ambiguous chargen_plank reference in the vanilla game. // Search in reverse, this is a workaround for an ambiguous chargen_plank reference in the vanilla game.
// there is one at -22,16 and one at -2,-9, the latter should be used. // there is one at -22,16 and one at -2,-9, the latter should be used.
for (std::map<std::pair<int, int>, CellStore>::reverse_iterator iter = mExteriors.rbegin(); for (std::map<std::pair<int, int>, CellStore*>::reverse_iterator iter = mExteriors.rbegin();
iter != mExteriors.rend(); ++iter) iter != mExteriors.rend(); ++iter)
{ {
Ptr ptr = getPtrAndCache(name, iter->second); Ptr ptr = getPtrAndCache(name, *iter->second);
if (!ptr.isEmpty()) if (!ptr.isEmpty())
return ptr; return ptr;
} }
for (auto iter = mInteriors.begin(); iter != mInteriors.end(); ++iter) for (auto iter = mInteriors.begin(); iter != mInteriors.end(); ++iter)
{ {
Ptr ptr = getPtrAndCache(name, iter->second); Ptr ptr = getPtrAndCache(name, *iter->second);
if (!ptr.isEmpty()) if (!ptr.isEmpty())
return ptr; return ptr;
} }
@ -390,8 +393,7 @@ void MWWorld::WorldModel::getExteriorPtrs(const ESM::RefId& name, std::vector<MW
std::vector<MWWorld::Ptr> MWWorld::WorldModel::getAll(const ESM::RefId& id) std::vector<MWWorld::Ptr> MWWorld::WorldModel::getAll(const ESM::RefId& id)
{ {
PtrCollector visitor; PtrCollector visitor;
if (forEachInStore(id, visitor, mInteriors)) forEachInStore(id, visitor, mCells);
forEachInStore(id, visitor, mExteriors);
return visitor.mPtrs; return visitor.mPtrs;
} }
@ -399,12 +401,7 @@ int MWWorld::WorldModel::countSavedGameRecords() const
{ {
int count = 0; int count = 0;
for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter) for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
if (iter->second.hasState())
++count;
for (std::map<std::pair<int, int>, CellStore>::const_iterator iter(mExteriors.begin()); iter != mExteriors.end();
++iter)
if (iter->second.hasState()) if (iter->second.hasState())
++count; ++count;
@ -413,14 +410,7 @@ int MWWorld::WorldModel::countSavedGameRecords() const
void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progress) const void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
{ {
for (std::map<std::pair<int, int>, CellStore>::iterator iter(mExteriors.begin()); iter != mExteriors.end(); ++iter) for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
if (iter->second.hasState())
{
writeCell(writer, iter->second);
progress.increaseProgress();
}
for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter)
if (iter->second.hasState()) if (iter->second.hasState())
{ {
writeCell(writer, iter->second); writeCell(writer, iter->second);

View File

@ -42,8 +42,9 @@ namespace MWWorld
typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache; typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache;
const MWWorld::ESMStore& mStore; const MWWorld::ESMStore& mStore;
ESM::ReadersCache& mReaders; ESM::ReadersCache& mReaders;
mutable std::map<std::string, CellStore, Misc::StringUtils::CiComp> mInteriors; mutable std::unordered_map<ESM::RefId, CellStore> mCells;
mutable std::map<std::pair<int, int>, CellStore> mExteriors; mutable std::map<std::string, CellStore*, Misc::StringUtils::CiComp> mInteriors;
mutable std::map<std::pair<int, int>, CellStore*> mExteriors;
IdCache mIdCache; IdCache mIdCache;
std::size_t mIdCacheIndex = 0; std::size_t mIdCacheIndex = 0;
std::unordered_map<ESM::RefNum, Ptr> mPtrIndex; std::unordered_map<ESM::RefNum, Ptr> mPtrIndex;
@ -91,9 +92,7 @@ namespace MWWorld
template <typename Fn> template <typename Fn>
void forEachLoadedCellStore(Fn&& fn) void forEachLoadedCellStore(Fn&& fn)
{ {
for (auto& [_, store] : mInteriors) for (auto& [_, store] : mCells)
fn(store);
for (auto& [_, store] : mExteriors)
fn(store); fn(store);
} }