From 19d87c78f272f4f78b35d1e2e5fd2e515a835b47 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 17 Dec 2015 23:59:18 +0100 Subject: [PATCH] Add CellStore::forEachConst --- apps/openmw/mwworld/cellstore.cpp | 18 +++++++++--------- apps/openmw/mwworld/cellstore.hpp | 30 +++++++++++++++++++++++++----- apps/openmw/mwworld/worldimp.cpp | 14 +++++++------- apps/openmw/mwworld/worldimp.hpp | 4 ++-- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 2429a83a7d..c4ab9f316f 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -350,11 +350,12 @@ namespace MWWorld return searchConst (id).isEmpty(); } + template struct SearchVisitor { - MWWorld::Ptr mFound; + PtrType mFound; std::string mIdToFind; - bool operator()(const MWWorld::Ptr& ptr) + bool operator()(const PtrType& ptr) { if (ptr.getCellRef().getRefId() == mIdToFind) { @@ -367,19 +368,18 @@ namespace MWWorld Ptr CellStore::search (const std::string& id) { - SearchVisitor searchVisitor; + SearchVisitor searchVisitor; searchVisitor.mIdToFind = id; forEach(searchVisitor); return searchVisitor.mFound; } - Ptr CellStore::searchConst (const std::string& id) const + ConstPtr CellStore::searchConst (const std::string& id) const { - bool oldState = mHasState; - /// \todo address const-issues - Ptr result = const_cast(this)->search(id); - const_cast(this)->mHasState = oldState; - return result; + SearchVisitor searchVisitor; + searchVisitor.mIdToFind = id; + forEachConst(searchVisitor); + return searchVisitor.mFound; } Ptr CellStore::searchViaActorId (int id) diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 7047682fa5..f2cef1859e 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -214,7 +214,7 @@ namespace MWWorld /// containers. /// @note Triggers CellStore hasState flag. - Ptr searchConst (const std::string& id) const; + ConstPtr searchConst (const std::string& id) const; ///< Will return an empty Ptr if cell is not loaded. Does not check references in /// containers. /// @note Does not trigger CellStore hasState flag. Do not modify the returned Ptr! @@ -240,8 +240,9 @@ namespace MWWorld void preload (); ///< Build ID list from content file. - /// Call visitor (ref) for each reference. visitor must return a bool. Returning + /// Call visitor (MWWorld::Ptr) for each reference. visitor must return a bool. Returning /// false will abort the iteration. + /// \note Prefer using forEachConst when possible. /// \attention This function also lists deleted (count 0) objects! /// \return Iteration completed? template @@ -263,6 +264,28 @@ namespace MWWorld return true; } + /// Call visitor (MWWorld::ConstPtr) for each reference. visitor must return a bool. Returning + /// false will abort the iteration. + /// \attention This function also lists deleted (count 0) objects! + /// \return Iteration completed? + template + bool forEachConst (Visitor& visitor) const + { + if (mState != State_Loaded) + return false; + + for (unsigned int i=0; imData, mMergedRefs[i]->mRef)) + continue; + + if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this))) + return false; + } + return true; + } + + /// Call visitor (ref) for each reference of given type. visitor must return a bool. Returning /// false will abort the iteration. /// \attention This function also lists deleted (count 0) objects! @@ -298,9 +321,6 @@ namespace MWWorld return true; } - /// \todo add const version of forEach - - // NOTE: does not account for moved references // Should be phased out when we have const version of forEach inline const CellRefList& getReadOnlyDoors() const diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0969df6caf..56fe2fc3dd 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2805,7 +2805,7 @@ namespace MWWorld return false; } - MWWorld::Ptr World::getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ) + MWWorld::ConstPtr World::getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ) { if ( ptr.getCell()->isExterior() ) { return getClosestMarkerFromExteriorPosition(mPlayer->getLastKnownExteriorPosition(), id); @@ -2817,7 +2817,7 @@ namespace MWWorld std::set< std::string >checkedCells; std::set< std::string >currentCells; std::set< std::string >nextCells; - MWWorld::Ptr closestMarker; + MWWorld::ConstPtr closestMarker; nextCells.insert( ptr.getCell()->getCell()->mName ); while ( !nextCells.empty() ) { @@ -2861,8 +2861,8 @@ namespace MWWorld return MWWorld::Ptr(); } - MWWorld::Ptr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) { - MWWorld::Ptr closestMarker; + MWWorld::ConstPtr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) { + MWWorld::ConstPtr closestMarker; float closestDistance = std::numeric_limits::max(); std::vector markers; @@ -2887,7 +2887,7 @@ namespace MWWorld void World::teleportToClosestMarker (const MWWorld::Ptr& ptr, const std::string& id) { - MWWorld::Ptr closestMarker = getClosestMarker( ptr, id ); + MWWorld::ConstPtr closestMarker = getClosestMarker( ptr, id ); if ( closestMarker.isEmpty() ) { @@ -3047,13 +3047,13 @@ namespace MWWorld void World::confiscateStolenItems(const Ptr &ptr) { - MWWorld::Ptr prisonMarker = getClosestMarker( ptr, "prisonmarker" ); + MWWorld::ConstPtr prisonMarker = getClosestMarker( ptr, "prisonmarker" ); if ( prisonMarker.isEmpty() ) { std::cerr << "Failed to confiscate items: no closest prison marker found." << std::endl; return; } - std::string prisonName = prisonMarker.mRef->mRef.getDestCell(); + std::string prisonName = prisonMarker.getCellRef().getDestCell(); if ( prisonName.empty() ) { std::cerr << "Failed to confiscate items: prison marker not linked to prison interior" << std::endl; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7132132874..7d67395cfd 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -165,8 +165,8 @@ namespace MWWorld float feetToGameUnits(float feet); - MWWorld::Ptr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ); - MWWorld::Ptr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ); + MWWorld::ConstPtr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ); + MWWorld::ConstPtr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ); public: