Re: Was: Xapobj and houses Now: mobile_activity is bad!

From: Patrick Dughi (dughi@imaxx.net)
Date: 09/20/99


>
> 4.  How about something like this (pseudocode, unchecked, variables names will
> differ)...
>
> for (currmob = top_of_table; *currmob; currmob = nextmob) {
>   nextmob = currmob->next;
>
>   /* Main Mob Code goes in here */
>
>   if (argument == REMOVE_PLAYER) { /* <--- Or something like that. */
>     if (player_to_be_removed == nextmob)
>       nextmob = nextmov->next;
>
>     /* Code to remove player in here. */
>   }
>
>   /* Rest of Mob Code goes in here */
> }

        Matter of fact, I thought of this, but beacause I was in a hurry,
I didn't have time to jot this idea down as one of the non functional
ones.  Let's first assume you're not running mobprogs or spec_procs
which both allow you to cause instant extraction of a charater,
because there's no good way to check if a char exists or not without
recreating the entire character_index and restarting your for loop
from the top.  This would mean that you would have to traverse the list at
least once for every mob until such a time that a given mob does not
remove someone (which means multiple mob_activity cycles for that mob,
and all those previous to it). Let's say though that aside from those
difficult to check circumstances, that we have a mob whos type extracts
mobs.  Now, we can monitor this behavior pretty easily, say we have 5 mobs
in a room, and the first simply purges the room.  So, mob1 exists, but the
next mobs in the character list are all gone - mobs2 through mob5.  We had
previously saved our next char as next_char=mob1->next, however, that was
pointing to mob2.  We see that mob2 has been removed, and from there we go
to next_char=mob2->next ... and suddenly crash beccause we're accessing
information in a structure that has been freed.

        This dealing with extractions in a graceful, and most of all
efficient way is actually a common theme in quite a few forums, and funny
enough the efficient solution I used for my mud was based off of a garbage
collection memory management system.  It seems a little obscured but
here's the pseudo code:

struct list_struct {
  struct char_data *character;
  struct list_struct *next;
}

before game execution:

generate a list of all npcs -> (struct list_struct *) master_list
        (see note below about load_mobile())
also have a null storage list. -> secondary_list
within main game loop:

void our_function() {
   extern struct list_struct *master_list,*secondary_list;
   struct list_struct *current,*temp_list;
   temp_list=master_list;
   while(temp_list) {
     current=temp_list;
        /* could have just said temp_list = temp_list->next, but *shrug*/
     REMOVE_FROM_LIST(current,temp_list,next);
     current->next = secondary_list;
     secondary_list=temp_list;

    /* in extract_char, we also check for existance of character first
        in the master list (which we remove of course) and then in the
        secondary list (which we also remove) If any extractions occur in
        the following structure, we need ->no<- references to that fact
        from within this loop as we're operating only on the head of
        the list */

     perform_mobile_activity(current->character);
   }

   master_list=secondary_list;
}

Your only obligation is then to make sure that in load_mobile or
synonymous functions that you add the entry in master_list.  This can (and
should) be coupled with the addition of the mobile to the character_list.



--> THE PAYOFF <--
The end result of this is that you may extract characters from within your
mobile activity loops without error, whether it's from mob programs,
spec_procs, ..i'm not sure where random or timed dg scripts trigger from,
but i'd recommend placing them in the perform_mobile_activity loop.  This
only requires a bit more memory to make a character list, and that
character list is then reversed each time it is read out.  This should not
cause any trouble for anyone since you should never expect the order of
the character list to remain constant, or have any functions which depend
on it being so. Or you'll crash as if you would if you have the stock
mobile_activity and tried to extract chars :)

        I haven't looked, but I'm sure there's a few more of these rarely
triggered flaws around, like I said though, i'll put out a patch when I
have time, probably later tonight.

        George - this just shooting in the dark, or something that's
already been taken care of?

                                                PjD


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST