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.
This commit is contained in:
Øyvind Kolås 2008-03-07 17:34:40 +00:00
parent d628513f9d
commit cdf8bb0739
7 changed files with 197 additions and 65 deletions

View File

@ -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:

View 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)

View 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;

122
clutter/clutter-id-pool.c Normal file
View File

@ -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];
}

52
clutter/clutter-id-pool.h Normal file
View File

@ -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__ */

View 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

View 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 */