CoglObject: Adds cogl_object_{get,set}_user_data
authorRobert Bragg <robert@linux.intel.com>
Thu, 27 May 2010 21:24:56 +0000 (22:24 +0100)
committerRobert Bragg <robert@linux.intel.com>
Fri, 4 Jun 2010 13:44:15 +0000 (14:44 +0100)
This provides a mechanism for associating private data with any
CoglObject. We expect Clutter will use this to associate weak materials
with normal materials.

clutter/cogl/cogl/Makefile.am
clutter/cogl/cogl/cogl-handle.h
clutter/cogl/cogl/cogl-object-private.h [new file with mode: 0644]
clutter/cogl/cogl/cogl-object.c [new file with mode: 0644]
clutter/cogl/cogl/cogl-object.h
clutter/cogl/cogl/cogl-util.c
clutter/cogl/cogl/cogl.h
doc/reference/cogl/cogl-sections.txt

index 127c83b..f1247b0 100644 (file)
@@ -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                 \
index de63efb..f69e97e 100644 (file)
@@ -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/clutter/cogl/cogl/cogl-object-private.h b/clutter/cogl/cogl/cogl-object-private.h
new file mode 100644 (file)
index 0000000..cc0965f
--- /dev/null
@@ -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/clutter/cogl/cogl/cogl-object.c b/clutter/cogl/cogl/cogl-object.c
new file mode 100644 (file)
index 0000000..aa11cef
--- /dev/null
@@ -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;
+}
+
index 2ef1553..34de78f 100644 (file)
@@ -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/>.
  *
  *
  */
 #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 */
 
index cc28b08..369017b 100644 (file)
@@ -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
  */
index 2121851..88c7058 100644 (file)
@@ -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>
index 362ac66..2d98cf1 100644 (file)
@@ -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