mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 03:39:55 +00:00
Move Ptr registry into a separate type
There is no dependency on the rest of the WorldModel state.
This commit is contained in:
parent
16a580eb21
commit
ce91784085
@ -78,7 +78,7 @@ add_openmw_dir (mwworld
|
||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||
store esmstore fallback actionrepair actionsoulgem livecellref actiondoor
|
||||
contentloader esmloader actiontrap cellreflist cellref weather projectilemanager
|
||||
cellpreloader datetimemanager groundcoverstore magiceffects cell
|
||||
cellpreloader datetimemanager groundcoverstore magiceffects cell ptrregistry
|
||||
)
|
||||
|
||||
add_openmw_dir (mwphysics
|
||||
|
@ -208,7 +208,7 @@ namespace MWClass
|
||||
}
|
||||
newPtr.getCellRef().unsetRefNum();
|
||||
newPtr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ namespace MWClass
|
||||
newPtr = MWWorld::Ptr(cell.insert(ref), &cell);
|
||||
}
|
||||
ptr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ namespace MWLua
|
||||
auto visitor = [&](const MWWorld::Ptr& ptr) {
|
||||
if (ptr.getRefData().isDeleted())
|
||||
return true;
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(ptr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr);
|
||||
if (getLiveCellRefType(ptr.mRef) == ptr.getType())
|
||||
res->push_back(getId(ptr));
|
||||
return true;
|
||||
|
@ -74,7 +74,7 @@ namespace MWLua
|
||||
private:
|
||||
MWWorld::Ptr getPtr(const ESM::RefNum& id) const
|
||||
{
|
||||
MWWorld::Ptr res = mWorldModel->getPtr(id);
|
||||
MWWorld::Ptr res = mWorldModel->getPtrRegistry().getOrDefault(id);
|
||||
if (res.isEmpty() && Settings::lua().mLuaDebug)
|
||||
Log(Debug::Verbose) << "Can not find object" << id.toString() << " when calling engine hanglers";
|
||||
return res;
|
||||
|
@ -40,7 +40,7 @@ namespace MWLua
|
||||
mGlobalEventBatch.clear();
|
||||
for (const Local& e : mLocalEventBatch)
|
||||
{
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorldModel()->getPtr(e.mDest);
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(e.mDest);
|
||||
LocalScripts* scripts = ptr.isEmpty() ? nullptr : ptr.getRefData().getLuaScripts();
|
||||
if (scripts)
|
||||
scripts->receiveEvent(e.mEventName, e.mEventData);
|
||||
|
@ -136,7 +136,7 @@ namespace MWLua
|
||||
if (!mPlayer.isInCell() || !newPlayerPtr.isInCell() || mPlayer.getCell() != newPlayerPtr.getCell())
|
||||
{
|
||||
mPlayer = newPlayerPtr; // player was moved to another cell, update ptr in registry
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(mPlayer);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(mPlayer);
|
||||
}
|
||||
|
||||
mWorldView.update();
|
||||
@ -299,7 +299,7 @@ namespace MWLua
|
||||
if (localScripts)
|
||||
{
|
||||
mActiveLocalScripts.erase(localScripts);
|
||||
if (!MWBase::Environment::get().getWorldModel()->getPtr(getId(ptr)).isEmpty())
|
||||
if (!MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(getId(ptr)).isEmpty())
|
||||
mEngineEvents.addToQueue(EngineEvents::OnInactive{ getId(ptr) });
|
||||
}
|
||||
}
|
||||
@ -401,7 +401,7 @@ namespace MWLua
|
||||
return;
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(ptr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr);
|
||||
LocalScripts* scripts = createLocalScripts(ptr);
|
||||
|
||||
scripts->setSerializer(mLocalSerializer.get());
|
||||
@ -409,7 +409,7 @@ namespace MWLua
|
||||
scripts->load(data);
|
||||
|
||||
// LiveCellRef is usually copied after loading, so this Ptr will become invalid and should be deregistered.
|
||||
MWBase::Environment::get().getWorldModel()->deregisterPtr(ptr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().remove(ptr);
|
||||
}
|
||||
|
||||
void LuaManager::reloadAllScripts()
|
||||
@ -430,7 +430,7 @@ namespace MWLua
|
||||
mGlobalScripts.load(data);
|
||||
}
|
||||
|
||||
for (const auto& [id, ptr] : MWBase::Environment::get().getWorldModel()->getAllPtrs())
|
||||
for (const auto& [id, ptr] : MWBase::Environment::get().getWorldModel()->getPtrRegistry())
|
||||
{ // Reload local scripts
|
||||
LocalScripts* scripts = ptr.getRefData().getLuaScripts();
|
||||
if (scripts == nullptr)
|
||||
|
@ -497,7 +497,7 @@ namespace MWLua
|
||||
while (it.getType() != -1)
|
||||
{
|
||||
const MWWorld::Ptr& item = *(it++);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(item);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item);
|
||||
list->push_back(getId(item));
|
||||
}
|
||||
return ObjectList<ObjectT>{ list };
|
||||
@ -516,7 +516,7 @@ namespace MWLua
|
||||
{
|
||||
if (item.getCellRef().getRefId() == itemId)
|
||||
{
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(item);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item);
|
||||
return ObjectT(getId(item));
|
||||
}
|
||||
}
|
||||
@ -531,7 +531,7 @@ namespace MWLua
|
||||
{
|
||||
if (item.getCellRef().getRefId() == itemId)
|
||||
{
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(item);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item);
|
||||
list->push_back(getId(item));
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,8 @@ namespace MWLua
|
||||
MWWorld::Ptr itemPtr;
|
||||
if (std::holds_alternative<ObjectId>(item))
|
||||
{
|
||||
itemPtr = MWBase::Environment::get().getWorldModel()->getPtr(std::get<ObjectId>(item));
|
||||
itemPtr = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(
|
||||
std::get<ObjectId>(item));
|
||||
if (old_it != store.end() && *old_it == itemPtr)
|
||||
return true; // already equipped
|
||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0
|
||||
@ -217,7 +218,7 @@ namespace MWLua
|
||||
auto it = store.getSlot(slot);
|
||||
if (it == store.end())
|
||||
continue;
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(*it);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(*it);
|
||||
if (dynamic_cast<const GObject*>(&o))
|
||||
equipment[slot] = sol::make_object(lua, GObject(*it));
|
||||
else
|
||||
@ -233,7 +234,7 @@ namespace MWLua
|
||||
auto it = store.getSlot(slot);
|
||||
if (it == store.end())
|
||||
return sol::nil;
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(*it);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(*it);
|
||||
if (dynamic_cast<const GObject*>(&o))
|
||||
return sol::make_object(lua, GObject(*it));
|
||||
else
|
||||
|
@ -58,7 +58,7 @@ namespace MWLua
|
||||
|
||||
void WorldView::objectAddedToScene(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(ptr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr);
|
||||
ObjectGroup* group = chooseGroup(ptr);
|
||||
if (group)
|
||||
addToGroup(*group, ptr);
|
||||
@ -81,13 +81,13 @@ namespace MWLua
|
||||
void WorldView::load(ESM::ESMReader& esm)
|
||||
{
|
||||
esm.getHNT(mSimulationTime, "LUAW");
|
||||
MWBase::Environment::get().getWorldModel()->setLastGeneratedRefNum(esm.getFormId(true));
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().setLastGenerated(esm.getFormId(true));
|
||||
}
|
||||
|
||||
void WorldView::save(ESM::ESMWriter& esm) const
|
||||
{
|
||||
esm.writeHNT("LUAW", mSimulationTime);
|
||||
esm.writeFormId(MWBase::Environment::get().getWorldModel()->getLastGeneratedRefNum(), true);
|
||||
esm.writeFormId(MWBase::Environment::get().getWorldModel()->getPtrRegistry().getLastGenerated(), true);
|
||||
}
|
||||
|
||||
void WorldView::ObjectGroup::updateList()
|
||||
|
@ -63,7 +63,7 @@ namespace
|
||||
if (pair.second.empty())
|
||||
return MWWorld::Ptr();
|
||||
else if (pair.first.hasContentFile())
|
||||
return MWBase::Environment::get().getWorldModel()->getPtr(pair.first);
|
||||
return MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(pair.first);
|
||||
return MWBase::Environment::get().getWorld()->searchPtr(pair.second, false);
|
||||
}
|
||||
};
|
||||
|
@ -275,7 +275,7 @@ namespace
|
||||
iter->mData.enable();
|
||||
MWBase::Environment::get().getWorld()->disable(ptr);
|
||||
}
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(ptr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ namespace
|
||||
collection.mList.push_back(ref);
|
||||
|
||||
MWWorld::LiveCellRefBase* base = &collection.mList.back();
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(base, cellstore));
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(MWWorld::Ptr(base, cellstore));
|
||||
}
|
||||
|
||||
// this function allows us to link a CellRefList<T> to the associated recNameInt, and apply a function
|
||||
@ -443,7 +443,8 @@ namespace MWWorld
|
||||
throw std::runtime_error(
|
||||
"moveTo: can't move object from a non-loaded cell (how did you get this object anyway?)");
|
||||
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(
|
||||
MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
||||
|
||||
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
||||
if (found != mMovedHere.end())
|
||||
@ -1041,7 +1042,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
// Search for the reference. It might no longer exist if its content file was removed.
|
||||
Ptr movedRef = MWBase::Environment::get().getWorldModel()->getPtr(refnum);
|
||||
Ptr movedRef = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(refnum);
|
||||
if (movedRef.isEmpty())
|
||||
{
|
||||
Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex
|
||||
|
@ -375,7 +375,7 @@ namespace MWWorld
|
||||
newPtr.getCellRef().unsetRefNum(); // This RefNum is only valid within the original cell of the reference
|
||||
newPtr.getRefData().setCount(count);
|
||||
newPtr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr);
|
||||
if (hasInventoryStore(newPtr))
|
||||
getInventoryStore(newPtr).setActor(newPtr);
|
||||
return newPtr;
|
||||
@ -385,7 +385,7 @@ namespace MWWorld
|
||||
{
|
||||
Ptr newPtr = copyToCellImpl(ptr, cell);
|
||||
ptr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr);
|
||||
if (hasInventoryStore(newPtr))
|
||||
getInventoryStore(newPtr).setActor(newPtr);
|
||||
return newPtr;
|
||||
|
@ -308,7 +308,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(
|
||||
|
||||
// The copy of the original item we just made
|
||||
MWWorld::Ptr item = *it;
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(item);
|
||||
MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item);
|
||||
|
||||
// we may have copied an item from the world, so reset a few things first
|
||||
item.getRefData().setBaseNode(
|
||||
|
@ -24,7 +24,7 @@ namespace MWWorld
|
||||
SafePtr::SafePtr(const Ptr& ptr)
|
||||
: mId(ptr.getCellRef().getRefNum())
|
||||
, mPtr(ptr)
|
||||
, mLastUpdate(MWBase::Environment::get().getWorldModel()->getPtrIndexUpdateCounter())
|
||||
, mLastUpdate(MWBase::Environment::get().getWorldModel()->getPtrRegistry().getRevision())
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,11 +39,11 @@ namespace MWWorld
|
||||
|
||||
void SafePtr::update() const
|
||||
{
|
||||
WorldModel& w = *MWBase::Environment::get().getWorldModel();
|
||||
if (mLastUpdate < w.getPtrIndexUpdateCounter())
|
||||
const PtrRegistry& registry = MWBase::Environment::get().getWorldModel()->getPtrRegistry();
|
||||
if (mLastUpdate < registry.getRevision())
|
||||
{
|
||||
mPtr = w.getPtr(mId);
|
||||
mLastUpdate = w.getPtrIndexUpdateCounter();
|
||||
mPtr = registry.getOrDefault(mId);
|
||||
mLastUpdate = registry.getRevision();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
59
apps/openmw/mwworld/ptrregistry.hpp
Normal file
59
apps/openmw/mwworld/ptrregistry.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef OPENMW_APPS_OPENMW_MWWORLD_PTRREGISTRY_H
|
||||
#define OPENMW_APPS_OPENMW_MWWORLD_PTRREGISTRY_H
|
||||
|
||||
#include "ptr.hpp"
|
||||
|
||||
#include "components/esm3/cellref.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class PtrRegistry
|
||||
{
|
||||
public:
|
||||
std::size_t getRevision() const { return mRevision; }
|
||||
|
||||
ESM::RefNum getLastGenerated() const { return mLastGenerated; }
|
||||
|
||||
auto begin() const { return mIndex.cbegin(); }
|
||||
|
||||
auto end() const { return mIndex.cend(); }
|
||||
|
||||
Ptr getOrDefault(ESM::RefNum refNum) const
|
||||
{
|
||||
const auto it = mIndex.find(refNum);
|
||||
if (it != mIndex.end())
|
||||
return it->second;
|
||||
return Ptr();
|
||||
}
|
||||
|
||||
void setLastGenerated(ESM::RefNum v) { mLastGenerated = v; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
mIndex.clear();
|
||||
mLastGenerated = ESM::RefNum{};
|
||||
mRevision = 0;
|
||||
}
|
||||
|
||||
void insert(const Ptr& ptr)
|
||||
{
|
||||
mIndex[ptr.getCellRef().getOrAssignRefNum(mLastGenerated)] = ptr;
|
||||
++mRevision;
|
||||
}
|
||||
|
||||
void remove(const Ptr& ptr)
|
||||
{
|
||||
mIndex.erase(ptr.getCellRef().getRefNum());
|
||||
++mRevision;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t mRevision = 0;
|
||||
std::unordered_map<ESM::RefNum, Ptr> mIndex;
|
||||
ESM::RefNum mLastGenerated;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1851,7 +1851,8 @@ namespace MWWorld
|
||||
|
||||
facedObject = rayToObject.mHitObject;
|
||||
if (facedObject.isEmpty() && rayToObject.mHitRefnum.isSet())
|
||||
facedObject = MWBase::Environment::get().getWorldModel()->getPtr(rayToObject.mHitRefnum);
|
||||
facedObject
|
||||
= MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(rayToObject.mHitRefnum);
|
||||
if (rayToObject.mHit)
|
||||
mDistanceToFacedObject = (rayToObject.mRatio * maxDistance) - camDist;
|
||||
else
|
||||
@ -1868,7 +1869,8 @@ namespace MWWorld
|
||||
res.mHitNormal = rayRes.mHitNormalWorld;
|
||||
res.mHitObject = rayRes.mHitObject;
|
||||
if (res.mHitObject.isEmpty() && rayRes.mHitRefnum.isSet())
|
||||
res.mHitObject = MWBase::Environment::get().getWorldModel()->getPtr(rayRes.mHitRefnum);
|
||||
res.mHitObject
|
||||
= MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(rayRes.mHitRefnum);
|
||||
return res.mHit;
|
||||
}
|
||||
|
||||
|
@ -82,9 +82,7 @@ MWWorld::CellStore& MWWorld::WorldModel::insertCellStore(const ESM::Cell& cell)
|
||||
|
||||
void MWWorld::WorldModel::clear()
|
||||
{
|
||||
mPtrIndex.clear();
|
||||
mPtrIndexUpdateCounter = 0;
|
||||
mLastGeneratedRefnum = ESM::RefNum{};
|
||||
mPtrRegistry.clear();
|
||||
mInteriors.clear();
|
||||
mExteriors.clear();
|
||||
mCells.clear();
|
||||
@ -92,27 +90,6 @@ void MWWorld::WorldModel::clear()
|
||||
mIdCacheIndex = 0;
|
||||
}
|
||||
|
||||
void MWWorld::WorldModel::registerPtr(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mPtrIndex[ptr.getCellRef().getOrAssignRefNum(mLastGeneratedRefnum)] = ptr;
|
||||
mPtrIndexUpdateCounter++;
|
||||
}
|
||||
|
||||
void MWWorld::WorldModel::deregisterPtr(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mPtrIndex.erase(ptr.getCellRef().getRefNum());
|
||||
mPtrIndexUpdateCounter++;
|
||||
}
|
||||
|
||||
MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefNum& refNum) const
|
||||
{
|
||||
auto it = mPtrIndex.find(refNum);
|
||||
if (it != mPtrIndex.end())
|
||||
return it->second;
|
||||
else
|
||||
return MWWorld::Ptr();
|
||||
}
|
||||
|
||||
MWWorld::Ptr MWWorld::WorldModel::getPtrAndCache(const ESM::RefId& name, CellStore& cellStore)
|
||||
{
|
||||
Ptr ptr = cellStore.getPtr(name);
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "cellstore.hpp"
|
||||
#include "ptr.hpp"
|
||||
#include "ptrregistry.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
@ -51,17 +52,10 @@ namespace MWWorld
|
||||
CellStore& getCell(std::string_view name, bool forceLoad = true); // interior or named exterior
|
||||
CellStore& getCell(const ESM::RefId& Id, bool forceLoad = true);
|
||||
|
||||
void registerPtr(const MWWorld::Ptr& ptr);
|
||||
void deregisterPtr(const MWWorld::Ptr& ptr);
|
||||
ESM::RefNum getLastGeneratedRefNum() const { return mLastGeneratedRefnum; }
|
||||
void setLastGeneratedRefNum(ESM::RefNum v) { mLastGeneratedRefnum = v; }
|
||||
size_t getPtrIndexUpdateCounter() const { return mPtrIndexUpdateCounter; }
|
||||
const std::unordered_map<ESM::RefNum, Ptr>& getAllPtrs() const { return mPtrIndex; }
|
||||
|
||||
Ptr getPtr(const ESM::RefNum& refNum) const;
|
||||
|
||||
Ptr getPtr(const ESM::RefId& name);
|
||||
|
||||
PtrRegistry& getPtrRegistry() { return mPtrRegistry; }
|
||||
|
||||
template <typename Fn>
|
||||
void forEachLoadedCellStore(Fn&& fn)
|
||||
{
|
||||
@ -90,9 +84,7 @@ namespace MWWorld
|
||||
mutable std::map<ESM::ExteriorCellLocation, CellStore*> mExteriors;
|
||||
std::vector<std::pair<ESM::RefId, CellStore*>> mIdCache;
|
||||
std::size_t mIdCacheIndex = 0;
|
||||
std::unordered_map<ESM::RefNum, Ptr> mPtrIndex;
|
||||
std::size_t mPtrIndexUpdateCounter = 0;
|
||||
ESM::RefNum mLastGeneratedRefnum;
|
||||
PtrRegistry mPtrRegistry;
|
||||
|
||||
CellStore& getOrInsertCellStore(const ESM::Cell& cell);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user