diff --git a/ChangeLog b/ChangeLog index 9ca1ced2f..78ac9ae9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-03-07 Øyvind Kolås + + 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 * clutter/clutter-timeline.c: diff --git a/clutter/Makefile.am b/clutter/Makefile.am index a13f0f826..09e2df51d 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -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) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 71dabf5fb..5043ebe5d 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -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 index 000000000..fc47888d9 --- /dev/null +++ b/clutter/clutter-id-pool.c @@ -0,0 +1,122 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * 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 + * + */ + +#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 index 000000000..857cf6d07 --- /dev/null +++ b/clutter/clutter-id-pool.h @@ -0,0 +1,52 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * 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 + */ + +#ifndef __CLUTTER_ID_POOL_H__ +#define __CLUTTER_ID_POOL_H__ + +#include + +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__ */ diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index d34ab3b58..10eeba0b0 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -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 diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index df2e011c3..815c94a30 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -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 */