Speedup ESM4 cell loading; load objects from permanent cells (exterior doors in particular)

simplify_debugging
Petr Mikheev 2 years ago
parent b1409182bc
commit ac65246389

@ -760,12 +760,10 @@ namespace MWWorld
template <typename ReferenceInvocable> template <typename ReferenceInvocable>
static void visitCell4References(const ESM4::Cell& cell, ESM::ReadersCache& readers, ReferenceInvocable&& invocable) static void visitCell4References(const ESM4::Cell& cell, ESM::ReadersCache& readers, ReferenceInvocable&& invocable)
{ {
for (const ESM4::Reference& ref : MWBase::Environment::get().getESMStore()->get<ESM4::Reference>()) for (const ESM4::Reference* ref :
MWBase::Environment::get().getESMStore()->get<ESM4::Reference>().getByCell(cell.mId))
{ {
if (ref.mParent == cell.mId) invocable(*ref);
{
invocable(ref);
}
} }
} }

@ -447,6 +447,7 @@ namespace MWWorld
getWritable<ESM::Skill>().setUp(); getWritable<ESM::Skill>().setUp();
getWritable<ESM::MagicEffect>().setUp(); getWritable<ESM::MagicEffect>().setUp();
getWritable<ESM::Attribute>().setUp(); getWritable<ESM::Attribute>().setUp();
getWritable<ESM4::Reference>().preprocessReferences(get<ESM4::Cell>());
} }
void ESMStore::validateRecords(ESM::ReadersCache& readers) void ESMStore::validateRecords(ESM::ReadersCache& readers)

@ -1155,6 +1155,33 @@ namespace MWWorld
} }
MWWorld::TypedDynamicStore<ESM4::Cell>::clearDynamic(); MWWorld::TypedDynamicStore<ESM4::Cell>::clearDynamic();
} }
// ESM4 Reference
//=========================================================================
void Store<ESM4::Reference>::preprocessReferences(const Store<ESM4::Cell>& cells)
{
for (auto& [_, ref] : mStatic)
{
const ESM4::Cell* cell = cells.find(ref.mParent);
if (cell->isExterior() && (cell->mFlags & ESM4::Rec_Persistent))
{
const ESM4::Cell* actualCell
= cells.searchExterior(positionToCellIndex(ref.mPos.pos[0], ref.mPos.pos[1], cell->mParent));
if (actualCell)
ref.mParent = actualCell->mId;
}
mPerCellReferences[ref.mParent].push_back(&ref);
}
}
std::span<const ESM4::Reference* const> Store<ESM4::Reference>::getByCell(ESM::RefId cellId) const
{
auto it = mPerCellReferences.find(cellId);
if (it == mPerCellReferences.end())
return {};
return it->second;
}
} }
template class MWWorld::TypedDynamicStore<ESM::Activator>; template class MWWorld::TypedDynamicStore<ESM::Activator>;

@ -4,6 +4,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <set> #include <set>
#include <span>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -552,6 +553,13 @@ namespace MWWorld
template <> template <>
class Store<ESM4::Reference> : public TypedDynamicStore<ESM4::Reference, ESM::FormId> class Store<ESM4::Reference> : public TypedDynamicStore<ESM4::Reference, ESM::FormId>
{ {
public:
void preprocessReferences(const Store<ESM4::Cell>& cells);
std::span<const ESM4::Reference* const> getByCell(ESM::RefId cellId) const;
private:
std::unordered_map<ESM::RefId, std::vector<ESM4::Reference*>> mPerCellReferences;
}; };
} // end namespace } // end namespace

Loading…
Cancel
Save