diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index a7cfae503e..fdb2a7274f 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -208,7 +208,7 @@ namespace MWClass } newPtr.getCellRef().unsetRefNum(); newPtr.getRefData().setLuaScripts(nullptr); - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr); + MWBase::Environment::get().getWorldModel()->registerPtr(newPtr); return newPtr; } @@ -229,7 +229,7 @@ namespace MWClass newPtr = MWWorld::Ptr(cell.insert(ref), &cell); } ptr.getRefData().setLuaScripts(nullptr); - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(newPtr); + MWBase::Environment::get().getWorldModel()->registerPtr(newPtr); return newPtr; } diff --git a/apps/openmw/mwlua/cellbindings.cpp b/apps/openmw/mwlua/cellbindings.cpp index a8e448aa6c..e961168bee 100644 --- a/apps/openmw/mwlua/cellbindings.cpp +++ b/apps/openmw/mwlua/cellbindings.cpp @@ -83,7 +83,7 @@ namespace MWLua auto visitor = [&](const MWWorld::Ptr& ptr) { if (ptr.getRefData().isDeleted()) return true; - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr); + MWBase::Environment::get().getWorldModel()->registerPtr(ptr); if (getLiveCellRefType(ptr.mRef) == ptr.getType()) res->push_back(getId(ptr)); return true; diff --git a/apps/openmw/mwlua/engineevents.cpp b/apps/openmw/mwlua/engineevents.cpp index 7c1342aefe..0c5abe6cef 100644 --- a/apps/openmw/mwlua/engineevents.cpp +++ b/apps/openmw/mwlua/engineevents.cpp @@ -74,7 +74,7 @@ namespace MWLua private: MWWorld::Ptr getPtr(const ESM::RefNum& id) const { - MWWorld::Ptr res = mWorldModel->getPtrRegistry().getOrDefault(id); + MWWorld::Ptr res = mWorldModel->getPtr(id); if (res.isEmpty() && Settings::lua().mLuaDebug) Log(Debug::Verbose) << "Can not find object" << id.toString() << " when calling engine hanglers"; return res; diff --git a/apps/openmw/mwlua/luaevents.cpp b/apps/openmw/mwlua/luaevents.cpp index d96ae63579..b036fea3b6 100644 --- a/apps/openmw/mwlua/luaevents.cpp +++ b/apps/openmw/mwlua/luaevents.cpp @@ -40,7 +40,7 @@ namespace MWLua mGlobalEventBatch.clear(); for (const Local& e : mLocalEventBatch) { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(e.mDest); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorldModel()->getPtr(e.mDest); LocalScripts* scripts = ptr.isEmpty() ? nullptr : ptr.getRefData().getLuaScripts(); if (scripts) scripts->receiveEvent(e.mEventName, e.mEventData); diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 50d4d9c11d..bb84dc7989 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -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()->getPtrRegistry().insert(mPlayer); + MWBase::Environment::get().getWorldModel()->registerPtr(mPlayer); } mWorldView.update(); @@ -299,7 +299,7 @@ namespace MWLua if (localScripts) { mActiveLocalScripts.erase(localScripts); - if (!MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(getId(ptr)).isEmpty()) + if (!MWBase::Environment::get().getWorldModel()->getPtr(getId(ptr)).isEmpty()) mEngineEvents.addToQueue(EngineEvents::OnInactive{ getId(ptr) }); } } @@ -401,7 +401,7 @@ namespace MWLua return; } - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr); + MWBase::Environment::get().getWorldModel()->registerPtr(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()->getPtrRegistry().remove(ptr); + MWBase::Environment::get().getWorldModel()->deregisterPtr(ptr); } void LuaManager::reloadAllScripts() @@ -430,7 +430,7 @@ namespace MWLua mGlobalScripts.load(data); } - for (const auto& [id, ptr] : MWBase::Environment::get().getWorldModel()->getPtrRegistry()) + for (const auto& [id, ptr] : MWBase::Environment::get().getWorldModel()->getPtrRegistryView()) { // Reload local scripts LocalScripts* scripts = ptr.getRefData().getLuaScripts(); if (scripts == nullptr) diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index 5ad80c97eb..5e5c380469 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -497,7 +497,7 @@ namespace MWLua while (it.getType() != -1) { const MWWorld::Ptr& item = *(it++); - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item); + MWBase::Environment::get().getWorldModel()->registerPtr(item); list->push_back(getId(item)); } return ObjectList{ list }; @@ -516,7 +516,7 @@ namespace MWLua { if (item.getCellRef().getRefId() == itemId) { - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item); + MWBase::Environment::get().getWorldModel()->registerPtr(item); return ObjectT(getId(item)); } } @@ -531,7 +531,7 @@ namespace MWLua { if (item.getCellRef().getRefId() == itemId) { - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(item); + MWBase::Environment::get().getWorldModel()->registerPtr(item); list->push_back(getId(item)); } } diff --git a/apps/openmw/mwlua/types/actor.cpp b/apps/openmw/mwlua/types/actor.cpp index d1f0e1ec8c..bf0866bc0f 100644 --- a/apps/openmw/mwlua/types/actor.cpp +++ b/apps/openmw/mwlua/types/actor.cpp @@ -32,8 +32,7 @@ namespace MWLua MWWorld::Ptr itemPtr; if (std::holds_alternative(item)) { - itemPtr = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault( - std::get(item)); + itemPtr = MWBase::Environment::get().getWorldModel()->getPtr(std::get(item)); if (old_it != store.end() && *old_it == itemPtr) return true; // already equipped if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0 @@ -218,7 +217,7 @@ namespace MWLua auto it = store.getSlot(slot); if (it == store.end()) continue; - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(*it); + MWBase::Environment::get().getWorldModel()->registerPtr(*it); if (dynamic_cast(&o)) equipment[slot] = sol::make_object(lua, GObject(*it)); else @@ -234,7 +233,7 @@ namespace MWLua auto it = store.getSlot(slot); if (it == store.end()) return sol::nil; - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(*it); + MWBase::Environment::get().getWorldModel()->registerPtr(*it); if (dynamic_cast(&o)) return sol::make_object(lua, GObject(*it)); else diff --git a/apps/openmw/mwlua/worldview.cpp b/apps/openmw/mwlua/worldview.cpp index 80f836c73b..f5699dff89 100644 --- a/apps/openmw/mwlua/worldview.cpp +++ b/apps/openmw/mwlua/worldview.cpp @@ -58,7 +58,7 @@ namespace MWLua void WorldView::objectAddedToScene(const MWWorld::Ptr& ptr) { - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr); + MWBase::Environment::get().getWorldModel()->registerPtr(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()->getPtrRegistry().setLastGenerated(esm.getFormId(true)); + MWBase::Environment::get().getWorldModel()->setLastGeneratedRefNum(esm.getFormId(true)); } void WorldView::save(ESM::ESMWriter& esm) const { esm.writeHNT("LUAW", mSimulationTime); - esm.writeFormId(MWBase::Environment::get().getWorldModel()->getPtrRegistry().getLastGenerated(), true); + esm.writeFormId(MWBase::Environment::get().getWorldModel()->getLastGeneratedRefNum(), true); } void WorldView::ObjectGroup::updateList() diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index d95f9c40ae..60bf58953a 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -63,7 +63,7 @@ namespace if (pair.second.empty()) return MWWorld::Ptr(); else if (pair.first.hasContentFile()) - return MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(pair.first); + return MWBase::Environment::get().getWorldModel()->getPtr(pair.first); return MWBase::Environment::get().getWorld()->searchPtr(pair.second, false); } }; diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index fef4ecb9c8..957f8174f6 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -272,7 +272,7 @@ namespace iter->mData.enable(); MWBase::Environment::get().getWorld()->disable(ptr); } - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(ptr); + MWBase::Environment::get().getWorldModel()->registerPtr(ptr); return; } @@ -287,7 +287,7 @@ namespace collection.mList.push_back(ref); MWWorld::LiveCellRefBase* base = &collection.mList.back(); - MWBase::Environment::get().getWorldModel()->getPtrRegistry().insert(MWWorld::Ptr(base, cellstore)); + MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(base, cellstore)); } // this function allows us to link a CellRefList to the associated recNameInt, and apply a function @@ -440,8 +440,7 @@ 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()->getPtrRegistry().insert( - MWWorld::Ptr(object.getBase(), cellToMoveTo)); + MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(object.getBase(), cellToMoveTo)); MovedRefTracker::iterator found = mMovedHere.find(object.getBase()); if (found != mMovedHere.end()) @@ -1036,7 +1035,7 @@ namespace MWWorld } // Search for the reference. It might no longer exist if its content file was removed. - Ptr movedRef = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(refnum); + Ptr movedRef = MWBase::Environment::get().getWorldModel()->getPtr(refnum); if (movedRef.isEmpty()) { Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index ee6f3cc1ab..28777656c8 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -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()->getPtrRegistry().insert(newPtr); + MWBase::Environment::get().getWorldModel()->registerPtr(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()->getPtrRegistry().insert(newPtr); + MWBase::Environment::get().getWorldModel()->registerPtr(newPtr); if (hasInventoryStore(newPtr)) getInventoryStore(newPtr).setActor(newPtr); return newPtr; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 62285c29a6..5de939b6e9 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -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()->getPtrRegistry().insert(item); + MWBase::Environment::get().getWorldModel()->registerPtr(item); // we may have copied an item from the world, so reset a few things first item.getRefData().setBaseNode( diff --git a/apps/openmw/mwworld/ptr.cpp b/apps/openmw/mwworld/ptr.cpp index 2a64507348..1421b51a2a 100644 --- a/apps/openmw/mwworld/ptr.cpp +++ b/apps/openmw/mwworld/ptr.cpp @@ -24,7 +24,7 @@ namespace MWWorld SafePtr::SafePtr(const Ptr& ptr) : mId(ptr.getCellRef().getRefNum()) , mPtr(ptr) - , mLastUpdate(MWBase::Environment::get().getWorldModel()->getPtrRegistry().getRevision()) + , mLastUpdate(MWBase::Environment::get().getWorldModel()->getPtrRegistryRevision()) { } @@ -39,11 +39,11 @@ namespace MWWorld void SafePtr::update() const { - const PtrRegistry& registry = MWBase::Environment::get().getWorldModel()->getPtrRegistry(); - if (mLastUpdate != registry.getRevision()) + const WorldModel& worldModel = *MWBase::Environment::get().getWorldModel(); + if (mLastUpdate != worldModel.getPtrRegistryRevision()) { - mPtr = registry.getOrDefault(mId); - mLastUpdate = registry.getRevision(); + mPtr = worldModel.getPtr(mId); + mLastUpdate = worldModel.getPtrRegistryRevision(); } } } diff --git a/apps/openmw/mwworld/ptrregistry.hpp b/apps/openmw/mwworld/ptrregistry.hpp index 9acb3df3ca..c40ea8e434 100644 --- a/apps/openmw/mwworld/ptrregistry.hpp +++ b/apps/openmw/mwworld/ptrregistry.hpp @@ -20,7 +20,7 @@ namespace MWWorld auto end() const { return mIndex.cend(); } - Ptr getOrDefault(ESM::RefNum refNum) const + Ptr getOrEmpty(ESM::RefNum refNum) const { const auto it = mIndex.find(refNum); if (it != mIndex.end()) @@ -54,6 +54,22 @@ namespace MWWorld std::unordered_map mIndex; ESM::RefNum mLastGenerated; }; + + class PtrRegistryView + { + public: + explicit PtrRegistryView(const PtrRegistry& ref) + : mPtr(&ref) + { + } + + auto begin() const { return mPtr->begin(); } + + auto end() const { return mPtr->end(); } + + private: + const PtrRegistry* mPtr; + }; } #endif diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 681e623d34..5338980299 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1853,8 +1853,7 @@ namespace MWWorld facedObject = rayToObject.mHitObject; if (facedObject.isEmpty() && rayToObject.mHitRefnum.isSet()) - facedObject - = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(rayToObject.mHitRefnum); + facedObject = MWBase::Environment::get().getWorldModel()->getPtr(rayToObject.mHitRefnum); if (rayToObject.mHit) mDistanceToFacedObject = (rayToObject.mRatio * maxDistance) - camDist; else @@ -1871,8 +1870,7 @@ namespace MWWorld res.mHitNormal = rayRes.mHitNormalWorld; res.mHitObject = rayRes.mHitObject; if (res.mHitObject.isEmpty() && rayRes.mHitRefnum.isSet()) - res.mHitObject - = MWBase::Environment::get().getWorldModel()->getPtrRegistry().getOrDefault(rayRes.mHitRefnum); + res.mHitObject = MWBase::Environment::get().getWorldModel()->getPtr(rayRes.mHitRefnum); return res.mHit; } diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 53a46c78d1..cdbc458022 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -54,7 +54,19 @@ namespace MWWorld Ptr getPtr(const ESM::RefId& name); - PtrRegistry& getPtrRegistry() { return mPtrRegistry; } + Ptr getPtr(ESM::RefNum refNum) const { return mPtrRegistry.getOrEmpty(refNum); } + + PtrRegistryView getPtrRegistryView() const { return PtrRegistryView(mPtrRegistry); } + + ESM::RefNum getLastGeneratedRefNum() const { return mPtrRegistry.getLastGenerated(); } + + void setLastGeneratedRefNum(ESM::RefNum v) { mPtrRegistry.setLastGenerated(v); } + + std::size_t getPtrRegistryRevision() const { return mPtrRegistry.getRevision(); } + + void registerPtr(const Ptr& ptr) { mPtrRegistry.insert(ptr); } + + void deregisterPtr(const Ptr& ptr) { mPtrRegistry.remove(ptr); } template void forEachLoadedCellStore(Fn&& fn)