summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2010-05-27 22:24:56 +0100
committerRobert Bragg <robert@linux.intel.com>2010-06-04 14:44:15 +0100
commit5af3ead3a2bbd18f4b1ee35eabffd20d740749c1 (patch)
treec738f5c82f5ea0e6fc3e2818d6b4e1f980fbbc22
parentef08c6369a0bb2a261fa16bf4323a5d524d5d788 (diff)
downloadcogl-5af3ead3a2bbd18f4b1ee35eabffd20d740749c1.tar.gz
CoglObject: Adds cogl_object_{get,set}_user_data
This provides a mechanism for associating private data with any CoglObject. We expect Clutter will use this to associate weak materials with normal materials.
-rw-r--r--cogl/Makefile.am3
-rw-r--r--cogl/cogl-handle.h2
-rw-r--r--cogl/cogl-object-private.h205
-rw-r--r--cogl/cogl-object.c246
-rw-r--r--cogl/cogl-object.h245
-rw-r--r--cogl/cogl-util.c61
-rw-r--r--cogl/cogl.h1
-rw-r--r--doc/reference/cogl/cogl-sections.txt6
8 files changed, 554 insertions, 215 deletions
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 127c83b9..f1247b0f 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -80,6 +80,9 @@ cogl_sources_c = \
$(srcdir)/cogl-context.c \
$(srcdir)/cogl-internal.h \
$(srcdir)/cogl.c \
+ $(srcdir)/cogl-object-private.h \
+ $(srcdir)/cogl-object.h \
+ $(srcdir)/cogl-object.c \
$(srcdir)/cogl-util.h \
$(srcdir)/cogl-util.c \
$(srcdir)/cogl-bitmap-private.h \
diff --git a/cogl/cogl-handle.h b/cogl/cogl-handle.h
index de63efb1..f69e97e5 100644
--- a/cogl/cogl-handle.h
+++ b/cogl/cogl-handle.h
@@ -29,7 +29,7 @@
#ifndef __COGL_HANDLE_H
#define __COGL_HANDLE_H
-#include "cogl-object.h"
+#include "cogl-object-private.h"
#endif /* __COGL_HANDLE_H */
diff --git a/cogl/cogl-object-private.h b/cogl/cogl-object-private.h
new file mode 100644
index 00000000..cc0965f4
--- /dev/null
+++ b/cogl/cogl-object-private.h
@@ -0,0 +1,205 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2008,2009,2010 Intel Corporation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Robert Bragg <robert@linux.intel.com>
+ */
+
+#ifndef __COGL_OBJECT_PRIVATE_H
+#define __COGL_OBJECT_PRIVATE_H
+
+#include "cogl-object.h"
+
+/* For compatability until all components have been converted */
+typedef struct _CoglObjectClass CoglHandleClass;
+typedef struct _CoglObject CoglHandleObject;
+
+typedef struct _CoglObjectClass
+{
+ GQuark type;
+ void *virt_free;
+} CoglObjectClass;
+
+#define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2
+
+typedef struct
+{
+ CoglUserDataKey *key;
+ void *user_data;
+ CoglUserDataDestroyCallback destroy;
+} CoglUserDataEntry;
+
+/* All Cogl objects inherit from this base object by adding a member:
+ *
+ * CoglObject _parent;
+ *
+ * at the top of its main structure. This structure is initialized
+ * when you call _cogl_#type_name#_object_new (new_object);
+ */
+struct _CoglObject
+{
+ unsigned int ref_count;
+
+ CoglUserDataEntry user_data_entry[
+ COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES];
+ GArray *user_data_array;
+ int n_user_data_entries;
+
+ CoglObjectClass *klass;
+};
+
+/* Helper macro to encapsulate the common code for COGL reference
+ counted objects */
+
+#ifdef COGL_OBJECT_DEBUG
+
+#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \
+ COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \
+ (obj), (obj)->ref_count)
+
+#define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \
+ CoglObject *__obj = (CoglObject *)object; \
+ COGL_NOTE (HANDLE, "COGL %s REF %p %i", \
+ g_quark_to_string ((__obj)->klass->type), \
+ (__obj), (__obj)->ref_count); } G_STMT_END
+
+#define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \
+ CoglObject *__obj = (CoglObject *)object; \
+ COGL_NOTE (HANDLE, "COGL %s UNREF %p %i", \
+ g_quark_to_string ((__obj)->klass->type), \
+ (__obj), (__obj)->ref_count - 1); } G_STMT_END
+
+#define COGL_OBJECT_DEBUG_FREE(obj) \
+ COGL_NOTE (HANDLE, "COGL %s FREE %p", \
+ g_quark_to_string ((obj)->klass->type), (obj))
+
+#else /* !COGL_OBJECT_DEBUG */
+
+#define _COGL_OBJECT_DEBUG_NEW(type_name, obj)
+#define _COGL_OBJECT_DEBUG_REF(type_name, obj)
+#define _COGL_OBJECT_DEBUG_UNREF(type_name, obj)
+#define COGL_OBJECT_DEBUG_FREE(obj)
+
+#endif /* COGL_OBJECT_DEBUG */
+
+/* For temporary compatability */
+#define _COGL_HANDLE_DEBUG_NEW _COGL_OBJECT_DEBUG_NEW
+#define _COGL_HANDLE_DEBUG_REF _COGL_OBJECT_DEBUG_REF
+#define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF
+#define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE
+
+#define COGL_OBJECT_DEFINE(TypeName, type_name) \
+ \
+static CoglObjectClass _cogl_##type_name##_class; \
+ \
+GQuark \
+_cogl_object_##type_name##_get_type (void) \
+{ \
+ static GQuark type = 0; \
+ if (!type) \
+ type = g_quark_from_static_string ("Cogl"#TypeName); \
+ return type; \
+} \
+ \
+GQuark \
+_cogl_handle_##type_name##_get_type (void) \
+{ \
+ return _cogl_object_##type_name##_get_type (); \
+} \
+ \
+static Cogl##TypeName * \
+_cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \
+{ \
+ CoglObject *obj = (CoglObject *)&new_obj->_parent; \
+ obj->ref_count = 1; \
+ obj->n_user_data_entries = 0; \
+ obj->user_data_array = NULL; \
+ \
+ obj->klass = &_cogl_##type_name##_class; \
+ if (!obj->klass->type) \
+ { \
+ obj->klass->type = _cogl_object_##type_name##_get_type ();\
+ obj->klass->virt_free = _cogl_##type_name##_free; \
+ } \
+ \
+ _COGL_OBJECT_DEBUG_NEW (TypeName, obj); \
+ return new_obj; \
+} \
+ \
+Cogl##TypeName * \
+_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
+{ \
+ return handle; \
+} \
+ \
+gboolean \
+cogl_is_##type_name (CoglHandle object) \
+{ \
+ CoglObject *obj = object; \
+ \
+ if (object == NULL) \
+ return FALSE; \
+ \
+ return (obj->klass->type == \
+ _cogl_object_##type_name##_get_type ()); \
+} \
+ \
+void * G_GNUC_DEPRECATED \
+cogl_##type_name##_ref (void *object) \
+{ \
+ if (!cogl_is_##type_name (object)) \
+ return NULL; \
+ \
+ _COGL_OBJECT_DEBUG_REF (TypeName, object); \
+ \
+ cogl_handle_ref (object); \
+ \
+ return object; \
+} \
+ \
+void G_GNUC_DEPRECATED \
+cogl_##type_name##_unref (void *object) \
+{ \
+ if (!cogl_is_##type_name (object)) \
+ { \
+ g_warning (G_STRINGIFY (cogl_##type_name##_unref) \
+ ": Ignoring unref of Cogl handle " \
+ "due to type mismatch"); \
+ return; \
+ } \
+ \
+ _COGL_OBJECT_DEBUG_UNREF (TypeName, object); \
+ \
+ cogl_handle_unref (object); \
+}
+
+/* For temporary compatability */
+#define COGL_HANDLE_DEFINE(TypeName, type_name) \
+ \
+COGL_OBJECT_DEFINE (TypeName, type_name) \
+ \
+static Cogl##TypeName * \
+_cogl_##type_name##_handle_new (CoglHandle handle) \
+{ \
+ return _cogl_##type_name##_object_new (handle); \
+}
+
+#endif /* __COGL_OBJECT_PRIVATE_H */
+
diff --git a/cogl/cogl-object.c b/cogl/cogl-object.c
new file mode 100644
index 00000000..aa11cef2
--- /dev/null
+++ b/cogl/cogl-object.c
@@ -0,0 +1,246 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2007,2008,2009,2010 Intel Corporation.
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Robert Bragg <robert@linux.intel.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+
+#include "cogl-types.h"
+#include "cogl-object-private.h"
+
+void *
+cogl_object_ref (void *object)
+{
+ CoglObject *obj = object;
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ obj->ref_count++;
+ return object;
+}
+
+CoglHandle
+cogl_handle_ref (CoglHandle handle)
+{
+ return cogl_object_ref (handle);
+}
+
+void
+cogl_object_unref (void *object)
+{
+ CoglObject *obj = object;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (obj->ref_count > 0);
+
+ if (--obj->ref_count < 1)
+ {
+ void (*free_func)(void *obj);
+
+ if (obj->n_user_data_entries)
+ {
+ int i;
+ int count = MIN (obj->n_user_data_entries,
+ COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
+
+ for (i = 0; i < count; i++)
+ {
+ CoglUserDataEntry *entry = &obj->user_data_entry[i];
+ if (entry->destroy)
+ entry->destroy (entry->user_data);
+ }
+
+ if (obj->user_data_array != NULL)
+ {
+ for (i = 0; i < obj->user_data_array->len; i++)
+ {
+ CoglUserDataEntry *entry =
+ &g_array_index (obj->user_data_array,
+ CoglUserDataEntry, i);
+
+ if (entry->destroy)
+ entry->destroy (entry->user_data);
+ }
+ }
+
+ g_array_free (obj->user_data_array, TRUE);
+ }
+
+ COGL_OBJECT_DEBUG_FREE (obj);
+ free_func = obj->klass->virt_free;
+ free_func (obj);
+ }
+}
+
+void
+cogl_handle_unref (CoglHandle handle)
+{
+ cogl_object_unref (handle);
+}
+
+GType
+cogl_object_get_type (void)
+{
+ static GType our_type = 0;
+
+ /* XXX: We are keeping the "CoglHandle" name for now incase it would
+ * break bindings to change to "CoglObject" */
+ if (G_UNLIKELY (our_type == 0))
+ our_type = g_boxed_type_register_static (g_intern_static_string ("CoglHandle"),
+ (GBoxedCopyFunc) cogl_object_ref,
+ (GBoxedFreeFunc) cogl_object_unref);
+
+ return our_type;
+}
+
+GType
+cogl_handle_get_type (void)
+{
+ return cogl_object_get_type ();
+}
+
+/* XXX: Unlike for cogl_object_get_user_data this code will return
+ * an empty entry if available and no entry for the given key can be
+ * found. */
+static CoglUserDataEntry *
+_cogl_object_find_entry (CoglObject *object, CoglUserDataKey *key)
+{
+ CoglUserDataEntry *entry = NULL;
+ int count;
+ int i;
+
+ count = MIN (object->n_user_data_entries,
+ COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
+
+ for (i = 0; i < count; i++)
+ {
+ CoglUserDataEntry *current = &object->user_data_entry[i];
+ if (current->key == key)
+ return current;
+ if (current->user_data == NULL)
+ entry = current;
+ }
+
+ if (G_UNLIKELY (object->user_data_array != NULL))
+ {
+ for (i = 0; i < object->user_data_array->len; i++)
+ {
+ CoglUserDataEntry *current =
+ &g_array_index (object->user_data_array, CoglUserDataEntry, i);
+
+ if (current->key == key)
+ return current;
+ if (current->user_data == NULL)
+ entry = current;
+ }
+ }
+
+ return entry;
+}
+
+void
+cogl_object_set_user_data (CoglObject *object,
+ CoglUserDataKey *key,
+ void *user_data,
+ CoglUserDataDestroyCallback destroy)
+{
+ CoglUserDataEntry new_entry;
+ CoglUserDataEntry *entry;
+
+ if (user_data)
+ {
+ new_entry.key = key;
+ new_entry.user_data = user_data;
+ new_entry.destroy = destroy;
+ }
+ else
+ memset (&new_entry, 0, sizeof (new_entry));
+
+ entry = _cogl_object_find_entry (object, key);
+ if (entry)
+ {
+ if (G_LIKELY (entry->destroy))
+ entry->destroy (entry->user_data);
+ }
+ else
+ {
+ if (G_LIKELY (object->n_user_data_entries <
+ COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES))
+ entry = &object->user_data_entry[object->n_user_data_entries++];
+ else
+ {
+ if (G_UNLIKELY (object->user_data_array == NULL))
+ {
+ object->user_data_array =
+ g_array_new (FALSE, FALSE, sizeof (CoglUserDataEntry));
+ }
+
+ g_array_set_size (object->user_data_array,
+ object->user_data_array->len + 1);
+ entry =
+ &g_array_index (object->user_data_array, CoglUserDataEntry,
+ object->user_data_array->len - 1);
+
+ object->n_user_data_entries++;
+ }
+ }
+
+ *entry = new_entry;
+}
+
+void *
+cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key)
+{
+ int count;
+ int i;
+
+ count = MIN (object->n_user_data_entries,
+ COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES);
+
+ for (i = 0; i < count; i++)
+ {
+ CoglUserDataEntry *entry = &object->user_data_entry[i];
+ if (entry->key == key)
+ return entry->user_data;
+ }
+
+ if (object->user_data_array != NULL)
+ {
+ for (i = 0; i < object->user_data_array->len; i++)
+ {
+ CoglUserDataEntry *entry =
+ &g_array_index (object->user_data_array, CoglUserDataEntry, i);
+
+ if (entry->key == key)
+ return entry->user_data;
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/cogl/cogl-object.h b/cogl/cogl-object.h
index 2ef15533..34de78f3 100644
--- a/cogl/cogl-object.h
+++ b/cogl/cogl-object.h
@@ -3,7 +3,7 @@
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
- * Copyright (C) 2008,2009 Intel Corporation.
+ * Copyright (C) 2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,8 @@
* 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, see <http://www.gnu.org/licenses/>.
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
*
*
*/
@@ -24,162 +25,100 @@
#ifndef __COGL_OBJECT_H
#define __COGL_OBJECT_H
-/* For compatability until all components have been converted */
-typedef struct _CoglObjectClass CoglHandleClass;
-typedef struct _CoglObject CoglHandleObject;
+typedef struct _CoglObject CoglObject;
-typedef struct _CoglObjectClass
-{
- GQuark type;
- void *virt_free;
-} CoglObjectClass;
-
-/* All Cogl objects inherit from this base object by adding a member:
+/**
+ * CoglUserDataKey:
+ * @unused: ignored.
+ *
+ * A #CoglUserDataKey is used to declare a key for attaching data to a
+ * #CoglObject using cogl_object_set_user_data. The typedef only exists as a
+ * formality to make code self documenting since only the unique address of a
+ * #CoglUserDataKey is used.
+ *
+ * Typically you would declare a static #CoglUserDataKey and set private data
+ * on an object something like this:
*
- * CoglObject _parent;
+ * |[
+ * static CoglUserDataKey path_private_key;
*
- * at the top of its main structure. This structure is initialized
- * when you call _cogl_#type_name#_object_new (new_object);
+ * static void
+ * destroy_path_private_cb (void *data)
+ * {
+ * g_free (data);
+ * }
+ *
+ * static void
+ * my_path_set_data (CoglPath *path, void *data)
+ * {
+ * cogl_object_set_user_data (COGL_OBJECT (path),
+ * &private_key,
+ * data,
+ * destroy_path_private_cb);
+ * }
+ * ]|
+ *
+ * Since: 1.4
*/
-typedef struct _CoglObject
+typedef struct
{
- unsigned int ref_count;
- CoglObjectClass *klass;
-} CoglObject;
-
-/* Helper macro to encapsulate the common code for COGL reference
- counted objects */
-
-#ifdef COGL_OBJECT_DEBUG
-
-#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \
- COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \
- (obj), (obj)->ref_count)
-
-#define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \
- CoglObject *__obj = (CoglObject *)object; \
- COGL_NOTE (HANDLE, "COGL %s REF %p %i", \
- g_quark_to_string ((__obj)->klass->type), \
- (__obj), (__obj)->ref_count); } G_STMT_END
-
-#define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \
- CoglObject *__obj = (CoglObject *)object; \
- COGL_NOTE (HANDLE, "COGL %s UNREF %p %i", \
- g_quark_to_string ((__obj)->klass->type), \
- (__obj), (__obj)->ref_count - 1); } G_STMT_END
-
-#define COGL_OBJECT_DEBUG_FREE(obj) \
- COGL_NOTE (HANDLE, "COGL %s FREE %p", \
- g_quark_to_string ((obj)->klass->type), (obj))
-
-#else /* !COGL_OBJECT_DEBUG */
-
-#define _COGL_OBJECT_DEBUG_NEW(type_name, obj)
-#define _COGL_OBJECT_DEBUG_REF(type_name, obj)
-#define _COGL_OBJECT_DEBUG_UNREF(type_name, obj)
-#define COGL_OBJECT_DEBUG_FREE(obj)
-
-#endif /* COGL_OBJECT_DEBUG */
-
-/* For temporary compatability */
-#define _COGL_HANDLE_DEBUG_NEW _COGL_OBJECT_DEBUG_NEW
-#define _COGL_HANDLE_DEBUG_REF _COGL_OBJECT_DEBUG_REF
-#define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF
-#define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE
-
-#define COGL_OBJECT_DEFINE(TypeName, type_name) \
- \
-static CoglObjectClass _cogl_##type_name##_class; \
- \
-GQuark \
-_cogl_object_##type_name##_get_type (void) \
-{ \
- static GQuark type = 0; \
- if (!type) \
- type = g_quark_from_static_string ("Cogl"#TypeName); \
- return type; \
-} \
- \
-GQuark \
-_cogl_handle_##type_name##_get_type (void) \
-{ \
- return _cogl_object_##type_name##_get_type (); \
-} \
- \
-static Cogl##TypeName * \
-_cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \
-{ \
- CoglObject *obj = (CoglObject *)&new_obj->_parent;\
- obj->ref_count = 1; \
- \
- obj->klass = &_cogl_##type_name##_class; \
- if (!obj->klass->type) \
- { \
- obj->klass->type = _cogl_object_##type_name##_get_type ();\
- obj->klass->virt_free = _cogl_##type_name##_free; \
- } \
- \
- _COGL_OBJECT_DEBUG_NEW (TypeName, obj); \
- return new_obj; \
-} \
- \
-Cogl##TypeName * \
-_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
-{ \
- return handle; \
-} \
- \
-gboolean \
-cogl_is_##type_name (CoglHandle object) \
-{ \
- CoglObject *obj = object; \
- \
- if (object == NULL) \
- return FALSE; \
- \
- return (obj->klass->type == \
- _cogl_object_##type_name##_get_type ()); \
-} \
- \
-void * G_GNUC_DEPRECATED \
-cogl_##type_name##_ref (void *object) \
-{ \
- if (!cogl_is_##type_name (object)) \
- return NULL; \
- \
- _COGL_OBJECT_DEBUG_REF (TypeName, object); \
- \
- cogl_handle_ref (object); \
- \
- return object; \
-} \
- \
-void G_GNUC_DEPRECATED \
-cogl_##type_name##_unref (void *object) \
-{ \
- if (!cogl_is_##type_name (object)) \
- { \
- g_warning (G_STRINGIFY (cogl_##type_name##_unref) \
- ": Ignoring unref of Cogl handle " \
- "due to type mismatch"); \
- return; \
- } \
- \
- _COGL_OBJECT_DEBUG_UNREF (TypeName, object); \
- \
- cogl_handle_unref (object); \
-}
-
-/* For temporary compatability */
-#define COGL_HANDLE_DEFINE(TypeName, type_name) \
- \
-COGL_OBJECT_DEFINE (TypeName, type_name) \
- \
-static Cogl##TypeName * \
-_cogl_##type_name##_handle_new (CoglHandle handle) \
-{ \
- return _cogl_##type_name##_object_new (handle); \
-}
+ int unused;
+} CoglUserDataKey;
+/**
+ * CoglUserDataDestroyCallback:
+ * @user_data: The data whos association with a #CoglObject has been
+ * destoyed.
+ *
+ * When associating private data with a #CoglObject a callback can be
+ * given which will be called either if the object is destroyed or if
+ * cogl_object_set_user_data() is called with NULL user_data for the
+ * same key.
+ *
+ * Since: 1.4
+ */
+typedef void (*CoglUserDataDestroyCallback) (void *user_data);
+
+/**
+ * cogl_object_set_user_data:
+ * @object: The object to associate private data with
+ * @key: The address of a #CoglUserDataKey which provides a unique value
+ * with which to index the private data.
+ * @user_data: The data to associate with the given object, or NULL to
+ * remove a previous association.
+ * @destroy: A #CoglUserDataDestroyCallback to call if the object is
+ * destroyed or if the association is removed by later setting
+ * NULL data for the same key.
+ *
+ * Associates some private @user_data with a given #CoglObject. To
+ * later remove the association call cogl_object_set_user_data() with
+ * the same @key but NULL for the @user_data.
+ *
+ * Since: 1.4
+ */
+void
+cogl_object_set_user_data (CoglObject *object,
+ CoglUserDataKey *key,
+ void *user_data,
+ CoglUserDataDestroyCallback destroy);
+
+/**
+ * cogl_object_get_user_data:
+ * @object: The object with associated private data to query
+ * @key: The address of a #CoglUserDataKey which provides a unique value
+ * with which to index the private data.
+ *
+ * Finds the user data previously associated with @object using
+ * the given @key. If no user data has been associated with @object
+ * for the given @key this function returns NULL.
+ *
+ * Returns: The user data previously associated with @object using
+ * the given @key; or NULL if no associated data is found.
+ *
+ * Since: 1.4
+ */
+void *
+cogl_object_get_user_data (CoglObject *object,
+ CoglUserDataKey *key);
#endif /* __COGL_OBJECT_H */
diff --git a/cogl/cogl-util.c b/cogl/cogl-util.c
index cc28b08e..369017b8 100644
--- a/cogl/cogl-util.c
+++ b/cogl/cogl-util.c
@@ -61,67 +61,6 @@ cogl_util_next_p2 (int a)
/* gtypes */
-void *
-cogl_object_ref (void *object)
-{
- CoglObject *obj = object;
-
- g_return_val_if_fail (object != NULL, NULL);
-
- obj->ref_count++;
- return object;
-}
-
-CoglHandle
-cogl_handle_ref (CoglHandle handle)
-{
- return cogl_object_ref (handle);
-}
-
-void
-cogl_object_unref (void *object)
-{
- CoglObject *obj = object;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (obj->ref_count > 0);
-
- if (--obj->ref_count < 1)
- {
- void (*free_func)(void *obj);
-
- COGL_OBJECT_DEBUG_FREE (obj);
- free_func = obj->klass->virt_free;
- free_func (obj);
- }
-}
-
-void
-cogl_handle_unref (CoglHandle handle)
-{
- cogl_object_unref (handle);
-}
-
-GType
-cogl_object_get_type (void)
-{
- static GType our_type = 0;
-
- /* XXX: We are keeping the "CoglHandle" name for now incase it would
- * break bindings to change to "CoglObject" */
- if (G_UNLIKELY (our_type == 0))
- our_type = g_boxed_type_register_static (g_intern_static_string ("CoglHandle"),
- (GBoxedCopyFunc) cogl_object_ref,
- (GBoxedFreeFunc) cogl_object_unref);
-
- return our_type;
-}
-
-GType
-cogl_handle_get_type (void)
-{
- return cogl_object_get_type ();
-}
/*
* CoglFixed
*/
diff --git a/cogl/cogl.h b/cogl/cogl.h
index 2121851e..88c7058b 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -31,6 +31,7 @@
#include <cogl/cogl-defines.h>
+#include <cogl/cogl-object.h>
#include <cogl/cogl-bitmap.h>
#include <cogl/cogl-color.h>
#include <cogl/cogl-debug.h>
diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt
index 362ac66b..2d98cf13 100644
--- a/doc/reference/cogl/cogl-sections.txt
+++ b/doc/reference/cogl/cogl-sections.txt
@@ -1,6 +1,12 @@
<SECTION>
<FILE>cogl</FILE>
<TITLE>General API</TITLE>
+CoglObject
+cogl_object_ref
+cogl_object_unref
+CoglUserDataKey
+cogl_object_get_user_data
+cogl_object_set_user_data
COGL_INVALID_HANDLE
CoglHandle
cogl_handle_ref