Add CellStore::forEachConst

openmw-38
scrawl 9 years ago
parent d4eba794c3
commit 19d87c78f2

@ -350,11 +350,12 @@ namespace MWWorld
return searchConst (id).isEmpty(); return searchConst (id).isEmpty();
} }
template <typename PtrType>
struct SearchVisitor struct SearchVisitor
{ {
MWWorld::Ptr mFound; PtrType mFound;
std::string mIdToFind; std::string mIdToFind;
bool operator()(const MWWorld::Ptr& ptr) bool operator()(const PtrType& ptr)
{ {
if (ptr.getCellRef().getRefId() == mIdToFind) if (ptr.getCellRef().getRefId() == mIdToFind)
{ {
@ -367,19 +368,18 @@ namespace MWWorld
Ptr CellStore::search (const std::string& id) Ptr CellStore::search (const std::string& id)
{ {
SearchVisitor searchVisitor; SearchVisitor<MWWorld::Ptr> searchVisitor;
searchVisitor.mIdToFind = id; searchVisitor.mIdToFind = id;
forEach(searchVisitor); forEach(searchVisitor);
return searchVisitor.mFound; return searchVisitor.mFound;
} }
Ptr CellStore::searchConst (const std::string& id) const ConstPtr CellStore::searchConst (const std::string& id) const
{ {
bool oldState = mHasState; SearchVisitor<MWWorld::ConstPtr> searchVisitor;
/// \todo address const-issues searchVisitor.mIdToFind = id;
Ptr result = const_cast<CellStore*>(this)->search(id); forEachConst(searchVisitor);
const_cast<CellStore*>(this)->mHasState = oldState; return searchVisitor.mFound;
return result;
} }
Ptr CellStore::searchViaActorId (int id) Ptr CellStore::searchViaActorId (int id)

@ -214,7 +214,7 @@ namespace MWWorld
/// containers. /// containers.
/// @note Triggers CellStore hasState flag. /// @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 ///< Will return an empty Ptr if cell is not loaded. Does not check references in
/// containers. /// containers.
/// @note Does not trigger CellStore hasState flag. Do not modify the returned Ptr! /// @note Does not trigger CellStore hasState flag. Do not modify the returned Ptr!
@ -240,8 +240,9 @@ namespace MWWorld
void preload (); void preload ();
///< Build ID list from content file. ///< 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. /// false will abort the iteration.
/// \note Prefer using forEachConst when possible.
/// \attention This function also lists deleted (count 0) objects! /// \attention This function also lists deleted (count 0) objects!
/// \return Iteration completed? /// \return Iteration completed?
template<class Visitor> template<class Visitor>
@ -263,6 +264,28 @@ namespace MWWorld
return true; 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<class Visitor>
bool forEachConst (Visitor& visitor) const
{
if (mState != State_Loaded)
return false;
for (unsigned int i=0; i<mMergedRefs.size(); ++i)
{
if (!isAccessible(mMergedRefs[i]->mData, 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 /// Call visitor (ref) for each reference of given type. visitor must return a bool. Returning
/// false will abort the iteration. /// false will abort the iteration.
/// \attention This function also lists deleted (count 0) objects! /// \attention This function also lists deleted (count 0) objects!
@ -298,9 +321,6 @@ namespace MWWorld
return true; return true;
} }
/// \todo add const version of forEach
// NOTE: does not account for moved references // NOTE: does not account for moved references
// Should be phased out when we have const version of forEach // Should be phased out when we have const version of forEach
inline const CellRefList<ESM::Door>& getReadOnlyDoors() const inline const CellRefList<ESM::Door>& getReadOnlyDoors() const

@ -2805,7 +2805,7 @@ namespace MWWorld
return false; 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() ) { if ( ptr.getCell()->isExterior() ) {
return getClosestMarkerFromExteriorPosition(mPlayer->getLastKnownExteriorPosition(), id); return getClosestMarkerFromExteriorPosition(mPlayer->getLastKnownExteriorPosition(), id);
@ -2817,7 +2817,7 @@ namespace MWWorld
std::set< std::string >checkedCells; std::set< std::string >checkedCells;
std::set< std::string >currentCells; std::set< std::string >currentCells;
std::set< std::string >nextCells; std::set< std::string >nextCells;
MWWorld::Ptr closestMarker; MWWorld::ConstPtr closestMarker;
nextCells.insert( ptr.getCell()->getCell()->mName ); nextCells.insert( ptr.getCell()->getCell()->mName );
while ( !nextCells.empty() ) { while ( !nextCells.empty() ) {
@ -2861,8 +2861,8 @@ namespace MWWorld
return MWWorld::Ptr(); return MWWorld::Ptr();
} }
MWWorld::Ptr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) { MWWorld::ConstPtr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) {
MWWorld::Ptr closestMarker; MWWorld::ConstPtr closestMarker;
float closestDistance = std::numeric_limits<float>::max(); float closestDistance = std::numeric_limits<float>::max();
std::vector<MWWorld::Ptr> markers; std::vector<MWWorld::Ptr> markers;
@ -2887,7 +2887,7 @@ namespace MWWorld
void World::teleportToClosestMarker (const MWWorld::Ptr& ptr, void World::teleportToClosestMarker (const MWWorld::Ptr& ptr,
const std::string& id) const std::string& id)
{ {
MWWorld::Ptr closestMarker = getClosestMarker( ptr, id ); MWWorld::ConstPtr closestMarker = getClosestMarker( ptr, id );
if ( closestMarker.isEmpty() ) if ( closestMarker.isEmpty() )
{ {
@ -3047,13 +3047,13 @@ namespace MWWorld
void World::confiscateStolenItems(const Ptr &ptr) void World::confiscateStolenItems(const Ptr &ptr)
{ {
MWWorld::Ptr prisonMarker = getClosestMarker( ptr, "prisonmarker" ); MWWorld::ConstPtr prisonMarker = getClosestMarker( ptr, "prisonmarker" );
if ( prisonMarker.isEmpty() ) if ( prisonMarker.isEmpty() )
{ {
std::cerr << "Failed to confiscate items: no closest prison marker found." << std::endl; std::cerr << "Failed to confiscate items: no closest prison marker found." << std::endl;
return; return;
} }
std::string prisonName = prisonMarker.mRef->mRef.getDestCell(); std::string prisonName = prisonMarker.getCellRef().getDestCell();
if ( prisonName.empty() ) if ( prisonName.empty() )
{ {
std::cerr << "Failed to confiscate items: prison marker not linked to prison interior" << std::endl; std::cerr << "Failed to confiscate items: prison marker not linked to prison interior" << std::endl;

@ -165,8 +165,8 @@ namespace MWWorld
float feetToGameUnits(float feet); float feetToGameUnits(float feet);
MWWorld::Ptr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ); MWWorld::ConstPtr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id );
MWWorld::Ptr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ); MWWorld::ConstPtr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id );
public: public:

Loading…
Cancel
Save