mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-25 12:41:01 +00:00
Merge branch 'cellstore_optimize' into 'master'
Optimize CellStore modifications See merge request OpenMW/openmw!3013
This commit is contained in:
commit
42bf639916
@ -430,7 +430,7 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
mMovedHere.insert(std::make_pair(object.getBase(), from));
|
mMovedHere.insert(std::make_pair(object.getBase(), from));
|
||||||
}
|
}
|
||||||
updateMergedRefs();
|
requestMergedRefsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr CellStore::moveTo(const Ptr& object, CellStore* cellToMoveTo)
|
MWWorld::Ptr CellStore::moveTo(const Ptr& object, CellStore* cellToMoveTo)
|
||||||
@ -443,10 +443,6 @@ namespace MWWorld
|
|||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"moveTo: can't move object from a non-loaded cell (how did you get this object anyway?)");
|
"moveTo: can't move object from a non-loaded cell (how did you get this object anyway?)");
|
||||||
|
|
||||||
// Ensure that the object actually exists in the cell
|
|
||||||
if (searchViaRefNum(object.getCellRef().getRefNum()).isEmpty())
|
|
||||||
throw std::runtime_error("moveTo: object is not in this cell");
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
MWBase::Environment::get().getWorldModel()->registerPtr(MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
||||||
|
|
||||||
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
||||||
@ -466,14 +462,14 @@ namespace MWWorld
|
|||||||
originalCell->moveTo(object, cellToMoveTo);
|
originalCell->moveTo(object, cellToMoveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMergedRefs();
|
requestMergedRefsUpdate();
|
||||||
return MWWorld::Ptr(object.getBase(), cellToMoveTo);
|
return MWWorld::Ptr(object.getBase(), cellToMoveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
cellToMoveTo->moveFrom(object, this);
|
cellToMoveTo->moveFrom(object, this);
|
||||||
mMovedToAnotherCell.insert(std::make_pair(object.getBase(), cellToMoveTo));
|
mMovedToAnotherCell.insert(std::make_pair(object.getBase(), cellToMoveTo));
|
||||||
|
|
||||||
updateMergedRefs();
|
requestMergedRefsUpdate();
|
||||||
MWWorld::Ptr ptr(object.getBase(), cellToMoveTo);
|
MWWorld::Ptr ptr(object.getBase(), cellToMoveTo);
|
||||||
const Class& cls = ptr.getClass();
|
const Class& cls = ptr.getClass();
|
||||||
if (cls.hasInventoryStore(ptr))
|
if (cls.hasInventoryStore(ptr))
|
||||||
@ -513,13 +509,19 @@ namespace MWWorld
|
|||||||
const std::map<LiveCellRefBase*, MWWorld::CellStore*>& mMovedToAnotherCell;
|
const std::map<LiveCellRefBase*, MWWorld::CellStore*>& mMovedToAnotherCell;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CellStore::updateMergedRefs()
|
void CellStore::requestMergedRefsUpdate()
|
||||||
|
{
|
||||||
|
mRechargingItemsUpToDate = false;
|
||||||
|
mMergedRefsNeedsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CellStore::updateMergedRefs() const
|
||||||
{
|
{
|
||||||
mMergedRefs.clear();
|
mMergedRefs.clear();
|
||||||
mRechargingItemsUpToDate = false;
|
|
||||||
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
||||||
CellStoreImp::forEachInternal(visitor, *this);
|
CellStoreImp::forEachInternal(visitor, const_cast<CellStore&>(*this));
|
||||||
visitor.merge();
|
visitor.merge();
|
||||||
|
mMergedRefsNeedsUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CellStore::movedHere(const MWWorld::Ptr& ptr) const
|
bool CellStore::movedHere(const MWWorld::Ptr& ptr) const
|
||||||
@ -659,13 +661,6 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ptr CellStore::searchViaRefNum(const ESM::RefNum& refNum)
|
|
||||||
{
|
|
||||||
RefNumSearchVisitor searchVisitor(refNum);
|
|
||||||
forEach(searchVisitor);
|
|
||||||
return searchVisitor.mFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CellStore::getWaterLevel() const
|
float CellStore::getWaterLevel() const
|
||||||
{
|
{
|
||||||
if (isExterior())
|
if (isExterior())
|
||||||
@ -681,6 +676,8 @@ namespace MWWorld
|
|||||||
|
|
||||||
std::size_t CellStore::count() const
|
std::size_t CellStore::count() const
|
||||||
{
|
{
|
||||||
|
if (mMergedRefsNeedsUpdate)
|
||||||
|
updateMergedRefs();
|
||||||
return mMergedRefs.size();
|
return mMergedRefs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +844,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
ESM::visit([&](auto&& cell) { loadRefs(cell, refNumToID); }, mCellVariant);
|
ESM::visit([&](auto&& cell) { loadRefs(cell, refNumToID); }, mCellVariant);
|
||||||
|
|
||||||
updateMergedRefs();
|
requestMergedRefsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CellStore::isExterior() const
|
bool CellStore::isExterior() const
|
||||||
@ -1033,10 +1030,6 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do another update here to make sure objects referred to by MVRF tags can be found
|
|
||||||
// This update is only needed for old saves that used the old copy&delete way of moving objects
|
|
||||||
updateMergedRefs();
|
|
||||||
|
|
||||||
while (reader.isNextSub("MVRF"))
|
while (reader.isNextSub("MVRF"))
|
||||||
{
|
{
|
||||||
reader.cacheSubName();
|
reader.cacheSubName();
|
||||||
@ -1050,7 +1043,7 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search for the reference. It might no longer exist if its content file was removed.
|
// Search for the reference. It might no longer exist if its content file was removed.
|
||||||
Ptr movedRef = searchViaRefNum(refnum);
|
Ptr movedRef = MWBase::Environment::get().getWorldModel()->getPtr(refnum);
|
||||||
if (movedRef.isEmpty())
|
if (movedRef.isEmpty())
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex
|
Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex
|
||||||
|
@ -128,7 +128,7 @@ namespace MWWorld
|
|||||||
mHasState = true;
|
mHasState = true;
|
||||||
CellRefList<T>& list = get<T>();
|
CellRefList<T>& list = get<T>();
|
||||||
LiveCellRefBase* ret = &list.insert(*ref);
|
LiveCellRefBase* ret = &list.insert(*ref);
|
||||||
updateMergedRefs();
|
requestMergedRefsUpdate();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +166,6 @@ namespace MWWorld
|
|||||||
Ptr searchViaActorId(int id);
|
Ptr searchViaActorId(int id);
|
||||||
///< Will return an empty Ptr if cell is not loaded.
|
///< Will return an empty Ptr if cell is not loaded.
|
||||||
|
|
||||||
Ptr searchViaRefNum(const ESM::RefNum& refNum);
|
|
||||||
///< Will return an empty Ptr if cell is not loaded. Does not check references in
|
|
||||||
/// containers.
|
|
||||||
/// @note Triggers CellStore hasState flag.
|
|
||||||
|
|
||||||
float getWaterLevel() const;
|
float getWaterLevel() const;
|
||||||
|
|
||||||
bool movedHere(const MWWorld::Ptr& ptr) const;
|
bool movedHere(const MWWorld::Ptr& ptr) const;
|
||||||
@ -203,6 +198,8 @@ namespace MWWorld
|
|||||||
if (mState != State_Loaded)
|
if (mState != State_Loaded)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mMergedRefsNeedsUpdate)
|
||||||
|
updateMergedRefs();
|
||||||
if (mMergedRefs.empty())
|
if (mMergedRefs.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -230,6 +227,9 @@ namespace MWWorld
|
|||||||
if (mState != State_Loaded)
|
if (mState != State_Loaded)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mMergedRefsNeedsUpdate)
|
||||||
|
updateMergedRefs();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mMergedRefs.size(); ++i)
|
for (unsigned int i = 0; i < mMergedRefs.size(); ++i)
|
||||||
{
|
{
|
||||||
if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef))
|
if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef))
|
||||||
@ -252,6 +252,8 @@ namespace MWWorld
|
|||||||
if (mState != State_Loaded)
|
if (mState != State_Loaded)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mMergedRefsNeedsUpdate)
|
||||||
|
updateMergedRefs();
|
||||||
if (mMergedRefs.empty())
|
if (mMergedRefs.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -373,7 +375,8 @@ namespace MWWorld
|
|||||||
|
|
||||||
// Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from
|
// Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from
|
||||||
// mMovedToAnotherCell
|
// mMovedToAnotherCell
|
||||||
std::vector<LiveCellRefBase*> mMergedRefs;
|
mutable std::vector<LiveCellRefBase*> mMergedRefs;
|
||||||
|
mutable bool mMergedRefsNeedsUpdate = false;
|
||||||
|
|
||||||
// Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point).
|
// Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point).
|
||||||
Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref);
|
Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref);
|
||||||
@ -382,7 +385,8 @@ namespace MWWorld
|
|||||||
void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from);
|
void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from);
|
||||||
|
|
||||||
/// Repopulate mMergedRefs.
|
/// Repopulate mMergedRefs.
|
||||||
void updateMergedRefs();
|
void requestMergedRefsUpdate();
|
||||||
|
void updateMergedRefs() const;
|
||||||
|
|
||||||
// (item, max charge)
|
// (item, max charge)
|
||||||
typedef std::vector<std::pair<LiveCellRefBase*, float>> TRechargingItems;
|
typedef std::vector<std::pair<LiveCellRefBase*, float>> TRechargingItems;
|
||||||
|
@ -1880,14 +1880,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
facedObject = rayToObject.mHitObject;
|
facedObject = rayToObject.mHitObject;
|
||||||
if (facedObject.isEmpty() && rayToObject.mHitRefnum.isSet())
|
if (facedObject.isEmpty() && rayToObject.mHitRefnum.isSet())
|
||||||
{
|
facedObject = MWBase::Environment::get().getWorldModel()->getPtr(rayToObject.mHitRefnum);
|
||||||
for (CellStore* cellstore : mWorldScene->getActiveCells())
|
|
||||||
{
|
|
||||||
facedObject = cellstore->searchViaRefNum(rayToObject.mHitRefnum);
|
|
||||||
if (!facedObject.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rayToObject.mHit)
|
if (rayToObject.mHit)
|
||||||
mDistanceToFacedObject = (rayToObject.mRatio * maxDistance) - camDist;
|
mDistanceToFacedObject = (rayToObject.mRatio * maxDistance) - camDist;
|
||||||
else
|
else
|
||||||
@ -1904,14 +1897,7 @@ namespace MWWorld
|
|||||||
res.mHitNormal = rayRes.mHitNormalWorld;
|
res.mHitNormal = rayRes.mHitNormalWorld;
|
||||||
res.mHitObject = rayRes.mHitObject;
|
res.mHitObject = rayRes.mHitObject;
|
||||||
if (res.mHitObject.isEmpty() && rayRes.mHitRefnum.isSet())
|
if (res.mHitObject.isEmpty() && rayRes.mHitRefnum.isSet())
|
||||||
{
|
res.mHitObject = MWBase::Environment::get().getWorldModel()->getPtr(rayRes.mHitRefnum);
|
||||||
for (CellStore* cellstore : mWorldScene->getActiveCells())
|
|
||||||
{
|
|
||||||
res.mHitObject = cellstore->searchViaRefNum(rayRes.mHitRefnum);
|
|
||||||
if (!res.mHitObject.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res.mHit;
|
return res.mHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user