From: Oliver Jowett <oliver@sa-search.massey.ac.nz>
Subject: Re: Events and Ticks
> I did some thinking on this very subject over the weekend. First, I don't
> think that event-based means you get rid of the cascading loops. You still
> have to poll mobs to see if they have events to register.
>
> So, the aggressive function could work like this:
>
> [ char_to_room registers a "new person in room" event on the room ]
> [ char_to_room registers another "new person in room" event on the room ]
>
> [ room_event loop ]
> we realize that the room has an event pending, so we look at it. Since its
> a "new person in room" event, we check for any room reactions (through room
> programs) and we pass the message to each character and object in the room.
> We also delete any other "new person in room" events, since we've handled
> it.
>
> [ mob_event loop ]
> the aggressive mob catches the message and decides that it needs to agress
> on a random person. Purge the event.
You can use a single global event queue, which means you don't have to
run through every room/mob on each pulse.
As an example, here's my current event structure:
/* Event queueing/dequeueing/etc */
typedef void (*ev_callback)(struct _event *ev);
struct _event {
union {
CHAR_DATA *ch;
OBJ_DATA *obj;
ROOM_INDEX_DATA *room;
} item; /* object/char etc. associated with this */
void *param; /* param for the callback */
ev_callback callback; /* callback to call */
int when; /* when event is going to happen (pulseclock) */
struct _event *next; /* next in priority queue */
struct _event *nextitem; /* next in item queue */
struct _event **start; /* pointer to pointer to start of this sublist */
};
The 'next' pointer goes through a global priority queue of events; the
'nextitem' and 'start' pointers are to maintain a list for each
char/room/obj/etc.
In char_data (and obj_data, room_index_data, etc) I have:
EVENT *events;
which is a pointer to the first event concerning this character in the
queue; the nextitem pointers then chain through other events concerning
it. ch->events->start == &ch->events, so that the event update function
can remove an event from the itemlist without knowing the details of the
object it's removing it from.
> I'm sure that there are better ways to do it, but the main point is simple:
> the event-based system waits until the movement cycle is complete before it
> starts agressing.
Yes, exactly.
Oliver
--
"The flames are all long gone / But the pain lingers on..."