]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
trigger: Add the ability to trigger data with an associated instance
authorRay Strode <rstrode@redhat.com>
Wed, 16 Nov 2022 18:57:56 +0000 (13:57 -0500)
committerRay Strode <rstrode@redhat.com>
Tue, 29 Nov 2022 14:22:06 +0000 (09:22 -0500)
Right now triggers can only fire off handlers that have one piece
of data associated with them, but sometimes it's useful to have
an object associated with the data too.

This commit adds new api for adding "instance handlers" that have
an additional parameter and a new method `ply_trigger_set_instance`
that allows an object to be associated with the trigger and get
used for the additional parameter of the instance handlers.

src/libply/ply-trigger.c
src/libply/ply-trigger.h

index 620fa9fb3f4a696fa2b5f7965f6be0c8315062f7..dda73d3d7f4d71a3d52fb4f0c1707f2a0db99641 100644 (file)
 #include "ply-list.h"
 #include "ply-utils.h"
 
+typedef enum
+{
+        PLY_TRIGGER_HANDLER_TYPE_HANDLER,
+        PLY_TRIGGER_HANDLER_TYPE_INSTANCE_HANDLER
+} ply_trigger_handler_type_t;
+
 typedef struct
 {
-        ply_trigger_handler_t handler;
-        void                 *user_data;
+        ply_trigger_handler_type_t handler_type;
+        union
+        {
+                ply_trigger_handler_t          handler;
+                ply_trigger_instance_handler_t instance_handler;
+        };
+        void                      *user_data;
 } ply_trigger_closure_t;
 
 struct _ply_trigger
 {
         ply_list_t     *closures;
 
+        void           *instance;
+
         ply_trigger_t **free_address;
         int             ignore_count;
 };
@@ -90,6 +103,62 @@ ply_trigger_free (ply_trigger_t *trigger)
         free (trigger);
 }
 
+void
+ply_trigger_set_instance (ply_trigger_t *trigger,
+                          void          *instance)
+{
+        trigger->instance = instance;
+}
+
+void *
+ply_trigger_get_instance (ply_trigger_t *trigger)
+{
+        return trigger->instance;
+}
+
+void
+ply_trigger_add_instance_handler (ply_trigger_t                 *trigger,
+                                  ply_trigger_instance_handler_t handler,
+                                  void                          *user_data)
+{
+        ply_trigger_closure_t *closure;
+
+        closure = calloc (1, sizeof(ply_trigger_closure_t));
+        closure->handler_type = PLY_TRIGGER_HANDLER_TYPE_INSTANCE_HANDLER;
+        closure->instance_handler = handler;
+        closure->user_data = user_data;
+
+        ply_list_append_data (trigger->closures, closure);
+}
+
+void
+ply_trigger_remove_instance_handler (ply_trigger_t                 *trigger,
+                                     ply_trigger_instance_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_type == PLY_TRIGGER_HANDLER_TYPE_INSTANCE_HANDLER &&
+                    closure->instance_handler == handler &&
+                    closure->user_data == user_data) {
+                        free (closure);
+                        ply_list_remove_node (trigger->closures, node);
+                        break;
+                }
+
+                node = next_node;
+        }
+}
+
 void
 ply_trigger_add_handler (ply_trigger_t        *trigger,
                          ply_trigger_handler_t handler,
@@ -98,6 +167,7 @@ ply_trigger_add_handler (ply_trigger_t        *trigger,
         ply_trigger_closure_t *closure;
 
         closure = calloc (1, sizeof(ply_trigger_closure_t));
+        closure->handler_type = PLY_TRIGGER_HANDLER_TYPE_HANDLER;
         closure->handler = handler;
         closure->user_data = user_data;
 
@@ -120,7 +190,9 @@ ply_trigger_remove_handler (ply_trigger_t        *trigger,
 
                 next_node = ply_list_get_next_node (trigger->closures, node);
 
-                if (closure->handler == handler && closure->user_data == user_data) {
+                if (closure->handler_type == PLY_TRIGGER_HANDLER_TYPE_HANDLER &&
+                    closure->handler == handler &&
+                    closure->user_data == user_data) {
                         free (closure);
                         ply_list_remove_node (trigger->closures, node);
                         break;
@@ -158,8 +230,16 @@ ply_trigger_pull (ply_trigger_t *trigger,
                 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);
+                switch (closure->handler_type) {
+                case PLY_TRIGGER_HANDLER_TYPE_HANDLER:
+                        closure->handler (closure->user_data, data, trigger);
+                        break;
+                case PLY_TRIGGER_HANDLER_TYPE_INSTANCE_HANDLER:
+                        closure->instance_handler (closure->user_data, trigger->instance, data, trigger);
+                        break;
+                default:
+                        break;
+                }
 
                 node = next_node;
         }
index 162a794c07e0fdd22f03b28df9724d8070553628..bb088386864fa9ae57aee821186adfb8449022a2 100644 (file)
@@ -33,6 +33,11 @@ typedef struct _ply_trigger ply_trigger_t;
 typedef void (*ply_trigger_handler_t) (void          *user_data,
                                        const void    *trigger_data,
                                        ply_trigger_t *trigger);
+
+typedef void (*ply_trigger_instance_handler_t) (void          *user_data,
+                                                void          *instance,
+                                                const void    *trigger_data,
+                                                ply_trigger_t *trigger);
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
 ply_trigger_t *ply_trigger_new (ply_trigger_t **free_address);
 
@@ -42,6 +47,18 @@ void ply_trigger_add_handler (ply_trigger_t        *trigger,
 void ply_trigger_remove_handler (ply_trigger_t        *trigger,
                                  ply_trigger_handler_t handler,
                                  void                 *user_data);
+
+void ply_trigger_set_instance (ply_trigger_t *trigger,
+                               void          *instance);
+void *ply_trigger_get_instance (ply_trigger_t *trigger);
+
+void ply_trigger_add_instance_handler (ply_trigger_t                 *trigger,
+                                       ply_trigger_instance_handler_t handler,
+                                       void                          *user_data);
+void ply_trigger_remove_instance_handler (ply_trigger_t                 *trigger,
+                                          ply_trigger_instance_handler_t handler,
+                                          void                          *user_data);
+
 void ply_trigger_free (ply_trigger_t *trigger);
 
 void ply_trigger_ignore_next_pull (ply_trigger_t *trigger);