Start eradicating the CoglHandle typedef
authorRobert Bragg <robert@linux.intel.com>
Thu, 27 May 2010 22:31:40 +0000 (23:31 +0100)
committerRobert Bragg <robert@linux.intel.com>
Fri, 28 May 2010 17:39:22 +0000 (18:39 +0100)
CoglHandle is a common source of complaints and confusion because people
expect a "handle" to be some form of integer type with some indirection
to lookup the corresponding objects as opposed to a direct pointer.

This patch starts by renaming CoglHandle to CoglObject * and creating
corresponding cogl_object_ APIs to replace the cogl_handle ones.

The next step though is to remove all use of CoglHandle in the Cogl APIs
and replace with strongly typed pointer types such as CoglMaterial * or
CoglTexture * etc also all occurrences of COGL_INVALID_HANDLE can just
use NULL instead.

After this we will consider switching to GTypeInstance internally so we
can have inheritance for our types and hopefully improve how we handle
bindings.

Note all these changes will be done in a way that maintains the API and
ABI.

clutter/cogl/cogl/cogl-handle.h
clutter/cogl/cogl/cogl-object.h [new file with mode: 0644]
clutter/cogl/cogl/cogl-types.h
clutter/cogl/cogl/cogl-util.c

index 576598e..de63efb 100644 (file)
@@ -3,7 +3,7 @@
  *
  * An object oriented GL/GLES Abstraction/Utility Layer
  *
- * Copyright (C) 2008,2009 Intel Corporation.
+ * Copyright (C) 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
  * 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_HANDLE_H
-#define __COGL_HANDLE_H
-
-typedef struct _CoglHandleClass
-{
-  GQuark   type;
-  void    *virt_free;
-} CoglHandleClass;
-
-/* All Cogl objects inherit from this base object by adding a member:
- *
- *   CoglHandleObject _parent;
- *
- * at the top of its main structure. This structure is initialized
- * when you call _cogl_#type_name#_handle_new (new_object);
+/* This file is just kept for compatability while we eradicate
+ * CoglHandle
  */
-typedef struct _CoglHandleObject
-{
-  unsigned int     ref_count;
-  CoglHandleClass *klass;
-} CoglHandleObject;
-
-/* Helper macro to encapsulate the common code for COGL reference
-   counted handles */
-
-#ifdef COGL_HANDLE_DEBUG
-
-#define _COGL_HANDLE_DEBUG_NEW(type_name, obj)                         \
-  COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW   %p %i",    \
-            (obj), (obj)->ref_count)
 
-#define _COGL_HANDLE_DEBUG_REF(type_name, handle)       G_STMT_START {  \
-  CoglHandleObject *__obj = (CoglHandleObject *)handle;                 \
-  COGL_NOTE (HANDLE, "COGL %s REF %p %i",                              \
-             g_quark_to_string ((__obj)->klass->type),                  \
-             (__obj), (__obj)->ref_count);              } G_STMT_END
-
-#define _COGL_HANDLE_DEBUG_UNREF(type_name, handle)     G_STMT_START {  \
-  CoglHandleObject *__obj = (CoglHandleObject *)handle;                 \
-  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_HANDLE_DEBUG_FREE(obj)                                     \
-  COGL_NOTE (HANDLE, "COGL %s FREE %p",                                 \
-             g_quark_to_string ((obj)->klass->type), (obj))
-
-#else /* !COGL_HANDLE_DEBUG */
-
-#define _COGL_HANDLE_DEBUG_NEW(type_name, obj)
-#define _COGL_HANDLE_DEBUG_REF(type_name, obj)
-#define _COGL_HANDLE_DEBUG_UNREF(type_name, obj)
-#define COGL_HANDLE_DEBUG_FREE(obj)
-
-#endif /* COGL_HANDLE_DEBUG */
+#ifndef __COGL_HANDLE_H
+#define __COGL_HANDLE_H
 
-#define COGL_HANDLE_DEFINE(TypeName, type_name)                        \
-                                                               \
-static CoglHandleClass _cogl_##type_name##_class;               \
-                                                               \
-GQuark                                                          \
-_cogl_handle_##type_name##_get_type (void)                      \
-{                                                               \
-  static GQuark type = 0;                                       \
-  if (!type)                                                    \
-    type = g_quark_from_static_string ("Cogl"#TypeName);        \
-  return type;                                                  \
-}                                                               \
-                                                               \
-static CoglHandle                                              \
-_cogl_##type_name##_handle_new (Cogl##TypeName *new_obj)       \
-{                                                              \
-  CoglHandleObject *obj = (CoglHandleObject *)&new_obj->_parent;\
-  obj->ref_count = 1;                                           \
-                                                               \
-  obj->klass = &_cogl_##type_name##_class;                      \
-  if (!obj->klass->type)                                        \
-    {                                                           \
-      obj->klass->type = _cogl_handle_##type_name##_get_type ();\
-      obj->klass->virt_free = _cogl_##type_name##_free;         \
-    }                                                           \
-                                                               \
-  _COGL_HANDLE_DEBUG_NEW (TypeName, obj);                       \
-  return (CoglHandle) new_obj;                                 \
-}                                                              \
-                                                               \
-Cogl##TypeName *                                               \
-_cogl_##type_name##_pointer_from_handle (CoglHandle handle)    \
-{                                                              \
-  return (Cogl##TypeName *) handle;                            \
-}                                                              \
-                                                               \
-gboolean                                                       \
-cogl_is_##type_name (CoglHandle handle)                                \
-{                                                               \
-  CoglHandleObject *obj = (CoglHandleObject *)handle;           \
-                                                                \
-  if (handle == COGL_INVALID_HANDLE)                            \
-    return FALSE;                                               \
-                                                                \
-  return (obj->klass->type ==                                   \
-          _cogl_handle_##type_name##_get_type ());              \
-}                                                              \
-                                                               \
-CoglHandle G_GNUC_DEPRECATED                                   \
-cogl_##type_name##_ref (CoglHandle handle)                     \
-{                                                              \
-  if (!cogl_is_##type_name (handle))                           \
-    return COGL_INVALID_HANDLE;                                        \
-                                                                \
-  _COGL_HANDLE_DEBUG_REF (TypeName, handle);                   \
-                                                               \
-  cogl_handle_ref (handle);                                     \
-                                                               \
-  return handle;                                               \
-}                                                              \
-                                                               \
-void G_GNUC_DEPRECATED                                         \
-cogl_##type_name##_unref (CoglHandle handle)                   \
-{                                                              \
-  if (!cogl_is_##type_name (handle))                           \
-    {                                                           \
-      g_warning (G_STRINGIFY (cogl_##type_name##_unref)         \
-                 ": Ignoring unref of Cogl handle "             \
-                 "due to type mismatch");                       \
-      return;                                                  \
-    }                                                           \
-                                                               \
-  _COGL_HANDLE_DEBUG_UNREF (TypeName, handle);                 \
-                                                                \
-  cogl_handle_unref (handle);                                   \
-}
+#include "cogl-object.h"
 
 #endif /* __COGL_HANDLE_H */
+
diff --git a/clutter/cogl/cogl/cogl-object.h b/clutter/cogl/cogl/cogl-object.h
new file mode 100644 (file)
index 0000000..bfa660b
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2008,2009 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/>.
+ *
+ *
+ */
+
+#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 _CoglObjectClass
+{
+  GQuark   type;
+  void    *virt_free;
+} CoglObjectClass;
+
+/* 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);
+ */
+typedef struct _CoglObject
+{
+  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;                                              \
+}                                                              \
+                                                               \
+static Cogl##TypeName *                                                \
+_cogl_##type_name##_handle_new (CoglHandle handle)             \
+{                                                               \
+  return _cogl_##type_name##_object_new (handle);               \
+}                                                               \
+                                                               \
+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 COGL_OBJECT_DEFINE
+
+#endif /* __COGL_OBJECT_H */
+
index 547ed12..61a3eff 100644 (file)
@@ -84,6 +84,27 @@ void
 cogl_handle_unref (CoglHandle Handle);
 
 /**
+ * cogl_handle_ref:
+ * @object: a #CoglObject
+ *
+ * Increases the reference count of @handle by 1
+ *
+ * Returns: the @object, with its reference count increased
+ */
+void *
+cogl_object_ref (void *object);
+
+/**
+ * cogl_handle_unref:
+ * @object: a #CoglObject
+ *
+ * Drecreases the reference count of @object by 1; if the reference
+ * count reaches 0, the resources allocated by @object will be freed
+ */
+void
+cogl_object_unref (void *object);
+
+/**
  * CoglFuncPtr:
  *
  * The type used by cogl for function pointers, note that this type
index 622b785..cc28b08 100644 (file)
@@ -61,48 +61,67 @@ cogl_util_next_p2 (int a)
 
 /* gtypes */
 
-CoglHandle
-cogl_handle_ref (CoglHandle handle)
+void *
+cogl_object_ref (void *object)
 {
-  CoglHandleObject *obj = (CoglHandleObject *)handle;
+  CoglObject *obj = object;
 
-  g_return_val_if_fail (handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
+  g_return_val_if_fail (object != NULL, NULL);
 
   obj->ref_count++;
-  return handle;
+  return object;
+}
+
+CoglHandle
+cogl_handle_ref (CoglHandle handle)
+{
+  return cogl_object_ref (handle);
 }
 
 void
-cogl_handle_unref (CoglHandle handle)
+cogl_object_unref (void *object)
 {
-  CoglHandleObject *obj = (CoglHandleObject *)handle;
+  CoglObject *obj = object;
 
-  g_return_if_fail (handle != COGL_INVALID_HANDLE);
+  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_HANDLE_DEBUG_FREE (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_handle_get_type (void)
+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_handle_ref,
-                                            (GBoxedFreeFunc) cogl_handle_unref);
+                                             (GBoxedCopyFunc) cogl_object_ref,
+                                             (GBoxedFreeFunc) cogl_object_unref);
 
   return our_type;
 }
 
+GType
+cogl_handle_get_type (void)
+{
+  return cogl_object_get_type ();
+}
 /*
  * CoglFixed
  */