Allow ply-trigger to have multiple pull handlers

This will be useful for hooking into a trigger
at multiple layers in the code.
This commit is contained in:
Ray Strode 2008-09-25 00:00:58 -04:00
parent 1ec380a44e
commit 86f1383a7b
3 changed files with 103 additions and 13 deletions

View file

@ -27,26 +27,30 @@
#include <string.h>
#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);

View file

@ -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,

View file

@ -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);
}