Deleting Animations

M

Mark

I'm making a game. I need to maintain a bunch of objects, in this
case animations (explosions and stuff). I've decided to use an STL
vector. From my understanding, I need to declare it as
vector<Animation*> so that I can insert new animations with something
like myAnimations.push_back(new Animation(...)); So that's all fine
and dandy, but what I can't decide on is how to delete this animation
after it's done playing (the explosion should be deleted and removed
from the vector when it's done cycling through all it's frames). I've
been told it's a bad idea to get an object to delete itself, because
then the caller won't know whether or not it still exists, and it's
just a bad design decision. So, would it be best to have some sort of
boolean in my animation object that says something like
"animationComplete", and when set to true the iterator would then
remove it? If so, what would my iterator look like?

for( vector<Animation*>::iterator current = myAnimations.begin();
current != myAnimations.end(); current++ )
{
(*current)->step(); // tells the animation to change frames
and do whatever it needs to do
if( (*current)->animationComplete )
{
current = projectile.erase(current);
delete (*current); // <-- is this right?
continue;
}
(*current)->draw(); // draw it
}

Code looks kind of ugly... is that really the best way of doing it?
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I'm making a game. I need to maintain a bunch of objects, in this
case animations (explosions and stuff). I've decided to use an STL
vector. From my understanding, I need to declare it as
vector<Animation*> so that I can insert new animations with something
like myAnimations.push_back(new Animation(...)); So that's all fine
and dandy, but what I can't decide on is how to delete this animation
after it's done playing (the explosion should be deleted and removed
from the vector when it's done cycling through all it's frames). I've
been told it's a bad idea to get an object to delete itself, because
then the caller won't know whether or not it still exists, and it's
just a bad design decision. So, would it be best to have some sort of
boolean in my animation object that says something like
"animationComplete", and when set to true the iterator would then
remove it? If so, what would my iterator look like?

for( vector<Animation*>::iterator current = myAnimations.begin();
current != myAnimations.end(); current++ )
{
(*current)->step(); // tells the animation to change frames
and do whatever it needs to do
if( (*current)->animationComplete )
{
current = projectile.erase(current);
delete (*current); // <-- is this right?
continue;
}
(*current)->draw(); // draw it
}

Code looks kind of ugly... is that really the best way of doing it?

Is there any special reason why you don't just declare it as
vector<Animation> and add new elements like this:
'myAnimations.push_back(Animation(...))', notice the lack of new?

Then all you have to do is to use erase() on the vector to delete
them, I think it's possible to add a predicate to erase so that it
only erases those where animationComplete is true.
 
M

mos

Mark said:
I'm making a game. I need to maintain a bunch of objects, in this
case animations (explosions and stuff). I've decided to use an STL
vector. From my understanding, I need to declare it as
vector<Animation*> so that I can insert new animations with something
like myAnimations.push_back(new Animation(...)); So that's all fine
and dandy, but what I can't decide on is how to delete this animation
after it's done playing (the explosion should be deleted and removed
from the vector when it's done cycling through all it's frames). I've
been told it's a bad idea to get an object to delete itself, because
then the caller won't know whether or not it still exists, and it's
just a bad design decision. So, would it be best to have some sort of
boolean in my animation object that says something like
"animationComplete", and when set to true the iterator would then
remove it? If so, what would my iterator look like?

for( vector<Animation*>::iterator current = myAnimations.begin();
current != myAnimations.end(); current++ )
{
(*current)->step(); // tells the animation to change frames
and do whatever it needs to do
if( (*current)->animationComplete )
{
current = projectile.erase(current);
delete (*current); // <-- is this right?
continue;
}
(*current)->draw(); // draw it
}

Code looks kind of ugly... is that really the best way of doing it?

I suppose it should be :

delete (*current); // first
current = projectile.erase(current); // second

and I almost use list as
for (it = list.begin(); it != list.end(); )
{
if ((*it).die())
{
delete *it;
it = list.erase(it)
}
else
++it;
}
 
M

mos

Hi
sorry for posting unfinished mail.
I mean you'd better choose list to do it than vector.

mos.
 
R

Roland Pibinger

Is there any special reason why you don't just declare it as
vector<Animation> and add new elements like this:
'myAnimations.push_back(Animation(...))', notice the lack of new?

I guess the reason simply is that he deosn't want to duplicate the
Animation objects. The reason why the original code looks so 'ugly' is
that STL was designed only for values, not for (pointers to) objects.
 
J

Jim Langston

Mark said:
I'm making a game. I need to maintain a bunch of objects, in this
case animations (explosions and stuff). I've decided to use an STL
vector. From my understanding, I need to declare it as
vector<Animation*> so that I can insert new animations with something
like myAnimations.push_back(new Animation(...)); So that's all fine
and dandy, but what I can't decide on is how to delete this animation
after it's done playing (the explosion should be deleted and removed
from the vector when it's done cycling through all it's frames). I've
been told it's a bad idea to get an object to delete itself, because
then the caller won't know whether or not it still exists, and it's
just a bad design decision. So, would it be best to have some sort of
boolean in my animation object that says something like
"animationComplete", and when set to true the iterator would then
remove it? If so, what would my iterator look like?

for( vector<Animation*>::iterator current = myAnimations.begin();
current != myAnimations.end(); current++ )
{
(*current)->step(); // tells the animation to change frames
and do whatever it needs to do
if( (*current)->animationComplete )
{
current = projectile.erase(current);
delete (*current); // <-- is this right?
continue;
}
(*current)->draw(); // draw it
}

Code looks kind of ugly... is that really the best way of doing it?

The way I'm doing it:

// Update ALL the -On-The-Fly- or Fired 'Beams' to NEW positions.
for ( BeamEffectsType::iterator it = Client.BeamEffects.begin(); it !=
Client.BeamEffects.end(); )
{
if ( !(*it).second->Update() )
{
delete (*it).second;
it = Client.BeamEffects.erase(it);
}
else
++it;
}

Although I'm using a map instead of a vector, the same logic should apply.

The only real difference between mine and yours is I have the function call
itself return a boolean. So you could have your step() return bool whether
to delete it or not. Also, your code is not removing the element from the
vector, which it needs to.
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I guess the reason simply is that he deosn't want to duplicate the
Animation objects. The reason why the original code looks so 'ugly' is
that STL was designed only for values, not for (pointers to) objects.

I asked since in his original post he said that he wanted to use it
like this:

myAnimations.push_back(new Animation(...));

notice that he creates the object in the push_back, in which case my
solution would be just as good (or better).
 
R

Roland Pibinger

I asked since in his original post he said that he wanted to use it
like this:

myAnimations.push_back(new Animation(...));

notice that he creates the object in the push_back, in which case my
solution would be just as good (or better).

Not quite. Your solution copies the new Animation object into the
vector and may copy all other objects in the vector due to relocation.
The pointer solution never copies Animation objects, just pointers.
Moreover, since Animation seems to be an object in the OO sense it may
be semantically problematic to duplicate these objects, i.e. the copy
constructor probably should private.
 
D

dave_mikesell

I'm making a game. I need to maintain a bunch of objects, in this
case animations (explosions and stuff). I've decided to use an STL
vector. From my understanding, I need to declare it as
vector<Animation*> so that I can insert new animations with something
like myAnimations.push_back(new Animation(...)); So that's all fine
and dandy, but what I can't decide on is how to delete this animation
after it's done playing (the explosion should be deleted and removed
from the vector when it's done cycling through all it's frames).

Why? Do you only use the explosion once in the entire game? You're
going to need a Cray to run your game if you allocate/load/delete
animations every time you play them.
 
M

Mark

Is there any special reason why you don't just declare it as
vector<Animation> and add new elements like this:
'myAnimations.push_back(Animation(...))', notice the lack of new?

Then all you have to do is to use erase() on the vector to delete
them, I think it's possible to add a predicate to erase so that it
only erases those where animationComplete is true.

heh. I was just thinking about that, and I asked my friend if it was
possible, but he said it was necessary to use "new". Shows how much
he knows :)
This will help, thank you!
 
M

Mark

"Mark" <[email protected]>
??????:[email protected]...






I suppose it should be :

delete (*current); // first
current = projectile.erase(current); // second

and I almost use list as
for (it = list.begin(); it != list.end(); )
{
if ((*it).die())
{
delete *it;
it = list.erase(it)
}
else
++it;
}

I guess it looks nicer without the continue; statement. Thanks!
 
M

Mark

Hi
sorry for posting unfinished mail.
I mean you'd better choose list to do it than vector.

mos.

I was debating whether I should use a list or a vector... I was
thinking of ways I could get the animation to delete itself in which
case it would require random access, and I ought to use a vector...but
since I'm only iterating through it now, you're quite right. Thanks.
 
M

Mark

I guess the reason simply is that he deosn't want to duplicate the
Animation objects. The reason why the original code looks so 'ugly' is
that STL was designed only for values, not for (pointers to) objects.

Uhh..no, I was just being dumb. The animations need to be duplicated
I think because they have different values. Inside the animation
object is a pointer to an image, so there is only one copy of the
image regardless (hopefully), but the x,y values and stuff need to be
independent for each animation.
 
M

Mark

Why? Do you only use the explosion once in the entire game? You're
going to need a Cray to run your game if you allocate/load/delete
animations every time you play them.

Well, like I said, it's not loading the actual image file each time.
But it is creating a new animation object each time something
explodes, however, it's only assigning it a pre-loaded image and an
x,y value. (That's okay, isn't it?)
 
D

Daniel Oberhoff

Not quite. Your solution copies the new Animation object into the
vector and may copy all other objects in the vector due to relocation.
The pointer solution never copies Animation objects, just pointers.
Moreover, since Animation seems to be an object in the OO sense it may
be semantically problematic to duplicate these objects, i.e. the copy
constructor probably should private.

How about boost::shared_ptr? A quick test shows that
std::list<shared_ptr<myclass> > works as expected.

If not familiar: boost is a pool of c++ libraries (http://www.boost.org) that hope to make it
into the standard. I think shared pointer is way up on the candidate
list. It is wrapped around your pointer like so:

boost::shared_ptr<myclass> p(new myclass(...));
std::list< boost::shared_ptr<myclass> > list;
list.push_back(p);

from there on that pointer is reference counted, so every "copy" will
point to the same object, and when there are no more copies (including
the first instance) the object is deleted autmagically. So

list.pop_back()

will actually delete the object, provided there is no other shared_ptr
holding a reference to it anymore.


cheers

daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top