/************************************************************************** * # # # ## # # ### ## ## ### http://www.lyonesse.it * * # # # # # ## # # # # # * * # # # # # ## ## # # ## ## ## # # ## * * # # # # # ## # # # # # # # # # # # * * ### # ## # # ### ## ## ### # # #### ## Ver. 1.0 * * * * -Based on CircleMud & Smaug- Copyright (c) 2001-2002 by Mithrandir * * * * ********************************************************************** */ /* ************************************************************************ * File: events.c * * * * Usage: Contains routines to handle events * * * * Written by Eric Green (ejg3@cornell.edu) * * * * Changes: * * 3/6/98 ejg: Changed event_process to check return value on the * * event function. If > 0, reenqueue to expire in * * retval time. * * Added check in event_cancel to make sure event_obj * * is non-NULL. * * Moved struct event definition from events.h. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" /* external variables */ extern unsigned long pulse; /* external functions */ QUEUE_DATA *queue_init( void ); Q_ELEM_DATA *queue_enq( QUEUE_DATA *q, void *data, long key ); long queue_key( QUEUE_DATA *q ); long queue_elmt_key( Q_ELEM_DATA *qe ); void queue_deq( QUEUE_DATA *q, Q_ELEM_DATA *qe ); void *queue_head( QUEUE_DATA *q ); void queue_free( QUEUE_DATA *q ); /* globals */ QUEUE_DATA *event_q; /* the event queue */ /* initializes the event queue */ void event_init(void) { event_q = queue_init(); } /* creates an event and returns it */ EVENT_DATA *event_create(EVENTFUNC(*func), void *event_obj, long when) { EVENT_DATA *new_event; if (when < 1) /* make sure its in the future */ when = 1; CREATE(new_event, EVENT_DATA, 1); new_event->func = func; new_event->event_obj = event_obj; new_event->q_el = queue_enq(event_q, new_event, when + pulse); return (new_event); } /* removes the event from the system */ void event_cancel(EVENT_DATA *event) { if (!event) { log("SYSERR: Attempted to cancle a NULL event"); return; } queue_deq(event_q, event->q_el); if (event->event_obj) free(event->event_obj); free(event); } /* Process any events whose time has come. */ void event_process(void) { EVENT_DATA *the_event; long new_time; while ((long) pulse >= queue_key(event_q)) { if (!(the_event = (EVENT_DATA *) queue_head(event_q))) { log("SYSERR: Attempt to get a NULL event"); return; } /* call event func, reenqueue event if retval > 0 */ if ((new_time = (the_event->func)(the_event->event_obj)) > 0) the_event->q_el = queue_enq(event_q, the_event, new_time + pulse); else free(the_event); } } /* returns the time remaining before the event */ long event_time(EVENT_DATA *event) { long when; when = queue_elmt_key(event->q_el); return (when - pulse); } /* frees all events in the queue */ void event_free_all(void) { EVENT_DATA *the_event; while ((the_event = (EVENT_DATA *) queue_head(event_q))) { if (the_event->event_obj) free(the_event->event_obj); free(the_event); } queue_free(event_q); }