From 5a467648f22c7782d1539f7125974e9d249536ce Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 20 Feb 2012 22:10:23 +0000 Subject: Replace listener hash with a list svn path=/trunk/libdom/; revision=13453 --- src/events/event_target.c | 159 ++++++++++++++-------------------------------- src/events/event_target.h | 11 +--- 2 files changed, 52 insertions(+), 118 deletions(-) diff --git a/src/events/event_target.c b/src/events/event_target.c index c4a2f90..7f941e2 100644 --- a/src/events/event_target.c +++ b/src/events/event_target.c @@ -19,68 +19,31 @@ #include "utils/utils.h" #include "utils/validate.h" -/* The number of chains in the hash table used for hash event types */ -#define CHAINS 11 - -static uint32_t event_target_hash(void *key, void *pw) +static void event_target_destroy_listeners(struct listener_entry *list) { - UNUSED(pw); - - return dom_string_hash(key); -} + struct listener_entry *next = NULL; -static void event_target_destroy_key(void *key, void *pw) -{ - UNUSED(pw); + if (list == NULL) + return; - dom_string_unref(key); -} - -static void event_target_destroy_value(void *value, void *pw) -{ - struct listener_entry *le = NULL; - struct list_entry *i = (struct list_entry *) value; - - UNUSED(pw); - - while (i != i->next) { - le = (struct listener_entry *) i->next; - list_del(i->next); - dom_event_listener_unref(le->listener); - free(le); + while (list != (struct listener_entry *) list->list.next) { + next = (struct listener_entry *) list->list.next; + list_del(list->list.next); + dom_event_listener_unref(list->listener); + dom_string_unref(list->type); + free(list); } - le = (struct listener_entry *) i; - list_del(i); - dom_event_listener_unref(le->listener); - free(le); -} - -static bool event_target_key_isequal(void *key1, void *key2, void *pw) -{ - UNUSED(pw); - - return dom_string_isequal(key1, key2); + dom_event_listener_unref(list->listener); + dom_string_unref(list->type); + free(list); } -static const dom_hash_vtable event_target_vtable = { - event_target_hash, - NULL, - event_target_destroy_key, - NULL, - event_target_destroy_value, - event_target_key_isequal -}; - /* Initialise this EventTarget */ dom_exception _dom_event_target_internal_initialise( dom_event_target_internal *eti) { - eti->listeners = _dom_hash_create(CHAINS, &event_target_vtable, NULL); - if (eti->listeners == NULL) - return DOM_NO_MEM_ERR; - - eti->ns_listeners = NULL; + eti->listeners = NULL; return DOM_NO_ERR; } @@ -88,12 +51,7 @@ dom_exception _dom_event_target_internal_initialise( /* Finalise this EventTarget */ void _dom_event_target_internal_finalise(dom_event_target_internal *eti) { - _dom_hash_destroy(eti->listeners); - - /* TODO: Now, we did not support the EventListener with namespace, - * when we support it, we should deal with the ns_listeners hash - * table, too. - */ + event_target_destroy_listeners(eti->listeners); } /*-------------------------------------------------------------------------*/ @@ -114,7 +72,6 @@ dom_exception _dom_event_target_add_event_listener( bool capture) { struct listener_entry *le = NULL; - dom_string *t = NULL; le = malloc(sizeof(struct listener_entry)); if (le == NULL) @@ -122,22 +79,15 @@ dom_exception _dom_event_target_add_event_listener( /* Initialise the listener_entry */ list_init(&le->list); + le->type = dom_string_ref(type); le->listener = listener; dom_event_listener_ref(listener); le->capture = capture; - t = dom_string_ref(type); - - /* Find the type of this event */ - struct list_entry *item = (struct list_entry *) _dom_hash_get( - eti->listeners, t); - if (item == NULL) { - /* If there is no item in the hash table, we should add the - * first */ - _dom_hash_add(eti->listeners, t, &le->list, false); + if (eti->listeners == NULL) { + eti->listeners = le; } else { - /* Append this listener to the end of the list */ - list_append(item, &le->list); + list_append(&eti->listeners->list, &le->list); } return DOM_NO_ERR; @@ -157,28 +107,22 @@ dom_exception _dom_event_target_remove_event_listener( dom_string *type, struct dom_event_listener *listener, bool capture) { - struct listener_entry *le = NULL; + if (eti->listeners != NULL) { + struct listener_entry *le = eti->listeners; - /* Find the type of this event */ - struct list_entry *item = (struct list_entry *) _dom_hash_get( - eti->listeners, type); - if (item == NULL) { - /* There is no such event listener */ - return DOM_NO_ERR; - } else { - struct list_entry *i = item; do { - le = (struct listener_entry *) i; - if (le->listener == listener && + if (dom_string_isequal(le->type, type) && + le->listener == listener && le->capture == capture) { - /* We found the listener */ - list_del(i); + list_del(&le->list); dom_event_listener_unref(le->listener); + dom_string_unref(le->type); free(le); break; } - i = i->next; - } while(i != item); + + le = (struct listener_entry *) le->list.next; + } while (le != eti->listeners); } return DOM_NO_ERR; @@ -255,38 +199,33 @@ dom_exception _dom_event_target_dispatch(dom_event_target *et, struct dom_event *evt, dom_event_flow_phase phase, bool *success) { - dom_string *t = evt->type; + if (eti->listeners != NULL) { + struct listener_entry *le = eti->listeners; - struct list_entry *item = (struct list_entry *) _dom_hash_get( - eti->listeners, t); - if (item == NULL) { - /* There is no such event listener */ - return DOM_NO_ERR; - } else { - /* Call the handler for each listener */ - struct list_entry *i = item; - /* Fill the Event fields */ evt->current = et; + do { - struct listener_entry *le = - (struct listener_entry *) i; - assert(le->listener->handler != NULL); - if ((le->capture == true && - phase == DOM_CAPTURING_PHASE) || - (le->capture == false && + if (dom_string_isequal(le->type, evt->type)) { + assert(le->listener->handler != NULL); + + if ((le->capture && + phase == DOM_CAPTURING_PHASE) || + (le->capture == false && phase == DOM_BUBBLING_PHASE) || - (evt->target == evt->current && + (evt->target == evt->current && phase == DOM_AT_TARGET)) { - /* We found the listener */ - le->listener->handler(evt, le->listener->pw); - /* If the handler call - * stopImmediatedPropagation, we should - * break */ - if (evt->stop_now == true) - break; + le->listener->handler(evt, + le->listener->pw); + /* If the handler called + * stopImmediatePropagation, we should + * break */ + if (evt->stop_now == true) + break; + } } - i = i->next; - } while(i != item); + + le = (struct listener_entry *) le->list.next; + } while (le != eti->listeners); } if (evt->prevent_default == true) diff --git a/src/events/event_target.h b/src/events/event_target.h index fad39d6..4415a2a 100644 --- a/src/events/event_target.h +++ b/src/events/event_target.h @@ -17,7 +17,6 @@ #include "events/dispatch.h" #include "utils/list.h" -#include "utils/hashtable.h" /** * Listener Entry @@ -26,6 +25,7 @@ struct listener_entry { struct list_entry list; /**< The listener list registered at the same * EventTarget */ + dom_string *type; /**< Event type */ dom_event_listener *listener; /**< The EventListener */ bool capture; /**< Whether this listener is in capture phase */ }; @@ -34,13 +34,8 @@ struct listener_entry { * EventTarget internal class */ struct dom_event_target_internal { - struct dom_hash_table *listeners; - /**< The listeners of this EventTarget. - * The listeners are organized by the - * type of events they listen for - */ - struct dom_hash_table *ns_listeners; - /**< The listeners with namespace of thie EventTarget */ + struct listener_entry *listeners; + /**< The listeners of this EventTarget. */ }; typedef struct dom_event_target_internal dom_event_target_internal; -- cgit v1.2.3