[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