[gtk/action-muxer-speedup: 10/12] actionmuxer: Create observed_actions on demand



commit e0ab60eba03dd54184f54a2956d9036f9023fb08
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 19 09:45:12 2020 -0400

    actionmuxer: Create observed_actions on demand
    
    The vast majority of action muxers don't have any
    observed actions, so we can avoid the overhead of
    carrying all these empty hash tables.

 gtk/gtkactionmuxer.c | 70 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 23 deletions(-)
---
diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c
index 08f02d271d..38a0914ae8 100644
--- a/gtk/gtkactionmuxer.c
+++ b/gtk/gtkactionmuxer.c
@@ -220,6 +220,16 @@ gtk_action_muxer_find (GtkActionMuxer  *muxer,
   return NULL;
 }
 
+static inline Action *
+find_observers (GtkActionMuxer *muxer,
+                const char     *action_name)
+{
+  if (muxer->observed_actions)
+    return g_hash_table_lookup (muxer->observed_actions, action_name);
+
+  return NULL;
+}
+
 void
 gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
                                          const gchar    *action_name,
@@ -246,7 +256,8 @@ gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
         }
     }
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+  action = find_observers (muxer, action_name);
+
   for (node = action ? action->watchers : NULL; node; node = node->next)
     gtk_action_observer_action_enabled_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, 
enabled);
 }
@@ -273,7 +284,7 @@ gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
   Action *action;
   GSList *node;
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+  action = find_observers (muxer, action_name);
   for (node = action ? action->watchers : NULL; node; node = node->next)
     gtk_action_observer_action_state_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, state);
 }
@@ -309,6 +320,9 @@ notify_observers_added (GtkActionMuxer *muxer,
   const char *action_name;
   Action *action;
 
+  if (!muxer->observed_actions)
+    return;
+
   g_hash_table_iter_init (&iter, muxer->observed_actions);
   while (g_hash_table_iter_next (&iter, (gpointer *)&action_name, (gpointer *)&action))
     {
@@ -353,6 +367,9 @@ notify_observers_removed (GtkActionMuxer *muxer,
   const char *action_name;
   Action *action;
 
+  if (!muxer->observed_actions)
+    return;
+
   g_hash_table_iter_init (&iter, muxer->observed_actions);
   while (g_hash_table_iter_next (&iter, (gpointer *)&action_name, (gpointer *)&action))
     {
@@ -379,8 +396,7 @@ gtk_action_muxer_action_added (GtkActionMuxer     *muxer,
   Action *action;
   GSList *node;
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
-
+  action = find_observers (muxer, action_name);
   for (node = action ? action->watchers : NULL; node; node = node->next)
     gtk_action_observer_action_added (node->data,
                                       GTK_ACTION_OBSERVABLE (muxer),
@@ -399,7 +415,12 @@ gtk_action_muxer_action_added_to_group (GActionGroup *action_group,
   gboolean enabled;
   GVariant *state;
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+   if (muxer->parent)
+     gtk_action_observable_unregister_observer (GTK_ACTION_OBSERVABLE (muxer->parent),
+                                                action_name,
+                                                GTK_ACTION_OBSERVER (muxer));
+
+  action = find_observers (muxer, action_name);
 
   if (action && action->watchers &&
       g_action_group_query_action (action_group, action_name,
@@ -414,11 +435,6 @@ gtk_action_muxer_action_added_to_group (GActionGroup *action_group,
       if (state)
         g_variant_unref (state);
     }
-
-   if (muxer->parent)
-     gtk_action_observable_unregister_observer (GTK_ACTION_OBSERVABLE (muxer->parent),
-                                                action_name,
-                                                GTK_ACTION_OBSERVER (muxer));
 }
 
 static void
@@ -428,7 +444,7 @@ gtk_action_muxer_action_removed (GtkActionMuxer *muxer,
   Action *action;
   GSList *node;
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+  action = find_observers (muxer, action_name);
   for (node = action ? action->watchers : NULL; node; node = node->next)
     gtk_action_observer_action_removed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name);
 }
@@ -447,7 +463,7 @@ gtk_action_muxer_action_removed_from_group (GActionGroup *action_group,
   gtk_action_muxer_action_removed (muxer, fullname);
   g_free (fullname);
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+  action = find_observers (muxer, action_name);
 
   if (action && action->watchers &&
       !action_muxer_query_action (muxer, action_name,
@@ -471,7 +487,7 @@ gtk_action_muxer_primary_accel_changed (GtkActionMuxer *muxer,
   if (!action_name)
     action_name = strrchr (action_and_target, '|') + 1;
 
-  action = g_hash_table_lookup (muxer->observed_actions, action_name);
+  action = find_observers (muxer, action_name);
   for (node = action ? action->watchers : NULL; node; node = node->next)
     gtk_action_observer_primary_accel_changed (node->data, GTK_ACTION_OBSERVABLE (muxer),
                                                action_name, action_and_target);
@@ -808,6 +824,8 @@ gtk_action_muxer_weak_notify (gpointer  data,
   gtk_action_muxer_unregister_internal (action, where_the_object_was);
 }
 
+static void gtk_action_muxer_free_action (gpointer data);
+
 static void
 gtk_action_muxer_register_observer (GtkActionObservable *observable,
                                     const gchar         *name,
@@ -819,6 +837,9 @@ gtk_action_muxer_register_observer (GtkActionObservable *observable,
   const GVariantType *parameter_type;
   GVariant *state;
 
+  if (!muxer->observed_actions)
+    muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, 
gtk_action_muxer_free_action);
+
   action = g_hash_table_lookup (muxer->observed_actions, name);
 
   if (action == NULL)
@@ -865,12 +886,12 @@ gtk_action_muxer_unregister_observer (GtkActionObservable *observable,
   GtkActionMuxer *muxer = GTK_ACTION_MUXER (observable);
   Action *action;
 
-  action = g_hash_table_lookup (muxer->observed_actions, name);
-  if (!action)
-    return;
-
-  g_object_weak_unref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
-  gtk_action_muxer_unregister_internal (action, observer);
+  action = find_observers (muxer, name);
+  if (action)
+    {
+      g_object_weak_unref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
+      gtk_action_muxer_unregister_internal (action, observer);
+    }
 }
 
 static void
@@ -909,8 +930,11 @@ gtk_action_muxer_finalize (GObject *object)
 {
   GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
 
-  g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0);
-  g_hash_table_unref (muxer->observed_actions);
+  if (muxer->observed_actions)
+    {
+      g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0);
+      g_hash_table_unref (muxer->observed_actions);
+    }
   g_hash_table_unref (muxer->groups);
   if (muxer->primary_accels)
     g_hash_table_unref (muxer->primary_accels);
@@ -926,7 +950,8 @@ gtk_action_muxer_dispose (GObject *object)
   GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
 
   g_clear_object (&muxer->parent);
-  g_hash_table_remove_all (muxer->observed_actions);
+  if (muxer->observed_actions)
+    g_hash_table_remove_all (muxer->observed_actions);
 
   muxer->widget = NULL;
 
@@ -988,7 +1013,6 @@ gtk_action_muxer_set_property (GObject      *object,
 static void
 gtk_action_muxer_init (GtkActionMuxer *muxer)
 {
-  muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, 
gtk_action_muxer_free_action);
   muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gtk_action_muxer_free_group);
   muxer->widget_actions_disabled = _gtk_bitmask_new ();
 }


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