diff options
Diffstat (limited to 'e-util')
-rw-r--r-- | e-util/e-event.c | 268 | ||||
-rw-r--r-- | e-util/e-event.h | 91 |
2 files changed, 204 insertions, 155 deletions
diff --git a/e-util/e-event.c b/e-util/e-event.c index 6cbe26453e..032b10af70 100644 --- a/e-util/e-event.c +++ b/e-util/e-event.c @@ -32,21 +32,14 @@ #include "e-event.h" #include <glib/gi18n.h> -#include <libedataserver/e-msgport.h> -#define d(x) - -struct _EEventFactory { - struct _EEventFactory *next, *prev; +#define E_EVENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_EVENT, EEventPrivate)) - gchar *menuid; - EEventFactoryFunc factory; - gpointer factory_data; -}; +#define d(x) struct _event_node { - struct _event_node *next, *prev; - GSList *events; gpointer data; EEventItemsFunc freefunc; @@ -58,89 +51,92 @@ struct _event_info { }; struct _EEventPrivate { - EDList events; - + GQueue events; GSList *sorted; /* sorted list of struct _event_info's */ }; -static GObjectClass *ep_parent; +static gpointer parent_class; static void -ep_init(GObject *o) +event_finalize (GObject *object) { - EEvent *emp = (EEvent *)o; - struct _EEventPrivate *p; + EEvent *event = (EEvent *)object; + EEventPrivate *p = event->priv; - p = emp->priv = g_malloc0(sizeof(struct _EEventPrivate)); - - e_dlist_init(&p->events); -} + if (event->target) + e_event_target_free (event, event->target); -static void -ep_finalise(GObject *o) -{ - EEvent *emp = (EEvent *)o; - struct _EEventPrivate *p = emp->priv; - struct _event_node *node; + g_free (event->id); - if (emp->target) - e_event_target_free(emp, emp->target); + while (!g_queue_is_empty (&p->events)) { + struct _event_node *node; - g_free(emp->id); + node = g_queue_pop_head (&p->events); - while ((node = (struct _event_node *)e_dlist_remhead(&p->events))) { - if (node->freefunc) - node->freefunc(emp, node->events, node->data); + if (node->freefunc != NULL) + node->freefunc (event, node->events, node->data); - g_free(node); + g_free (node); } g_slist_foreach(p->sorted, (GFunc)g_free, NULL); g_slist_free(p->sorted); - g_free(p); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} - ((GObjectClass *)ep_parent)->finalize(o); +static void +event_target_free (EEvent *event, + EEventTarget *target) +{ + g_free (target); + g_object_unref (event); } static void -ep_target_free(EEvent *ep, EEventTarget *t) +event_class_init (EEventClass *class) { - g_free(t); - g_object_unref(ep); + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EEventPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = event_finalize; + + class->target_free = event_target_free; } static void -ep_class_init(GObjectClass *klass) +event_init (EEvent *event) { - d(printf("EEvent class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); + event->priv = E_EVENT_GET_PRIVATE (event); - klass->finalize = ep_finalise; - ((EEventClass *)klass)->target_free = ep_target_free; + g_queue_init (&event->priv->events); } -/** - * e_event_get_type: - * - * Standard GObject type function. Used to subclass EEvent. - * - * Return value: The EEvent type. - **/ GType e_event_get_type(void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof(EEventClass), - (GBaseInitFunc)NULL, NULL, - (GClassInitFunc)ep_class_init, NULL, NULL, - sizeof(EEvent), 0, - (GInstanceInitFunc)ep_init + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EEventClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) event_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EEvent), + 0, /* n_preallocs */ + (GInstanceInitFunc) event_init, + NULL /* value_table */ }; - ep_parent = g_type_class_ref(G_TYPE_OBJECT); - type = g_type_register_static(G_TYPE_OBJECT, "EEvent", &info, 0); + + type = g_type_register_static ( + G_TYPE_OBJECT, "EEvent", &type_info, 0); } return type; @@ -164,17 +160,17 @@ EEvent *e_event_construct(EEvent *ep, const gchar *id) /** * e_event_add_items: - * @emp: An initialised EEvent structure. + * @event: An initialised EEvent structure. * @items: A list of EEventItems event listeners to register on this event manager. * @freefunc: A function called when the @items list is no longer needed. * @data: callback data for @freefunc and for item event handlers. * - * Adds @items to the list of events listened to on the event manager @emp. + * Adds @items to the list of events listened to on the event manager @event. * * Return value: An opaque key which can later be passed to remove_items. **/ gpointer -e_event_add_items(EEvent *emp, GSList *items, EEventItemsFunc freefunc, gpointer data) +e_event_add_items(EEvent *event, GSList *items, EEventItemsFunc freefunc, gpointer data) { struct _event_node *node; @@ -182,12 +178,13 @@ e_event_add_items(EEvent *emp, GSList *items, EEventItemsFunc freefunc, gpointer node->events = items; node->freefunc = freefunc; node->data = data; - e_dlist_addtail(&emp->priv->events, (EDListNode *)node); - if (emp->priv->sorted) { - g_slist_foreach(emp->priv->sorted, (GFunc)g_free, NULL); - g_slist_free(emp->priv->sorted); - emp->priv->sorted = NULL; + g_queue_push_tail (&event->priv->events, node); + + if (event->priv->sorted) { + g_slist_foreach(event->priv->sorted, (GFunc)g_free, NULL); + g_slist_free(event->priv->sorted); + event->priv->sorted = NULL; } return (gpointer)node; @@ -195,26 +192,27 @@ e_event_add_items(EEvent *emp, GSList *items, EEventItemsFunc freefunc, gpointer /** * e_event_remove_items: - * @emp: + * @event: * @handle: * * Remove items previously added. They MUST have been previously * added, and may only be removed once. **/ void -e_event_remove_items(EEvent *emp, gpointer handle) +e_event_remove_items(EEvent *event, gpointer handle) { struct _event_node *node = handle; - e_dlist_remove((EDListNode *)node); + g_queue_remove (&event->priv->events, node); + if (node->freefunc) - node->freefunc(emp, node->events, node->data); + node->freefunc(event, node->events, node->data); g_free(node); - if (emp->priv->sorted) { - g_slist_foreach(emp->priv->sorted, (GFunc)g_free, NULL); - g_slist_free(emp->priv->sorted); - emp->priv->sorted = NULL; + if (event->priv->sorted) { + g_slist_foreach(event->priv->sorted, (GFunc)g_free, NULL); + g_slist_free(event->priv->sorted); + event->priv->sorted = NULL; } } @@ -242,24 +240,25 @@ ee_cmp(gconstpointer ap, gconstpointer bp) * emission is complete. **/ void -e_event_emit(EEvent *emp, const gchar *id, EEventTarget *target) +e_event_emit(EEvent *event, const gchar *id, EEventTarget *target) { - struct _EEventPrivate *p = emp->priv; + EEventPrivate *p = event->priv; GSList *events; d(printf("emit event %s\n", id)); - if (emp->target != NULL) { + if (event->target != NULL) { g_warning ("Event already in progress.\n"); return; } - emp->target = target; + event->target = target; events = p->sorted; if (events == NULL) { - struct _event_node *node = (struct _event_node *)p->events.head; + GList *link = g_queue_peek_head_link (&p->events); - for (;node->next;node=node->next) { + while (link != NULL) { + struct _event_node *node = link->data; GSList *l = node->events; for (;l;l=g_slist_next(l)) { @@ -270,6 +269,8 @@ e_event_emit(EEvent *emp, const gchar *id, EEventTarget *target) info->item = l->data; events = g_slist_prepend(events, info); } + + link = g_list_next (link); } p->sorted = events = g_slist_sort(events, ee_cmp); @@ -277,23 +278,23 @@ e_event_emit(EEvent *emp, const gchar *id, EEventTarget *target) for (;events;events=g_slist_next(events)) { struct _event_info *info = events->data; - EEventItem *event = info->item; + EEventItem *item = info->item; d(printf("event '%s' mask %08x target %08x\n", event->id, event->enable, target->mask)); - if (event->enable & target->mask) + if (item->enable & target->mask) continue; if (strcmp(event->id, id) == 0) { - event->handle(emp, event, info->parent->data); + item->handle(event, item, info->parent->data); - if (event->type == E_EVENT_SINK) + if (item->type == E_EVENT_SINK) break; } } - e_event_target_free(emp, target); - emp->target = NULL; + e_event_target_free(event, target); + event->target = NULL; } /** @@ -306,21 +307,23 @@ e_event_emit(EEvent *emp, const gchar *id, EEventTarget *target) * the implementation to define the available target types and their * structure. **/ -gpointer e_event_target_new(EEvent *ep, gint type, gsize size) +gpointer +e_event_target_new (EEvent *event, + gint type, + gsize size) { - EEventTarget *t; + EEventTarget *target; if (size < sizeof(EEventTarget)) { g_warning ("Size is less than the size of EEventTarget\n"); size = sizeof(EEventTarget); } - t = g_malloc0(size); - t->event = ep; - g_object_ref(ep); - t->type = type; + target = g_malloc0 (size); + target->event = g_object_ref (event);; + target->type = type; - return t; + return target; } /** @@ -331,11 +334,12 @@ gpointer e_event_target_new(EEvent *ep, gint type, gsize size) * Free a target. This invokes the virtual free method on the EEventClass. **/ void -e_event_target_free(EEvent *ep, gpointer o) +e_event_target_free (EEvent *event, + gpointer object) { - EEventTarget *t = o; + EEventTarget *target = object; - ((EEventClass *)G_OBJECT_GET_CLASS(ep))->target_free(ep, t); + E_EVENT_GET_CLASS (event)->target_free (event, target); } /* ********************************************************************** */ @@ -393,7 +397,7 @@ static const EPluginHookTargetKey emph_item_types[] = { static void emph_event_handle(EEvent *ee, EEventItem *item, gpointer data) { - struct _EEventHook *hook = data; + EEventHook *hook = data; /* FIXME: we could/should just remove the items we added to the event handler */ if (!hook->hook.plugin->enabled) @@ -403,7 +407,7 @@ emph_event_handle(EEvent *ee, EEventItem *item, gpointer data) } static void -emph_free_item(struct _EEventItem *item) +emph_free_item(EEventItem *item) { g_free((gchar *)item->id); g_free(item->user_data); @@ -419,10 +423,10 @@ emph_free_items(EEvent *ee, GSList *items, gpointer data) g_slist_free(items); } -static struct _EEventItem * -emph_construct_item(EPluginHook *eph, xmlNodePtr root, EEventHookClass *klass) +static EEventItem * +emph_construct_item(EPluginHook *eph, xmlNodePtr root, EEventHookClass *class) { - struct _EEventItem *item; + EEventItem *item; EEventHookTargetMap *map; gchar *tmp; @@ -431,7 +435,7 @@ emph_construct_item(EPluginHook *eph, xmlNodePtr root, EEventHookClass *klass) tmp = (gchar *)xmlGetProp(root, (const guchar *)"target"); if (tmp == NULL) goto error; - map = g_hash_table_lookup(klass->target_map, tmp); + map = g_hash_table_lookup(class->target_map, tmp); xmlFree(tmp); if (map == NULL) goto error; @@ -459,7 +463,7 @@ static gint emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root) { xmlNodePtr node; - EEventHookClass *klass; + EEventHookClass *class; GSList *items = NULL; g_return_val_if_fail(((EEventHookClass *)G_OBJECT_GET_CLASS(eph))->event != NULL, -1); @@ -469,14 +473,14 @@ emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root) if (((EPluginHookClass *)emph_parent_class)->construct(eph, ep, root) == -1) return -1; - klass = (EEventHookClass *)G_OBJECT_GET_CLASS(eph); + class = (EEventHookClass *)G_OBJECT_GET_CLASS(eph); node = root->children; while (node) { if (strcmp((gchar *)node->name, "event") == 0) { - struct _EEventItem *item; + EEventItem *item; - item = emph_construct_item(eph, node, klass); + item = emph_construct_item(eph, node, class); if (item) items = g_slist_prepend(items, item); } @@ -486,31 +490,23 @@ emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root) eph->plugin = ep; if (items) - e_event_add_items(klass->event, items, emph_free_items, eph); + e_event_add_items(class->event, items, emph_free_items, eph); return 0; } static void -emph_finalise(GObject *o) -{ - /*EPluginHook *eph = (EPluginHook *)o;*/ - - ((GObjectClass *)emph_parent_class)->finalize(o); -} - -static void -emph_class_init(EPluginHookClass *klass) +emph_class_init (EEventHookClass *class) { - ((GObjectClass *)klass)->finalize = emph_finalise; - klass->construct = emph_construct; + EPluginHookClass *plugin_hook_class; - /* this is actually an abstract implementation but list it anyway */ - klass->id = "org.gnome.evolution.event:1.0"; + emph_parent_class = g_type_class_peek_parent (class); - d(printf("EEventHook: init class %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); + plugin_hook_class = E_PLUGIN_HOOK_CLASS (class); + plugin_hook_class->id = "org.gnome.evolution.event:1.0"; + plugin_hook_class->construct = emph_construct; - ((EEventHookClass *)klass)->target_map = g_hash_table_new(g_str_hash, g_str_equal); + class->target_map = g_hash_table_new (g_str_hash, g_str_equal); } /** @@ -526,14 +522,22 @@ e_event_hook_get_type(void) { static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof(EEventHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL, - sizeof(EEventHook), 0, (GInstanceInitFunc) NULL, + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EEventHookClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) emph_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EEventHook), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + NULL /* value_table */ }; - emph_parent_class = g_type_class_ref(e_plugin_hook_get_type()); - type = g_type_register_static(e_plugin_hook_get_type(), "EEventHook", &info, 0); + type = g_type_register_static ( + E_TYPE_PLUGIN_HOOK, "EEventHook", &type_info, 0); } return type; @@ -541,7 +545,7 @@ e_event_hook_get_type(void) /** * e_event_hook_class_add_target_map: - * @klass: The derived EEventHook class. + * @class: The derived EEventHook class. * @map: A map used to describe a single EEventTarget type for this * class. * @@ -549,7 +553,7 @@ e_event_hook_get_type(void) * map enumerates a single target type and th eenable mask bit names, * so that the type can be loaded automatically by the base EEvent class. **/ -void e_event_hook_class_add_target_map(EEventHookClass *klass, const EEventHookTargetMap *map) +void e_event_hook_class_add_target_map(EEventHookClass *class, const EEventHookTargetMap *map) { - g_hash_table_insert(klass->target_map, (gpointer)map->type, (gpointer)map); + g_hash_table_insert(class->target_map, (gpointer)map->type, (gpointer)map); } diff --git a/e-util/e-event.h b/e-util/e-event.h index 6f561a007c..e7999dc5c2 100644 --- a/e-util/e-event.h +++ b/e-util/e-event.h @@ -25,17 +25,37 @@ This a bit 'whipped together', so is likely to change mid-term */ -#ifndef __E_EVENT_H__ -#define __E_EVENT_H__ +#ifndef E_EVENT_H +#define E_EVENT_H #include <glib-object.h> +/* Standard GObject macros */ +#define E_TYPE_EVENT \ + (e_event_get_type ()) +#define E_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_EVENT, EEvent)) +#define E_EVENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_EVENT, EEventClass)) +#define E_IS_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_EVENT)) +#define E_IS_EVENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_EVENT)) +#define E_EVENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_EVENT, EEventClass)) + G_BEGIN_DECLS /* This is an abstract event management class. */ typedef struct _EEvent EEvent; typedef struct _EEventClass EEventClass; +typedef struct _EEventPrivate EEventPrivate; typedef struct _EEventItem EEventItem; typedef struct _EEventFactory EEventFactory; /* anonymous type */ @@ -105,7 +125,7 @@ struct _EEventItem { * **/ struct _EEventTarget { - struct _EEvent *event; /* used for virtual methods */ + EEvent *event; /* used for virtual methods */ guint32 type; /* targe type, for implementors */ guint32 mask; /* depends on type, enable mask */ @@ -128,8 +148,7 @@ struct _EEventTarget { **/ struct _EEvent { GObject object; - - struct _EEventPrivate *priv; + EEventPrivate *priv; gchar *id; EEventTarget *target; /* current target during event emission */ }; @@ -148,20 +167,27 @@ struct _EEvent { struct _EEventClass { GObjectClass object_class; - void (*target_free)(EEvent *ep, EEventTarget *t); + void (*target_free) (EEvent *event, + EEventTarget *target); }; -GType e_event_get_type(void); - -EEvent *e_event_construct(EEvent *, const gchar *id); - -gpointer e_event_add_items(EEvent *emp, GSList *items, EEventItemsFunc freefunc, gpointer data); -void e_event_remove_items(EEvent *emp, gpointer handle); - -void e_event_emit(EEvent *, const gchar *id, EEventTarget *); - -gpointer e_event_target_new(EEvent *, gint type, gsize size); -void e_event_target_free(EEvent *, gpointer ); +GType e_event_get_type (void); +EEvent * e_event_construct (EEvent *event, + const gchar *id); +gpointer e_event_add_items (EEvent *event, + GSList *items, + EEventItemsFunc freefunc, + gpointer data); +void e_event_remove_items (EEvent *event, + gpointer handle); +void e_event_emit (EEvent *event, + const gchar *id, + EEventTarget *target); +gpointer e_event_target_new (EEvent *event, + gint type, + gsize size); +void e_event_target_free (EEvent *event, + gpointer object); /* ********************************************************************** */ @@ -175,13 +201,32 @@ void e_event_target_free(EEvent *, gpointer ); #include "e-util/e-plugin.h" +/* Standard GObject macros */ +#define E_TYPE_EVENT_HOOK \ + (e_event_hook_get_type ()) +#define E_EVENT_HOOK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_EVENT_HOOK, EEventHook)) +#define E_EVENT_HOOK_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_EVENT_HOOK, EEventHookClass)) +#define E_IS_EVENT_HOOK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_EVENT_HOOK)) +#define E_IS_EVENT_HOOK_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_EVENT_HOOK)) +#define E_EVENT_HOOK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_EVENT_HOOK, EEventHookClass)) + typedef struct _EEventHook EEventHook; typedef struct _EEventHookClass EEventHookClass; typedef struct _EPluginHookTargetMap EEventHookTargetMap; typedef struct _EPluginHookTargetKey EEventHookTargetMask; -typedef void (*EEventHookFunc)(struct _EPlugin *plugin, EEventTarget *target); +typedef void (*EEventHookFunc)(EPlugin *plugin, EEventTarget *target); /** * struct _EEventHook - An event hook. @@ -223,11 +268,11 @@ struct _EEventHookClass { EEvent *event; }; -GType e_event_hook_get_type(void); - -/* for implementors */ -void e_event_hook_class_add_target_map(EEventHookClass *klass, const EEventHookTargetMap *); +GType e_event_hook_get_type (void); +void e_event_hook_class_add_target_map + (EEventHookClass *klass, + const EEventHookTargetMap *map); G_END_DECLS -#endif /* __E_EVENT_H__ */ +#endif /* E_EVENT_H */ |