Deleting, erasing objects

Hi,

As many I am beginning with OF and also C++, I already manage to create a particle system, from other post I found in the forum http://www.vimeo.com/11396707 but I still dont understand how vector containers, pointers and memory management works.

So I have an emitter class that creates particles on mouse events, its update methods cicles troug the vector using an iterator and check if the particle is dead and remove it

  
void Emitter::update() {  
particles_iterator = particles.begin();  
while (particles_iterator != particles.end()) {  
	particles_iterator->update();  
	if (particles_iterator->dead()) {  
		//cout << "particle just died" << endl;  
		particles_iterator = particles.erase(particles_iterator);  
	}  
	else ++particles_iterator;  
  }  
}  
  

Particles are created using the addParticle method from the Emitter class like this

  
void Emitter::addParticle(int amt, ofxVec2f mMouseLoc, ofxVec2f mMouseVel) {  
for (int i = 0; i < amt; i++) {  
	ofxVec2f loc = mMouseLoc + ofxVec2f(ofRandomf(), ofRandomf()) * 5.0;  
	  
	ofxVec2f velocityOffset = ofxVec2f(ofRandomf(), ofRandomf());  
	velocityOffset *= ofRandom(5.0, 10.0);  
	ofxVec2f vel = mMouseVel * 0.15 + velocityOffset;  
	  
	Particle p(loc, vel);  
	p.color1 = color1;  
	p.color2 = color2;  
	particles.push_back(p);  
   }  
}  
  

So I am not sure if I am taking the necessary steps to delete the particles, is
particles_iterator = particles.erase(particles_iterator); enough? or am I missing something else?

Any bit of explanation and/or links on the subject will be much appreciated

Cheers
rS

Also, because I am very new to C++, I am new to pointers, I know the basics:

  
int &value; // is the memory address of a int  
int *value; // poitns to the address of a int  
*value = 10; // assigns 10 to the address  

But I am not sure how to use this features, is there any source material for best practices, or better, can you recommend how to use them for a particle system?

Again, any help will be much appreciated

Cheers
rS

I myself was strugeling with memory mangment and vectors today. It seems to be you have to manually delete objects and remove them from the vector.

In my DisplayObjectContainer util class I added a clear method like this:

  
void DisplayObjectContainer::clear()  
{  
	for(int i = 0;i<children.size();i++)  
	{  
		DisplayObject* displayObject = children.at(i);  
		displayObject->destroy();  
		delete displayObject;  
	}	  
	children.clear();  
}  

Hope it helps.

Hi Peter, thanks for the reply, but is not very clear, will you be able to elaborate or recommend a similar approach using my code?

My particles are removed from the array when dead() returns true and I use the erase() method, is that enought? or they still exist? do I have to check if the array is empty and if so delete them all? how?

Too many questions!

Cheers
rS

Hello Nardove

as far as I see it, your code is fine.
You only need to specifically free memory that you have allocated on the heap with the “new” command. In other words, you want a “delete x” for every “new x” you call. But this is not the case in your code.

hope this helps.

regards

david

ps. you could also consider not erasing your particles to allow for later reuse. this article might be of interest

Hi david that is exactly what I was looking for, is PERFECT!

Thanks a lot guys!
rS

@david.demainlalune have you manage to work on the object pool concept? I am trying to port my code, but is not working as it should

Cheers
rS

I quickly ported the article’s first “naive” example to the OF dialect.
We have two classes: Particle and ParticlePool.

Particle.h:

  
  
#pragma once  
  
  
#include "ofMain.h"  
class Particle  
{  
    public:  
        Particle();  
        virtual ~Particle();  
  
        void init(const ofPoint& position, const ofPoint& velocity, int lifetime);  
  
        void update();  
  
        void draw();  
  
  
        bool inUse() const { return m_framesLeft > 0; }  
  
  
    private:  
        ofPoint m_position;  
        ofPoint m_velocity;  
  
        int  m_framesLeft;  
  
};  
  

Particle.cpp

  
  
#include "Particle.h"  
  
Particle::Particle()  
{  
    m_framesLeft = 0;  
}  
  
Particle::~Particle()  
{  
    //dtor  
}  
  
void Particle::init(const ofPoint& position, const ofPoint& velocity, int lifetime)  
{  
    m_position = position;  
    m_velocity = velocity;  
    m_framesLeft = lifetime;  
}  
  
void Particle::update()  
{  
    if (inUse())  
    {  
        m_framesLeft--;  
  
        m_position += m_velocity;  
    }  
}  
  
void Particle::draw()  
{  
    if (inUse())  
    {  
        // do somethinng nice here  
        ofCircle(m_position.x, m_position.y, 3);  
    }  
  
}  
  
  

ParticlePool.h:

  
  
#pragma once  
  
#include "Particle.h"  
  
class ParticlePool  
{  
    public:  
        void create(const ofPoint& position, const ofPoint& velocity, int lifetime);  
  
        void update()  
        {  
            for (int i = 0; i < POOL_SIZE; i++)    m_particles[i].update();  
        }  
  
        void draw()  
        {  
            for (int i = 0; i < POOL_SIZE; i++)    m_particles[i].draw();  
        }  
  
    private:  
        static const int POOL_SIZE = 1000;  
        Particle m_particles[POOL_SIZE];  
  
};  
  

ParticlePool.cpp:

  
  
#include "ParticlePool.h"  
  
void ParticlePool::create(const ofPoint& position, const ofPoint& velocity, int lifetime)  
{  
    // find an available particle  
    for (int i = 0; i < POOL_SIZE; i++)  
    {  
        if (!m_particles[i].inUse())  
        {  
            m_particles[i].init(position, velocity, lifetime);  
            return;  
        }  
    }  
}  
  

finally we import ParticlePool in testApp

  
  
#ifndef _TEST_APP  
#define _TEST_APP  
  
  
#include "ofMain.h"  
  
#include "ParticlePool.h"  
  
class testApp : public ofBaseApp{  
  
	public:  
		void setup();  
		void update();  
		void draw();  
  
		void keyPressed  (int key);  
		void keyReleased(int key);  
		void mouseMoved(int x, int y );  
		void mouseDragged(int x, int y, int button);  
		void mousePressed(int x, int y, int button);  
		void mouseReleased(int x, int y, int button);  
		void windowResized(int w, int h);  
  
		ParticlePool m_particlePool;  
  
};  
  
#endif  
  

and plug it in the OF loop

  
  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup(){  
    ofSetFrameRate(25);  
  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
    m_particlePool.update();  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
    m_particlePool.draw();  
}  
  
  
//--------------------------------------------------------------  
void testApp::mouseMoved(int x, int y ){  
  
    float randomVelocityX = ofRandom(-1, 1);  
    float randomVelocityY = ofRandom(-1, 1);  
    m_particlePool.create(ofPoint(x, y), ofPoint(randomVelocityX, randomVelocityY), 100);  
  
}  
  
  

this works for me on linux. If you are on mac, Xcode might complain about the definition of the constant POOL_SIZE. If this is the case, tell me and I will rewrite the definition.

This is the naive, not super optimised version of his article, but it should get you started.

best regards

david