Yes, I had the problem of events being created as a result of another event's
execution.
What I did was, in the main loop, events are flagged for deletion rather than
actually being removed.
All incoming events are put into a temporary list.
After the main processing loop, a second loop removes events to be deleted.
Then the temporary list is tacked onto the main queue.

--Palrich.

----- Original Message ----- 
From: "Jeremy Hill" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Tuesday, February 03, 2004 9:09 PM
Subject: Linked lists--new elements introduced outside loop creates problems


> Greetings,
>
> I have implemented a 'wait' mobprogram command that delays execution of a mob
> program for a certain amount of time, much like the 'mpsleep' snippet that is
> out there.  I am doing this with the event system I have created for events 
> such
> as these.  (Pun intended)  Here's what an event looks like.
> struct event
> {
>    struct event * next;
>    union
>    {
>     ...
>     struct prog_event_args  prog;
>       /* etc.... */
>    } event_args;
>
>    sh_int delay;
>    char *comments;
>    void (*fire)(struct event  *);
>    void (*destroy)(struct event *);
>    bool valid;
> };
>
> However, I'm coming across a small problem that I'm not sure how to resolve, 
> and
> wondered if you might have an idea in how to straighten this out.
>
> An event is created with an XXX_event function; in this instance, in
> program_flow: prog_event(ch, (void *)mob, MOB, prog, count+1, timer);
>
> ...and is placed into the 'events' list until it is ready to fire.  It is 
> fired,
> which is a function specific to the event's properties, and then it
> self-destroys, another function.  However, when I create a new event within 
> the
> previous event's fire function, the linked list gets out of whack.  I'll lay 
> out
> some code that'll help explain my problem.
>
> Like mobile_update and the other update routines, events are updated as well:
> void event_update(void)
> {
>    EVENT *ev = NULL, *ev_next = NULL, *ev_last = NULL;
>
>    for(ev = events; ev; ev = ev_next)
>    {
>       ev_next = ev->next;
>
>       if(--ev->delay <= 0)  //Expired, kill it
>       {
>           --> ev->fire(ev); <---
>
>           if(ev_last)       //We're past the first element of the list.
>              ev_last->next = ev_next;
>           else              //First element.
>              events = ev_next;
>
>           --> ev->destroy(ev); <---
>       }
>       else                  //Not ready yet; start from here.
>          ev_last = ev;
>    }
> }
>
> Pretty straightforward stuff, the items between --> <-- are the focus.
> Now, firing a program that is done waiting with ev->fire(ev) (function trimmed
> for brevity):
>
> void fire_prog_event(EVENT * ev)
> {
>     extern void program_flow( sh_int, char *, CHAR_DATA *, OBJ_DATA *,
> ROOM_INDEX_DATA *,
>                               CHAR_DATA *, const void *, const void *, int );
>
> ...
>             if (ev->event_args.prog.mob && ev->event_args.prog.ch &&
>                 ev->event_args.prog.mob->in_room ==
> ev->event_args.prog.ch->in_room)
>             {
>                 program_flow(ev->event_args.prog.prog_code->vnum,
>                              ev->event_args.prog.prog_code->code,
>                              ev->event_args.prog.mob,
>                              NULL,
>                              NULL,
>                              ev->event_args.prog.ch,
>                              NULL, NULL, ev->event_args.prog.line);
>             }
>     }
> }
>
> So if the event's program is still valid--i.e. the mob and ch still exist and
> are in the same room yet--then it'll continue execution with a call to
> program_flow.  This means if there is another wait in the mobprog code, this
> call to program_flow will create a new event to wait again.  As you can see,
> this is all done inside the ev->fire(ev), meaning the linked list is now
> different for the rest of the code in the event_update()'s for loop.
>
> What do you think? I'm thinking I may have to put firing events onto their own
> linked list so as not to disrupt the list of the ones still hatching.  
> However,
> is there a much more elegant solution?
>
>
>
>
> -- 
> ROM mailing list
> [email protected]
> http://www.rom.org/cgi-bin/mailman/listinfo/rom


Reply via email to