Original Post
std::list<IWorldObject*>::iterator it;
for(it = objects.begin(); it != objects.end(); it++){
(*it)->Update();
}
std::list<IWorldObject*>::iterator it;
for(it = objects.begin(); it != objects.end(); it++){
(*it)->Update();
}
Quote:How exactly do the objects remove themselves from the list? Perhaps you could post that code so we could see what it is exactly that you're doing.
Original post by squashed_bug
*** Source Snippet Removed ***
The problem is (*it)->Update() may remove itself from the objects list, if this occurs on the last element in the list then the iterator becomes invalid and when the iterator is incremented the "list iterator not incrementable" assertion fails.
Anyway to work around this?
for (...::iterator it = objects.begin(); it != objects.end(); ) { if ((*it)->Update()) { ++it; } else { delete *it; it = objects.erase(it); }}An even better alternative would be to make use of the 'erase-remove' idiom. However, we begin to see a problem with your current method; the 'raw' pointers that you're storing are not self-managing, and having to delete them manually complicates things and leaves a great deal of room for error. Fortunately, there's a solution to that problem too :)
std::list<IWorldObject*>::iterator it, jt; for(it = objects.begin(), jt = it, jt++; it != objects.end(); it = jt++){ (*it)->Update(); if(jt == objects.end()) break; }class IWorldObject;class World : public Engine::ITask{private: std::list<IDrawable*> drawables; std::list<IWorldObject*> objects;public: void Update(); ICamera *camera; void AddDrawable(IDrawable *d); void AddObject(IWorldObject *object); void RemoveObject(IWorldObject *object); void RemoveDrawable(IDrawable *d);};class IWorldObject : public Physics::IPhysicalObject{public: World *world; IWorldObject(World *world); ~IWorldObject();};#include "engine.h"void World::Update(){ std::list<IWorldObject*>::iterator it, jt; for(it = objects.begin(), jt = it, jt++; it != objects.end(); it = jt++){ (*it)->Update(); if(jt == objects.end()) break; } // Draw the objects std::list<IDrawable*>::iterator kt; glLoadIdentity(); camera->SetView(); for(kt = drawables.begin(); kt != drawables.end(); kt++){ glPushMatrix(); (*kt)->Draw(); glPopMatrix(); }}void World::AddDrawable(IDrawable *d){ drawables.push_back(d);}void World::AddObject(IWorldObject *object){ AddDrawable(object); objects.push_back(object);}void World::RemoveObject(IWorldObject *object){ RemoveDrawable(object); objects.remove(object);}void World::RemoveDrawable(IDrawable *d){ drawables.remove(d);}IWorldObject::IWorldObject(World *world){ this->world = world; world->AddObject(this);}IWorldObject::~IWorldObject(){ world->RemoveObject(this);}// note: conc is a sub class of IWorldObjectvoid Conc::Update(){ if(isExploded){ delete(this); // or isAlive = true; } else { if(timer.Expired()) Explode(); }}delete(this)on the member function of an object that is stored in a container would cause a disastrous double-delete if it were not that you are storing only pointers, not objects.Quote:
Original post by squashed_bug
The problem is (*it)->Update() may remove itself from the objects list
// return true if alive after the update.bool IWorldObject::Update();typedef boost::shared_ptr<IWorldObject> objhandle;bool aliveObject(objhandle& handle) { return handle->Update();}std::list<objhandle> objects;objects.erase(std::remove_if(objects.begin(), objects.end(), std::not1(aliveObject)), objects.end());
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more