[airstrike] Re: Refcounting?
Eero Tamminen
eero.tamminen at netsonic.fi
Thu Dec 30 16:46:51 EST 2004
Hi,
> > > > There's one strange thing in bonus.c:
> > > > - You changed sprite_kill(s) to refkill(s) and when I looked into
> > > > sprite_kill() function, that indeed only calls refkill(). My
> > > > question is: - Does sprite now get the MSG_KILL always when it's
> > > > destroyed?
> > >
> > > It should send MSG_KILL indeed. I wonder if it does though.. I don't
> > > have the code on this machine, but I will check.
> >
> > sprite_kill() doesn't do anything else except refkill(). refkill()
> > doesn't know anything about sprites...
>
> When you call refcount() you give it a function to use when free'ing the
> object. So in sprite_create() there is a line
>
> s = refcount(type->create_sprite(),type->free_sprite);
>
> which means that type->free_sprite will be evaluated on s when the
> refcount reaches zero. This is not exactly like killing, since it is
> evaluated _after_ everyone
> has released their references, not at the moment of the killing.
Ah, OK.
> > > > The reason why I ask is that the sprite should deref the
> > > > referenced sprite before dying... See bonus_free() and
> > > > bonus_sigget() in the new sprites/bonus.c.
>
> The dereferencing should be done in bonus_free(). The only exception is
> that bonus_free() with _only_ be called when the refcount reaches zero.
> It has to be like that because it's very likely that malloc() gives the
> same memory area back on
> the next call. Since we are identifying objects (dead and alive) with
> their memory
> location all references to the dead object must be gone before we
> create a new one.
> This is fine almost always, except when we want some action to happen
> immediately
> after we kill the sprite (such as the creation of smoke etc). As a
> rule all references should
> be gone after one game frame, but if we need some action in the same
> frame this must
> be implemented as a response to MSG_KILL. However, you must _not_ call
> bonus_free()
> directly there, only refkill(the_sprite_itself).
>
> > Do you mean that the sprite_kill function would be removed from the
> > sprite struct and replaced with handling of the MSG_KILL function?
>
> It should be removed, and replaced by refkill. Using only MSG_KILL is
> an option, but
> I think refkill is fine.
So, should it be like this:
---------
sprite_type_t bonus = {
"bonus",
&bullet_group,
bonus_setup,
bonus_create,
bonus_free,
....
case MSG_SET_TARGET:
/* get pointer to bonus ring */
bs->ring = ref(msg_get_target(msg));
break;
...
case MSG_KILL:
/* bonus expired */
if (refcheck(bs->ring)) {
/* remove bonus ring */
sprite_msg(bs->ring, msg_kill());
}
/* remove bonus */
refkill(s);
break;
...
static void bonus_free(void *s)
{
bonus_sprite_t *bs = (bonus_sprite_t *)s;
if (bs->ring) {
deref(bs->ring);
}
free(s);
}
--------
?
bs->ring will not be deref'd anywhere else except in bonus_free()
(SET_TARGET message should come only once), I'm just wondering whether I
still need to do free(s) in bonus_free() function...?
- Eero
More information about the airstrike
mailing list