mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 17:09:41 +00:00
Cellstore uses RefId.
This commit is contained in:
parent
36502eaf75
commit
96e42d1666
3 changed files with 34 additions and 57 deletions
|
@ -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
|
||||
{
|
||||
return ESM::visit(IsEqualVisitor(), this->mCellVariant, right.mCellVariant);
|
||||
return right.mCellVariant.getId() == mCellVariant.getId();
|
||||
}
|
||||
|
||||
void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog)
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -62,27 +63,25 @@ namespace
|
|||
|
||||
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)
|
||||
{
|
||||
auto result = mInteriors.find(cell->mName);
|
||||
|
||||
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
|
||||
{
|
||||
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()));
|
||||
|
||||
if (result == mExteriors.end())
|
||||
result = mExteriors
|
||||
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
|
||||
CellStore(MWWorld::Cell(*cell), mStore, mReaders))
|
||||
.first;
|
||||
result = mExteriors.emplace(std::make_pair(cell->getGridX(), cell->getGridY()), cellStore).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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
|
@ -185,15 +184,17 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
|
|||
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)
|
||||
|
@ -203,24 +204,26 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
|
|||
if (result == mInteriors.end())
|
||||
{
|
||||
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().searchCellName(name);
|
||||
|
||||
CellStore* newCellStore = nullptr;
|
||||
if (!cell4)
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
|
@ -330,17 +333,17 @@ MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name)
|
|||
// Then check cells that are already listed
|
||||
// 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.
|
||||
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)
|
||||
{
|
||||
Ptr ptr = getPtrAndCache(name, iter->second);
|
||||
Ptr ptr = getPtrAndCache(name, *iter->second);
|
||||
if (!ptr.isEmpty())
|
||||
return ptr;
|
||||
}
|
||||
|
||||
for (auto iter = mInteriors.begin(); iter != mInteriors.end(); ++iter)
|
||||
{
|
||||
Ptr ptr = getPtrAndCache(name, iter->second);
|
||||
Ptr ptr = getPtrAndCache(name, *iter->second);
|
||||
if (!ptr.isEmpty())
|
||||
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)
|
||||
{
|
||||
PtrCollector visitor;
|
||||
if (forEachInStore(id, visitor, mInteriors))
|
||||
forEachInStore(id, visitor, mExteriors);
|
||||
forEachInStore(id, visitor, mCells);
|
||||
return visitor.mPtrs;
|
||||
}
|
||||
|
||||
|
@ -399,12 +401,7 @@ int MWWorld::WorldModel::countSavedGameRecords() const
|
|||
{
|
||||
int count = 0;
|
||||
|
||||
for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter)
|
||||
if (iter->second.hasState())
|
||||
++count;
|
||||
|
||||
for (std::map<std::pair<int, int>, CellStore>::const_iterator iter(mExteriors.begin()); iter != mExteriors.end();
|
||||
++iter)
|
||||
for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
|
||||
if (iter->second.hasState())
|
||||
++count;
|
||||
|
||||
|
@ -413,14 +410,7 @@ int MWWorld::WorldModel::countSavedGameRecords() 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)
|
||||
if (iter->second.hasState())
|
||||
{
|
||||
writeCell(writer, iter->second);
|
||||
progress.increaseProgress();
|
||||
}
|
||||
|
||||
for (auto iter(mInteriors.begin()); iter != mInteriors.end(); ++iter)
|
||||
for (auto iter(mCells.begin()); iter != mCells.end(); ++iter)
|
||||
if (iter->second.hasState())
|
||||
{
|
||||
writeCell(writer, iter->second);
|
||||
|
|
|
@ -42,8 +42,9 @@ namespace MWWorld
|
|||
typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache;
|
||||
const MWWorld::ESMStore& mStore;
|
||||
ESM::ReadersCache& mReaders;
|
||||
mutable std::map<std::string, CellStore, Misc::StringUtils::CiComp> mInteriors;
|
||||
mutable std::map<std::pair<int, int>, CellStore> mExteriors;
|
||||
mutable std::unordered_map<ESM::RefId, CellStore> mCells;
|
||||
mutable std::map<std::string, CellStore*, Misc::StringUtils::CiComp> mInteriors;
|
||||
mutable std::map<std::pair<int, int>, CellStore*> mExteriors;
|
||||
IdCache mIdCache;
|
||||
std::size_t mIdCacheIndex = 0;
|
||||
std::unordered_map<ESM::RefNum, Ptr> mPtrIndex;
|
||||
|
@ -91,9 +92,7 @@ namespace MWWorld
|
|||
template <typename Fn>
|
||||
void forEachLoadedCellStore(Fn&& fn)
|
||||
{
|
||||
for (auto& [_, store] : mInteriors)
|
||||
fn(store);
|
||||
for (auto& [_, store] : mExteriors)
|
||||
for (auto& [_, store] : mCells)
|
||||
fn(store);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue