From 86f1383a7b490f39749aa3ee6eab2f564ed4672c Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 25 Sep 2008 00:00:58 -0400 Subject: [PATCH] Allow ply-trigger to have multiple pull handlers This will be useful for hooking into a trigger at multiple layers in the code. --- src/libply/ply-trigger.c | 100 +++++++++++++++++++++++++++++++++++---- src/libply/ply-trigger.h | 11 +++-- src/ply-boot-splash.c | 5 +- 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/libply/ply-trigger.c b/src/libply/ply-trigger.c index 83131a0b..b1952d71 100644 --- a/src/libply/ply-trigger.c +++ b/src/libply/ply-trigger.c @@ -27,26 +27,30 @@ #include #include "ply-logger.h" +#include "ply-list.h" #include "ply-utils.h" -struct _ply_trigger +typedef struct { ply_trigger_handler_t handler; void *user_data; - ply_trigger_t **free_address; +} ply_trigger_closure_t; + +struct _ply_trigger +{ + ply_list_t *closures; + + ply_trigger_t **free_address; }; ply_trigger_t * -ply_trigger_new (ply_trigger_handler_t handler, - void *user_data, - ply_trigger_t **free_address) +ply_trigger_new (ply_trigger_t **free_address) { ply_trigger_t *trigger; trigger = calloc (1, sizeof (ply_trigger_t)); - trigger->handler = handler; - trigger->user_data = user_data; trigger->free_address = free_address; + trigger->closures = ply_list_new (); return trigger; } @@ -54,23 +58,101 @@ ply_trigger_new (ply_trigger_handler_t handler, void ply_trigger_free (ply_trigger_t *trigger) { + ply_list_node_t *node; + if (trigger == NULL) return; + node = ply_list_get_first_node (trigger->closures); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_trigger_closure_t *closure; + + closure = (ply_trigger_closure_t *) ply_list_node_get_data (node); + + next_node = ply_list_get_next_node (trigger->closures, node); + + free (closure); + ply_list_remove_node (trigger->closures, node); + + node = next_node; + } + ply_list_free (trigger->closures); + + if (trigger->free_address != NULL) + *trigger->free_address = NULL; + if (trigger->free_address != NULL) *trigger->free_address = NULL; free (trigger); } +void +ply_trigger_add_handler (ply_trigger_t *trigger, + ply_trigger_handler_t handler, + void *user_data) +{ + ply_trigger_closure_t *closure; + + closure = calloc (1, sizeof (ply_trigger_closure_t)); + closure->handler = handler; + closure->user_data = user_data; + + ply_list_append_data (trigger->closures, closure); +} + +void +ply_trigger_remove_handler (ply_trigger_t *trigger, + ply_trigger_handler_t handler, + void *user_data) +{ + ply_list_node_t *node; + + node = ply_list_get_first_node (trigger->closures); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_trigger_closure_t *closure; + + closure = (ply_trigger_closure_t *) ply_list_node_get_data (node); + + next_node = ply_list_get_next_node (trigger->closures, node); + + if (closure->handler == handler && closure->user_data == user_data) + { + free (closure); + ply_list_remove_node (trigger->closures, node); + break; + } + + node = next_node; + } +} + void ply_trigger_pull (ply_trigger_t *trigger, const void *data) { + ply_list_node_t *node; + assert (trigger != NULL); - if (trigger->handler != NULL) - trigger->handler (trigger->user_data, data, trigger); + node = ply_list_get_first_node (trigger->closures); + while (node != NULL) + { + ply_list_node_t *next_node; + ply_trigger_closure_t *closure; + + closure = (ply_trigger_closure_t *) ply_list_node_get_data (node); + + next_node = ply_list_get_next_node (trigger->closures, node); + + closure->handler (closure->user_data, data, trigger); + + node = next_node; + } if (trigger->free_address != NULL) ply_trigger_free (trigger); diff --git a/src/libply/ply-trigger.h b/src/libply/ply-trigger.h index d7dc936d..cf9fbf09 100644 --- a/src/libply/ply-trigger.h +++ b/src/libply/ply-trigger.h @@ -34,9 +34,14 @@ typedef void (* ply_trigger_handler_t) (void *user_data, const void *trigger_data, ply_trigger_t *trigger); #ifndef PLY_HIDE_FUNCTION_DECLARATIONS -ply_trigger_t *ply_trigger_new (ply_trigger_handler_t handler, - void *user_data, - ply_trigger_t **post_pull_free_address); +ply_trigger_t *ply_trigger_new (ply_trigger_t **free_address); + +void ply_trigger_add_handler (ply_trigger_t *trigger, + ply_trigger_handler_t handler, + void *user_data); +void ply_trigger_remove_handler (ply_trigger_t *trigger, + ply_trigger_handler_t handler, + void *user_data); void ply_trigger_free (ply_trigger_t *trigger); void ply_trigger_pull (ply_trigger_t *trigger, diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c index 844116a0..46bd21ab 100644 --- a/src/ply-boot-splash.c +++ b/src/ply-boot-splash.c @@ -308,7 +308,10 @@ ply_boot_splash_become_idle (ply_boot_splash_t *splash, return; } - splash->idle_trigger = ply_trigger_new ((ply_trigger_handler_t) idle_handler, user_data, &splash->idle_trigger); + splash->idle_trigger = ply_trigger_new (&splash->idle_trigger); + ply_trigger_add_handler (splash->idle_trigger, + (ply_trigger_handler_t) idle_handler, + user_data); splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger); } -- 2.47.3