[gtk: 1/2] gtk-demo: Avoid list for children in GtkFishBowl
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 1/2] gtk-demo: Avoid list for children in GtkFishBowl
- Date: Thu, 4 Jun 2020 12:11:34 +0000 (UTC)
commit 8707bab4506d92e3a931864f8f6a4ab9e4de6797
Author: Alexander Larsson <alexl redhat com>
Date: Thu Jun 4 12:06:42 2020 +0200
gtk-demo: Avoid list for children in GtkFishBowl
This is a demo that measures performance, so keep the child
info in a hashtable instead of a list. This means adding or removing
a child is not O(n-children).
demos/gtk-demo/gtkfishbowl.c | 65 ++++++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 29 deletions(-)
---
diff --git a/demos/gtk-demo/gtkfishbowl.c b/demos/gtk-demo/gtkfishbowl.c
index 58c2c5a182..47356924b6 100644
--- a/demos/gtk-demo/gtkfishbowl.c
+++ b/demos/gtk-demo/gtkfishbowl.c
@@ -25,7 +25,7 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
struct _GtkFishbowlPrivate
{
GtkFishCreationFunc creation_func;
- GList *children;
+ GHashTable *children;
guint count;
gint64 last_frame_time;
@@ -67,6 +67,8 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
priv->update_delay = G_USEC_PER_SEC;
+ priv->children = g_hash_table_new_full (NULL, NULL,
+ NULL, (GDestroyNotify) g_free);
}
/**
@@ -93,16 +95,18 @@ gtk_fishbowl_measure (GtkWidget *widget,
{
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
+ GHashTableIter iter;
+ gpointer key, value;
GtkFishbowlChild *child;
- GList *children;
gint child_min, child_nat;
*minimum = 0;
*natural = 0;
- for (children = priv->children; children; children = children->next)
+ g_hash_table_iter_init (&iter, priv->children);
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- child = children->data;
+ child = value;
if (!gtk_widget_get_visible (child->widget))
continue;
@@ -136,11 +140,13 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
GtkFishbowlChild *child;
GtkAllocation child_allocation;
GtkRequisition child_requisition;
- GList *children;
+ GHashTableIter iter;
+ gpointer key, value;
- for (children = priv->children; children; children = children->next)
+ g_hash_table_iter_init (&iter, priv->children);
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- child = children->data;
+ child = value;
if (!gtk_widget_get_visible (child->widget))
continue;
@@ -181,7 +187,7 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
gtk_widget_set_parent (widget, GTK_WIDGET (fishbowl));
- priv->children = g_list_prepend (priv->children, child_info);
+ g_hash_table_insert (priv->children, widget, child_info);
priv->count++;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
}
@@ -191,32 +197,30 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
GtkWidget *widget)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
- GtkFishbowlChild *child;
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
- GList *children;
- for (children = priv->children; children; children = children->next)
+ if (g_hash_table_remove (priv->children, widget))
{
- child = children->data;
+ gboolean was_visible = gtk_widget_get_visible (widget);
- if (child->widget == widget)
- {
- gboolean was_visible = gtk_widget_get_visible (widget);
+ gtk_widget_unparent (widget);
- gtk_widget_unparent (widget);
+ if (was_visible && gtk_widget_get_visible (widget_bowl))
+ gtk_widget_queue_resize (widget_bowl);
- priv->children = g_list_remove_link (priv->children, children);
- g_list_free (children);
- g_free (child);
+ priv->count--;
+ g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
+ }
+}
- if (was_visible && gtk_widget_get_visible (widget_bowl))
- gtk_widget_queue_resize (widget_bowl);
+static void
+gtk_fishbowl_finalize (GObject *object)
+{
+ GtkFishbowl *fishbowl = GTK_FISHBOWL (object);
+ GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
- priv->count--;
- g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
- break;
- }
- }
+ g_hash_table_destroy (priv->children);
+ priv->children = NULL;
}
static void
@@ -304,6 +308,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->finalize = gtk_fishbowl_finalize;
object_class->dispose = gtk_fishbowl_dispose;
object_class->set_property = gtk_fishbowl_set_property;
object_class->get_property = gtk_fishbowl_get_property;
@@ -535,8 +540,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child;
- GList *l;
gint64 frame_time, elapsed;
+ GHashTableIter iter;
+ gpointer key, value;
gboolean do_update;
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
@@ -548,9 +554,10 @@ gtk_fishbowl_tick (GtkWidget *widget,
if (elapsed == frame_time)
return G_SOURCE_CONTINUE;
- for (l = priv->children; l; l = l->next)
+ g_hash_table_iter_init (&iter, priv->children);
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- child = l->data;
+ child = value;
child->x += child->dx * ((double) elapsed / G_USEC_PER_SEC);
child->y += child->dy * ((double) elapsed / G_USEC_PER_SEC);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]