Kender,
This is absolutely delicious. The union saves on memory, and the function
pointers are way
simplier than the table layout that I am using. Plus it's incredibly
centralized, making adding
and removing new actions very easy.
What I have works, but is much more scattered/inefficient:
struct event_action_type
{
char *name;
int (*action)(EVENT_DATA *ev);
};
const struct event_action_type event_action_table[] =
{
{"NULL", NULL},
{"print", &action_print},
{"wait", &action_wait},
{"act", &action_act},
{"function", &action_function},
{"kill_menu", &action_killmenu},
{"NULL", NULL}
};
Example action (I switched to ints for debugging/event chaining purposes):
int action_print (EVENT_DATA *ev)
{
if((!ev->args[0]) || (!ev->argv[0]))
return FALSE;
send_to_char(ev->args[0], ev->argv[0]);
return TRUE;
}
My new event handler looks like:
void event_update(void)
{
EVENT_DATA *ev = NULL, *ev_next, *ev_last = ev;
if (!events)
return;
for( ev = events; ev; ev = ev_next)
{
ev_next = ev->next;
if (ev->delay-- <= 0)
{
event_action_table[ev->action].action (ev);
...<event freeing stuff>...
}
}
return;
}
The method you proposed is way easier to deal with, and is much more clean.
I have a couple of questions, however:
The new_event() and free_event() functions for your methods--what would they
look like? Here my
ignorance is showing. I am assuming that it's typical linked list node
adding/remove, such as:
void free_event(struct event *ev)
{
if (!IS_VALID(ev))
return;
INVALIDATE(ev);
int i = 0;
ev->next = ev_free;
ev_free = ev;
}
And with new_event,
struct event *new_event(void)
{
static event ev_zero;
struct event *ev;
if (ev_free == NULL)
ev = alloc_perm(sizeof(*ev));
else
{
ev = ev_free;
ev_free = ev_free->next;
}
*ev = ev_zero;
VALIDATE(ev);
return ev;
}
Right?
Only other thing I can think of is to typedef the event struct for my own
laziness. :)
-- Jeremy
----- Original Message -----
From: "Chad Simmons" <[EMAIL PROTECTED]>
To: "Jeremy Hill" <[EMAIL PROTECTED]>
Cc: <[email protected]>
Sent: Sunday, August 31, 2003 1:51 AM
Subject: Re: More describable event actions
> That layout does seem a bit overly complicated. Perhaps I can propose a
> somewhat simplier approach.
>
> To use the events you have listed..
>
> struct print_event_args
> {
> CHAR_DATA * ch;
> char * message;
> };
>
> struct wait_event_args
> {
> CHAR_DATA * ch;
> u_int16 seconds;
> };
>
> etc....
>
>
>
> Then you have the
>
> struct event
> {
> struct event * next;
> union
> {
> struct wait_event_args wait;
> struct print_event_args print;
> /* etc.... */
> } event_args;
>
> u_int16 delay;
> void (*fire)(struct event *);
> void (*destroy)(struct event *);
> bool valid;
> };
>
>
> Each type of event will need it's own creation function (similiar to what you
> have now)
>
>
> void print_event(CHAR_DATA *ch, int delay, char * fmt, ...)
> {
> char buf[2*MSL];
> va_list args;
>
> va_start(args, fmt);
> vsprintf(buf, fmt, args);
> va_end(args);
>
>
> struct event *ev = new_event();
>
> ev->fire = &fire_print_event;
> ev->destroy = &destroy_print_event;
>
> ev->event_args.print.ch = ch;
> ev->event_args.print.message = str_dup(buf);
> ev->delay = delay;
>
> ev->next = events;
> events = ev;
> return;
> }
>
>
> Then your update function need only look like:
>
> void event_update(void)
> {
> struct event *ev = NULL, *ev_next = NULL, *ev_last = NULL;
>
> for(ev=events;ev;ev=ev_next)
> {
> ev_next=ev->next;
>
> if(ev->delay-- <= 0)
> {
> ev->fire(ev);
> ev->destroy(ev);
>
> if(ev_last)
> ev_last->next = ev_next;
> else
> events = ev_next;
> }
> else
> ev_last = ev;
> }
> }
>
>
>
> Much simplier.
>
>
> But you'll still need to make 2 functions for each event.
>
> The fire function :
>
> void fire_print_event(struct event * ev)
> {
> send_to_character(ev->event_args.print.ch, ev->event_args.print.message);
> }
>
> And the destroy function :
>
> void destroy_print_event(struct event * ev)
> {
> free(ev->event_args.print.message);
> free_event(ev);
> }
>
>
>
> The advantage to using this method, is that you don't need to have a single
> function with all the code for all the events inside it.
>
> Once you're starting to reach this level of polymorphism however, it might be
> a
> good idea to look into some C++ books, as the language makes this type of
> design much simplier.
>
> Thanks,
> ~Kender
>
> =====
> -----BEGIN GEEK CODE BLOCK-----
> Version 3.1
> GCS/L/C/O d-(+) s++: a-- C+++$>++++ UBLS++++$
> P+++(--)$ L+++>++++ E--- W+>++$ N !o K? w(--) !O
> M- !V PS+ PE(++) Y+ PGP->+ t+ 5 X+() R(+) tv+@
> b++(+++) !DI+++ D G(-) e>+++$ h---() r+++ y+++
> ------END GEEK CODE BLOCK------
>
> __________________________________
> Do you Yahoo!?
> Yahoo! SiteBuilder - Free, easy-to-use web site design software
> http://sitebuilder.yahoo.com
>