/* IRCfs - IRC FileServ for *nix. * Copyright (C) 2002 Nick 'Zaf' Clifford * For licensing details, refer to the LICENSE file in the source * code directory. */ #ifndef __include_event_h__ #define __include_event_h__ /* Event system documentation. * An event object is registered with event_create_obj(). * This event object is used for most other function calls * When another module wishes to add an event handler, it should * call event_add_listener(), passing the eventobj handle, the * code to listen for, a possible filter, the callback function, * and appdata. * * Filters: * If the service module registers a filter function, this function * is called for each listener for every event that is raised. * The filter function should examine the message, and the user * provided filter, and return 0 if the user listener should be called, * or -1 if it shouldn't. * Example: * The following example sets up a filter system so the user can * elect to only recieve event msgs that match a user specified string. * * The first event_raise will NOT get passed to user_func(), but the * second one will. * * int filter_func(struct eventmsg *msg, void *filter) { * char *str1 = (char *) filter; * char *str2 = (char *) msg->msg; * if (strcasecmp(str1,str2) == 0) * return 0; * return -1; * } * ... * eo = event_create_obj(NULL,NULL); * event_set_filter_func(eo, filter_func); * ... * event_raise(eo,0,"test"); * event_raise(eo,0,"google"); * ... * ... Somewhere in user code ... * * event_add_listener(eo, 0, "google", user_func, NULL); * * * */ #include "pool.h" struct eventobj; #define event_code_any 0xFFFFFFFE struct eventmsg { struct eventobj *obj; unsigned int code; int count; void *appdata; void *msg; }; typedef int (*event_callback_t)(struct eventmsg *msg); typedef int (*event_filter_func_t)(struct eventmsg *msg, void *filter); int event_add_listener(struct eventobj *what, unsigned int code, void *filter, event_callback_t func, void *appdata); int event_del_listener(struct eventobj *what, unsigned int code, void *filter, event_callback_t func); /* event_del_listener_by_data(obj, code, filterdata, func, appdata) * Remove any matching code. * If NULL is passed for func or appdata, it is assumed to mean match any. * * eg: * // Deletes all listeners in given obj. * event_del_listener_by_data(obj, event_code_any, NULL, NULL, NULL) * * // Deletes all listeners that have the specified appdata (blah) * event_del_listener_by_data(obj, event_code_any, NULL, NULL, blah) * * // Deletes all listeners that call the specified function, matching * // any appdata, and any filterdata * event_del_listener_by_data(obj, event_code_any, NULL, myfunc, NULL) * * Returns number of matches or -1 if no matches. */ int event_del_listener_by_data(struct eventobj *obj, unsigned int code, void *filterdata, event_callback_t func, void *appdata); struct eventobj *event_create_obj(POOL p, void *objdata); void event_destroy_obj(struct eventobj *obj); int event_set_filter_func(struct eventobj *obj, event_filter_func_t func); void *event_get_obj_data(struct eventobj *obj); /* event_raise(obj, code, msgdata) * Raises an event within the specified object with the specified code. * Event listeners (registered with event_add_listener) that * match the specified code, and pass the optional filter (registered * with event_set_filter_func) are called with the msgdata as a parameter * (see event_add_listener). * * Returns -1 on error or the number of listeners that were called (0 * if there were no matches). */ int event_raise(struct eventobj *obj, unsigned int code, void *msg); // TODO, same as event_raise, however listeners are not called until // after all the select processing. (In the "idle" time). //int event_post(struct eventobj *obj, unsigned int code, void *msg); #endif