/* * 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, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #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); */ typedef struct _CoglHandleObject { guint 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) \ g_debug ("COGL " G_STRINGIFY (type_name) " NEW %p %i\n", \ (obj), (obj)->ref_count) #define _COGL_HANDLE_DEBUG_REF(type_name, handle) G_STMT_START { \ CoglHandleObject *__obj = (CoglHandleObject *)handle; \ g_debug ("COGL %s REF %p %i\n", \ 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; \ g_debug ("COGL %s UNREF %p %i\n", \ g_quark_to_string ((__obj)->klass->type), \ (__obj), (__obj)->ref_count - 1); } G_STMT_END #define COGL_HANDLE_DEBUG_FREE(obj) \ g_debug ("COGL %s FREE %p\n", 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 */ #define COGL_HANDLE_DEFINE(TypeName, type_name) \ \ static CoglHandleClass _cogl_##type_name##_class; \ \ static GQuark \ _cogl_##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 = &new_obj->_parent; \ obj->ref_count = 1; \ \ obj->klass = &_cogl_##type_name##_class; \ if (!obj->klass->type) \ { \ obj->klass->type = _cogl_##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_##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); \ } #endif /* __COGL_HANDLE_H */