From 57e3e165173cb0b4ca655b59202ff245f750b0e8 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 12 Jul 2015 10:34:00 +0200 Subject: [PATCH] Added check to avoid possible object deletion bug Objects must not be deleted while iterating through their list --- src/object/object_manager.cpp | 7 +++++-- src/object/object_manager.h | 26 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/object/object_manager.cpp b/src/object/object_manager.cpp index 99177c00..7dc2d32f 100644 --- a/src/object/object_manager.cpp +++ b/src/object/object_manager.cpp @@ -55,6 +55,9 @@ bool CObjectManager::DeleteObject(CObject* instance) { assert(instance != nullptr); + if (m_objectsIteratingUserCount > 0) + throw std::logic_error("Trying to delete object while holding iterators to objects map!"); + // TODO: temporarily... auto oldObj = dynamic_cast(instance); if (oldObj != nullptr) @@ -198,7 +201,7 @@ CObject* CObjectManager::Radar(CObject* pThis, std::vector type, flo float iAngle; if (pThis != nullptr) { - iPos = pThis->GetPosition(0); + iPos = pThis->GetPosition(); iAngle = pThis->GetAngleY(0); iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI } @@ -305,7 +308,7 @@ CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float if ( std::find(type.begin(), type.end(), oType) == type.end() && type.size() > 0 ) continue; - oPos = pObj->GetPosition(0); + oPos = pObj->GetPosition(); d = Math::DistanceProjected(iPos, oPos); if ( d < minDist || d > maxDist ) continue; // too close or too far? diff --git a/src/object/object_manager.h b/src/object/object_manager.h index 5353df6e..8f657515 100644 --- a/src/object/object_manager.h +++ b/src/object/object_manager.h @@ -92,7 +92,22 @@ private: class CObjectContainerProxy { +private: + friend class CObjectManager; + + inline CObjectContainerProxy(const CObjectMap& map, int& userCount) + : m_map(map) + , m_mapUserCount(userCount) + { + m_mapUserCount++; + } + public: + inline ~CObjectContainerProxy() + { + m_mapUserCount--; + } + inline CObjectIteratorProxy begin() const { return CObjectIteratorProxy(m_map.begin()); @@ -102,15 +117,9 @@ public: return CObjectIteratorProxy(m_map.end()); } -private: - friend class CObjectManager; - - inline CObjectContainerProxy(const CObjectMap& map) - : m_map(map) - {} - private: const CObjectMap& m_map; + int& m_mapUserCount; }; /** @@ -163,7 +172,7 @@ public: //! Returns all objects inline CObjectContainerProxy GetAllObjects() { - return CObjectContainerProxy(m_objects); + return CObjectContainerProxy(m_objects, m_objectsIteratingUserCount); } //! Finds an object, like radar() in CBot @@ -233,6 +242,7 @@ public: protected: CObjectMap m_objects; + int m_objectsIteratingUserCount; std::unique_ptr m_objectFactory; int m_nextId; };