Added check to avoid possible object deletion bug

Objects must not be deleted while iterating through their list
master
Piotr Dziwinski 2015-07-12 10:34:00 +02:00
parent fcbbbcb83c
commit 57e3e16517
2 changed files with 23 additions and 10 deletions

View File

@ -55,6 +55,9 @@ bool CObjectManager::DeleteObject(CObject* instance)
{ {
assert(instance != nullptr); assert(instance != nullptr);
if (m_objectsIteratingUserCount > 0)
throw std::logic_error("Trying to delete object while holding iterators to objects map!");
// TODO: temporarily... // TODO: temporarily...
auto oldObj = dynamic_cast<COldObject*>(instance); auto oldObj = dynamic_cast<COldObject*>(instance);
if (oldObj != nullptr) if (oldObj != nullptr)
@ -198,7 +201,7 @@ CObject* CObjectManager::Radar(CObject* pThis, std::vector<ObjectType> type, flo
float iAngle; float iAngle;
if (pThis != nullptr) if (pThis != nullptr)
{ {
iPos = pThis->GetPosition(0); iPos = pThis->GetPosition();
iAngle = pThis->GetAngleY(0); iAngle = pThis->GetAngleY(0);
iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI 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; 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); d = Math::DistanceProjected(iPos, oPos);
if ( d < minDist || d > maxDist ) continue; // too close or too far? if ( d < minDist || d > maxDist ) continue; // too close or too far?

View File

@ -92,7 +92,22 @@ private:
class CObjectContainerProxy class CObjectContainerProxy
{ {
private:
friend class CObjectManager;
inline CObjectContainerProxy(const CObjectMap& map, int& userCount)
: m_map(map)
, m_mapUserCount(userCount)
{
m_mapUserCount++;
}
public: public:
inline ~CObjectContainerProxy()
{
m_mapUserCount--;
}
inline CObjectIteratorProxy begin() const inline CObjectIteratorProxy begin() const
{ {
return CObjectIteratorProxy(m_map.begin()); return CObjectIteratorProxy(m_map.begin());
@ -102,15 +117,9 @@ public:
return CObjectIteratorProxy(m_map.end()); return CObjectIteratorProxy(m_map.end());
} }
private:
friend class CObjectManager;
inline CObjectContainerProxy(const CObjectMap& map)
: m_map(map)
{}
private: private:
const CObjectMap& m_map; const CObjectMap& m_map;
int& m_mapUserCount;
}; };
/** /**
@ -163,7 +172,7 @@ public:
//! Returns all objects //! Returns all objects
inline CObjectContainerProxy GetAllObjects() inline CObjectContainerProxy GetAllObjects()
{ {
return CObjectContainerProxy(m_objects); return CObjectContainerProxy(m_objects, m_objectsIteratingUserCount);
} }
//! Finds an object, like radar() in CBot //! Finds an object, like radar() in CBot
@ -233,6 +242,7 @@ public:
protected: protected:
CObjectMap m_objects; CObjectMap m_objects;
int m_objectsIteratingUserCount;
std::unique_ptr<CObjectFactory> m_objectFactory; std::unique_ptr<CObjectFactory> m_objectFactory;
int m_nextId; int m_nextId;
}; };