Refactored the integer id->ClutterActor mapping code to be a self
authorØyvind Kolås <pippin@openedhand.com>
Fri, 7 Mar 2008 17:34:40 +0000 (17:34 +0000)
committerØyvind Kolås <pippin@openedhand.com>
Fri, 7 Mar 2008 17:34:40 +0000 (17:34 +0000)
contained data structure.
* clutter/clutter-id-pool.[ch]: new files.
* clutter/Makefile.am: added clutter-id-pool.[ch]
* clutter/clutter-private.h: use a ClutterIDPool instead of GArray and
GSList to keep track of the reusable ids.
* clutter/clutter-actor.c: moved id pool logic away.
* clutter/clutter-main.c: simplified id pool creation/finalization.

ChangeLog
clutter/Makefile.am
clutter/clutter-actor.c
clutter/clutter-id-pool.c [new file with mode: 0644]
clutter/clutter-id-pool.h [new file with mode: 0644]
clutter/clutter-main.c
clutter/clutter-private.h

index 9ca1ced..78ac9ae 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-03-07  Øyvind Kolås  <pippin@o-hand.com>
+
+       Refactored the integer id->ClutterActor mapping code to be a self
+       contained data structure.
+
+       * clutter/clutter-id-pool.[ch]: new files.
+       * clutter/Makefile.am: added clutter-id-pool.[ch]
+       * clutter/clutter-private.h: use a ClutterIDPool instead of GArray and
+       GSList to keep track of the reusable ids.
+       * clutter/clutter-actor.c: moved id pool logic away.
+       * clutter/clutter-main.c: simplified id pool creation/finalization.
+
 2008-03-07  Robert Bragg  <bob@o-hand.com>
 
        * clutter/clutter-timeline.c:
index a13f0f8..09e2df5 100644 (file)
@@ -145,6 +145,7 @@ source_c = \
        clutter-feature.c               \
        clutter-fixed.c                 \
        clutter-group.c                 \
+       clutter-id-pool.c               \
        clutter-label.c                 \
        clutter-list-model.c            \
        clutter-main.c                  \
@@ -169,6 +170,7 @@ source_h_priv = \
        clutter-keysyms-table.h         \
        clutter-model-private.h         \
        clutter-private.h               \
+       clutter-id-pool.h               \
        clutter-script-private.h        \
        $(NULL)
 
index 71dabf5..5043ebe 100644 (file)
@@ -277,52 +277,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterActor,
                                                          clutter_scriptable_iface_init));
 
 
-static guint32
-create_actor_id (ClutterActor *actor)
-{
-  ClutterMainContext *context = CLUTTER_CONTEXT();
-  ClutterActor      **array;
-  guint32             id;
-
-  context = clutter_context_get_default ();
-
-  g_return_val_if_fail (context != NULL, 0);
-  g_return_val_if_fail (context->actor_array != NULL, 0);
-
-  /* There are items on our freelist */
-  if (context->free_actor_ids)
-    {
-      array = (void*) context->actor_array->data;
-      id = GPOINTER_TO_UINT (context->free_actor_ids->data);
-
-      context->free_actor_ids = g_slist_remove (context->free_actor_ids,
-                                                context->free_actor_ids->data);
-      array[id] = actor;
-      return id;
-    }
-
-  /* Allocate new id */
-  id = context->actor_array->len;
-  g_array_append_val (context->actor_array, actor);
-  return id;
-}
-
-static void
-release_actor_id (guint32 id)
-{
-  ClutterMainContext *context = CLUTTER_CONTEXT();
-  ClutterActor      **array;
-
-  context = clutter_context_get_default ();
-  g_return_if_fail (context != NULL);
-  g_return_if_fail (context->actor_array != NULL);
-
-  array = (void*) context->actor_array->data;
-  array[id] = (void*)0xdecafbad;
-
-  context->free_actor_ids = g_slist_prepend (context->free_actor_ids,
-                                             GUINT_TO_POINTER (id));
-}
 
 static gboolean
 redraw_update_idle (gpointer data)
@@ -1688,7 +1642,7 @@ clutter_actor_finalize (GObject *object)
                g_type_name (G_OBJECT_TYPE (actor)));
 
   g_free (actor->priv->name);
-  release_actor_id (actor->priv->id);
+  clutter_id_pool_remove (CLUTTER_CONTEXT()->id_pool, actor->priv->id);
 
   G_OBJECT_CLASS (clutter_actor_parent_class)->finalize (object);
 }
@@ -2368,7 +2322,7 @@ clutter_actor_init (ClutterActor *self)
   priv->parent_actor = NULL;
   priv->has_clip     = FALSE;
   priv->opacity      = 0xff;
-  priv->id           = create_actor_id (self);
+  priv->id           = clutter_id_pool_add (CLUTTER_CONTEXT()->id_pool, self);
   priv->scale_x      = CFX_ONE;
   priv->scale_y      = CFX_ONE;
   priv->shader_data  = NULL;
diff --git a/clutter/clutter-id-pool.c b/clutter/clutter-id-pool.c
new file mode 100644 (file)
index 0000000..fc47888
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2006-2008 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * ClutterIDPool: pool of reusable integer ids associated with pointers.
+ *
+ * Author: Øyvind Kolås <pippin@o-hand-com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-debug.h"
+#include "clutter-id-pool.h"
+
+struct _ClutterIDPool
+{
+  GArray *array;     /* Array of pointers    */
+  GSList *free_ids;  /* A stack of freed ids */
+};
+
+ClutterIDPool *
+clutter_id_pool_new  (guint initial_size)
+{
+  ClutterIDPool *self;
+
+  self = g_slice_new (ClutterIDPool);
+
+  self->array = g_array_sized_new (FALSE, FALSE, sizeof (gpointer), initial_size);
+  self->free_ids = NULL;
+  return self;
+}
+
+void
+clutter_id_pool_free (ClutterIDPool *id_pool)
+{
+  g_return_if_fail (id_pool != NULL);
+
+  g_array_free (id_pool->array, TRUE);
+  g_slist_free (id_pool->free_ids);
+  g_free (id_pool);
+}
+
+guint32
+clutter_id_pool_add (ClutterIDPool *id_pool,
+                     gpointer       ptr)
+{
+  gpointer *array;
+  guint32   id;
+
+  g_return_val_if_fail (id_pool != NULL, 0);
+
+  if (id_pool->free_ids) /* There are items on our freelist, reuse one */
+    {
+      array = (void*) id_pool->array->data;
+      id = GPOINTER_TO_UINT (id_pool->free_ids->data);
+
+      id_pool->free_ids = g_slist_remove (id_pool->free_ids,
+                                          id_pool->free_ids->data);
+      array[id] = ptr;
+      return id;
+    }
+
+  /* Allocate new id */
+  id = id_pool->array->len;
+  g_array_append_val (id_pool->array, ptr);
+  return id;
+}
+
+void
+clutter_id_pool_remove (ClutterIDPool *id_pool,
+                        guint32        id)
+{
+  gpointer *array;
+
+  g_return_if_fail (id_pool != NULL);
+  array = (void*) id_pool->array->data;
+
+  array[id] = (void*)0xdecafbad;   /* set pointer to a recognizably voided
+                                      value */
+
+  id_pool->free_ids = g_slist_prepend (id_pool->free_ids,
+                                       GUINT_TO_POINTER (id));
+}
+
+gpointer
+clutter_id_pool_lookup (ClutterIDPool *id_pool,
+                        guint32        id)
+{
+  gpointer *array;
+
+  g_return_val_if_fail (id_pool != NULL, NULL);
+  g_return_val_if_fail (id_pool->array != NULL, NULL);
+
+  g_return_val_if_fail (id < id_pool->array->len, NULL);
+
+  array = (void*) id_pool->array->data;
+
+  return array[id];
+}
diff --git a/clutter/clutter-id-pool.h b/clutter/clutter-id-pool.h
new file mode 100644 (file)
index 0000000..857cf6d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum  <mallum@openedhand.com>
+ *
+ * Copyright (C) 2008 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * ClutterIDPool: pool of reusable integer ids associated with pointers.
+ *
+ * Author: Øyvind Kolås <pippin@o-hand.com>
+ */
+
+#ifndef __CLUTTER_ID_POOL_H__
+#define __CLUTTER_ID_POOL_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ClutterIDPool   ClutterIDPool;
+
+
+ClutterIDPool *clutter_id_pool_new     (guint          initial_size);
+void           clutter_id_pool_free    (ClutterIDPool *id_pool);
+guint32        clutter_id_pool_add     (ClutterIDPool *id_pool,
+                                        gpointer       ptr);
+void           clutter_id_pool_remove  (ClutterIDPool *id_pool,
+                                        guint32        id);
+gpointer       clutter_id_pool_lookup  (ClutterIDPool *id_pool,
+                                        guint32        id);
+
+
+G_END_DECLS
+
+#endif /* __CLUTTER_ID_POOL_H__ */
index d34ab3b..10eeba0 100644 (file)
@@ -275,10 +275,9 @@ clutter_context_free (ClutterMainContext *context)
   /* this will take care of destroying the stage */
   g_object_unref (context->backend);
   context->backend = NULL;
-  g_array_free (context->actor_array, TRUE);
-  context->actor_array = NULL;
-  g_slist_free (context->free_actor_ids);
-  context->free_actor_ids = NULL;
+
+  clutter_id_pool_free (context->id_pool);
+  context->id_pool = NULL;
 
   /* XXX: The cleaning up of the event queue should be moved here from
           the backend base class. */
@@ -811,10 +810,7 @@ pre_parse_hook (GOptionContext  *context,
 
   clutter_context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
   pango_ft2_font_map_set_resolution (clutter_context->font_map, 96.0, 96.0);
-
-  clutter_context->actor_array = g_array_sized_new (FALSE, FALSE,
-                                                    sizeof (guint32), 256);
-  clutter_context->free_actor_ids = NULL;
+  clutter_context->id_pool = clutter_id_pool_new (256);
 
   backend = clutter_context->backend;
   g_assert (CLUTTER_IS_BACKEND (backend));
@@ -1571,18 +1567,12 @@ ClutterActor*
 clutter_get_actor_by_gid (guint32 id)
 {
   ClutterMainContext *context;
-  ClutterActor      **array;
 
   context = clutter_context_get_default ();
 
   g_return_val_if_fail (context != NULL, NULL);
-  g_return_val_if_fail (context->actor_array != NULL, NULL);
-
-  g_assert (id < context->actor_array->len);
-  g_return_val_if_fail (id < context->actor_array->len, NULL);
 
-  array = (void*) context->actor_array->data;
-  return array[id];
+  return CLUTTER_ACTOR (clutter_id_pool_lookup (context->id_pool, id));
 }
 
 void
index df2e011..815c94a 100644 (file)
@@ -44,6 +44,7 @@
 #include "clutter-backend.h"
 #include "clutter-stage.h"
 #include "clutter-feature.h"
+#include "clutter-id-pool.h"
 
 G_BEGIN_DECLS
 
@@ -83,8 +84,7 @@ struct _ClutterMainContext
   guint            motion_frequency;   /* Motion events per second */
   gint             num_reactives;      /* Num of reactive actors */
 
-  GArray          *actor_array;        /* Array of ClutterActors        */
-  GSList          *free_actor_ids;     /* A stack of released actor ids */
+  ClutterIDPool   *id_pool;            /* mapping between reused integer ids and actors */
 
   guint            frame_rate;         /* Default FPS */