[gtk/action-muxer-speedup: 9/19] Speed up action muxer setup



commit aa76f7e210ced94f7d06f51b306c487e65643c8e
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Apr 24 00:52:17 2020 -0400

    Speed up action muxer setup
    
    We don't need to duplicate all these action names and
    emit all these signals if nobody is listening.

 gtk/gtkactionmuxer.c | 122 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 106 insertions(+), 16 deletions(-)
---
diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c
index e939b106e0..bcd7ca2934 100644
--- a/gtk/gtkactionmuxer.c
+++ b/gtk/gtkactionmuxer.c
@@ -322,6 +322,108 @@ gtk_action_muxer_parent_action_state_changed (GActionGroup *action_group,
   gtk_action_muxer_action_state_changed (muxer, action_name, state);
 }
 
+static void
+notify_observers_added (GtkActionMuxer *muxer,
+                        GtkActionMuxer *parent)
+{
+  GHashTableIter iter;
+  const char *action_name;
+  Action *action;
+
+  g_hash_table_iter_init (&iter, muxer->observed_actions);
+  while (g_hash_table_iter_next (&iter, (gpointer *)&action_name, (gpointer *)&action))
+    {
+      const GVariantType *parameter_type;
+      gboolean enabled;
+      GVariant *state;
+      GSList *node;
+
+      if (!action->watchers)
+        continue;
+
+      if (!g_action_group_query_action (G_ACTION_GROUP (parent), action_name,
+                                        &enabled, &parameter_type, NULL, NULL, &state))
+        continue;
+
+      for (node = action->watchers; node; node = node->next)
+        gtk_action_observer_action_added (node->data,
+                                          GTK_ACTION_OBSERVABLE (muxer),
+                                          action_name, parameter_type, enabled, state);
+
+      if (state)
+        g_variant_unref (state);
+    }
+}
+
+static void
+emit_action_added (GtkActionMuxer *muxer,
+                   GtkActionMuxer *parent)
+{
+  static guint signal_id = 0;
+
+  if (signal_id == 0)
+    signal_id = g_signal_lookup ("action-added", G_OBJECT_TYPE (muxer));
+
+  if (g_signal_has_handler_pending (muxer, signal_id, 0, FALSE))
+    { 
+      gchar **actions;
+      gchar **it;
+
+      actions = g_action_group_list_actions (G_ACTION_GROUP (parent));
+
+      for (it = actions; *it; it++)
+        g_action_group_action_added (G_ACTION_GROUP (muxer), *it);
+
+      g_strfreev (actions);
+    }
+}
+
+static void
+notify_observers_removed (GtkActionMuxer *muxer,
+                          GtkActionMuxer *parent)
+{
+  GHashTableIter iter;
+  const char *action_name;
+  Action *action;
+
+  g_hash_table_iter_init (&iter, muxer->observed_actions);
+  while (g_hash_table_iter_next (&iter, (gpointer *)&action_name, (gpointer *)&action)) 
+    {
+      GSList *node;
+
+      if (!action->watchers)
+        continue;
+
+      for (node = action->watchers; node; node = node->next)
+        gtk_action_observer_action_removed (node->data,
+                                            GTK_ACTION_OBSERVABLE (muxer),
+                                            action_name);
+    }
+}
+
+static void
+emit_action_removed (GtkActionMuxer *muxer,
+                     GtkActionMuxer *parent)
+{
+  static guint signal_id = 0;
+
+  if (signal_id == 0)
+    signal_id = g_signal_lookup ("action-removed", G_OBJECT_TYPE (muxer));
+
+  if (g_signal_has_handler_pending (muxer, signal_id, 0, FALSE))
+    { 
+      gchar **actions;
+      gchar **it;
+
+      actions = g_action_group_list_actions (G_ACTION_GROUP (parent));
+
+      for (it = actions; *it; it++)
+        g_action_group_action_removed (G_ACTION_GROUP (muxer), *it);
+
+      g_strfreev (actions);
+    }
+}
+
 static void
 gtk_action_muxer_action_added (GtkActionMuxer *muxer,
                                const gchar    *action_name,
@@ -1125,14 +1227,8 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
 
   if (muxer->parent != NULL)
     {
-      gchar **actions;
-      gchar **it;
-
-      actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
-      for (it = actions; *it; it++)
-        gtk_action_muxer_action_removed (muxer, *it);
-      g_strfreev (actions);
-
+      notify_observers_removed (muxer, muxer->parent);
+      emit_action_removed (muxer, muxer->parent);
       emit_changed_accels (muxer, muxer->parent);
 
       g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
@@ -1148,16 +1244,10 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
 
   if (muxer->parent != NULL)
     {
-      gchar **actions;
-      gchar **it;
-
       g_object_ref (muxer->parent);
 
-      actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
-      for (it = actions; *it; it++)
-        gtk_action_muxer_action_added (muxer, *it, G_ACTION_GROUP (muxer->parent), *it);
-      g_strfreev (actions);
-
+      notify_observers_added (muxer, muxer->parent);
+      emit_action_added (muxer, muxer->parent);
       emit_changed_accels (muxer, muxer->parent);
 
       g_signal_connect (muxer->parent, "action-added",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]