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:
parent
36502eaf75
commit
96e42d1666
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user