| /* GObject - GLib Type, Object, Parameter and Signal Library |
| * Copyright (C) 2001, 2003 Red Hat, Inc. |
| * |
| * 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/>. |
| */ |
| |
| #undef G_LOG_DOMAIN |
| #define G_LOG_DOMAIN "TestIfaceInherit" |
| |
| #undef G_DISABLE_ASSERT |
| #undef G_DISABLE_CHECKS |
| #undef G_DISABLE_CAST_CHECKS |
| |
| #include <glib-object.h> |
| |
| #include "testcommon.h" |
| #include "testmodule.h" |
| |
| /* This test tests inheritance of interface. We two object |
| * class BaseObject and DerivedObject we add an interface |
| * to BaseObject: |
| * |
| * I1) Before DerivedObject is registered |
| * I2) After DerivedObject is registered, but before |
| * DerivedObject is class initialized |
| * I3) During DerivedObject's class_init |
| * I4) After DerivedObject's class init |
| * |
| * We also do some tests of overriding. |
| * |
| * I5) We add an interface to BaseObject, then add the same |
| * interface to DerivedObject. (Note that this is only legal |
| * before DerivedObject's class_init; the results of |
| * g_type_interface_peek() are not allowed to change from one |
| * non-NULL vtable to another non-NULL vtable) |
| */ |
| |
| /* |
| * BaseObject, a parent class for DerivedObject |
| */ |
| #define BASE_TYPE_OBJECT (base_object_get_type ()) |
| typedef struct _BaseObject BaseObject; |
| typedef struct _BaseObjectClass BaseObjectClass; |
| |
| struct _BaseObject |
| { |
| GObject parent_instance; |
| }; |
| struct _BaseObjectClass |
| { |
| GObjectClass parent_class; |
| }; |
| |
| static GType base_object_get_type (void); |
| static GType derived_object_get_type (void); |
| |
| /* |
| * DerivedObject, the child class of DerivedObject |
| */ |
| #define DERIVED_TYPE_OBJECT (derived_object_get_type ()) |
| typedef struct _DerivedObject DerivedObject; |
| typedef struct _DerivedObjectClass DerivedObjectClass; |
| |
| struct _DerivedObject |
| { |
| BaseObject parent_instance; |
| }; |
| struct _DerivedObjectClass |
| { |
| BaseObjectClass parent_class; |
| }; |
| |
| /* |
| * The interfaces |
| */ |
| typedef struct _TestIfaceClass TestIfaceClass; |
| typedef struct _TestIfaceClass TestIface1Class; |
| typedef struct _TestIfaceClass TestIface2Class; |
| typedef struct _TestIfaceClass TestIface3Class; |
| typedef struct _TestIfaceClass TestIface4Class; |
| typedef struct _TestIfaceClass TestIface5Class; |
| |
| struct _TestIfaceClass |
| { |
| GTypeInterface base_iface; |
| guint val; |
| }; |
| |
| static GType test_iface1_get_type (void); |
| static GType test_iface2_get_type (void); |
| static GType test_iface3_get_type (void); |
| static GType test_iface4_get_type (void); |
| static GType test_iface5_get_type (void); |
| |
| #define TEST_TYPE_IFACE1 (test_iface1_get_type ()) |
| #define TEST_TYPE_IFACE2 (test_iface2_get_type ()) |
| #define TEST_TYPE_IFACE3 (test_iface3_get_type ()) |
| #define TEST_TYPE_IFACE4 (test_iface4_get_type ()) |
| #define TEST_TYPE_IFACE5 (test_iface5_get_type ()) |
| |
| static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL) |
| static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL) |
| static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL) |
| static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL) |
| static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL) |
| |
| static void |
| add_interface (GType object_type, |
| GType iface_type, |
| GInterfaceInitFunc init_func) |
| { |
| GInterfaceInfo iface_info = { NULL, NULL, NULL }; |
| |
| iface_info.interface_init = init_func; |
| |
| g_type_add_interface_static (object_type, iface_type, &iface_info); |
| } |
| |
| static void |
| init_base_interface (TestIfaceClass *iface) |
| { |
| iface->val = 21; |
| } |
| |
| static void |
| add_base_interface (GType object_type, |
| GType iface_type) |
| { |
| add_interface (object_type, iface_type, |
| (GInterfaceInitFunc)init_base_interface); |
| } |
| |
| static gboolean |
| interface_is_base (GType object_type, |
| GType iface_type) |
| { |
| gpointer g_class = g_type_class_peek (object_type); |
| TestIfaceClass *iface = g_type_interface_peek (g_class, iface_type); |
| return iface && iface->val == 21; |
| } |
| |
| static void |
| init_derived_interface (TestIfaceClass *iface) |
| { |
| iface->val = 42; |
| } |
| |
| static void |
| add_derived_interface (GType object_type, |
| GType iface_type) |
| { |
| add_interface (object_type, iface_type, |
| (GInterfaceInitFunc)init_derived_interface); |
| } |
| |
| static gboolean |
| interface_is_derived (GType object_type, |
| GType iface_type) |
| { |
| gpointer g_class = g_type_class_peek (object_type); |
| TestIfaceClass *iface = g_type_interface_peek (g_class, iface_type); |
| return iface && iface->val == 42; |
| } |
| |
| static void |
| derived_object_class_init (BaseObjectClass *class) |
| { |
| add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE3); |
| } |
| |
| static DEFINE_TYPE(BaseObject, base_object, |
| NULL, NULL, NULL, |
| G_TYPE_OBJECT) |
| static DEFINE_TYPE(DerivedObject, derived_object, |
| derived_object_class_init, NULL, NULL, |
| BASE_TYPE_OBJECT) |
| |
| int |
| main (int argc, |
| char *argv[]) |
| { |
| g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | |
| G_LOG_LEVEL_WARNING | |
| G_LOG_LEVEL_CRITICAL); |
| |
| /* Register BaseObject */ |
| BASE_TYPE_OBJECT; |
| |
| add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE5); |
| |
| /* Class init BaseObject */ |
| g_type_class_ref (BASE_TYPE_OBJECT); |
| |
| add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE1); |
| |
| /* Register DerivedObject */ |
| DERIVED_TYPE_OBJECT; |
| |
| add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE2); |
| add_derived_interface (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE5); |
| |
| /* Class init DerivedObject */ |
| g_type_class_ref (DERIVED_TYPE_OBJECT); |
| |
| add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE4); |
| |
| /* Check that all the non-overridden interfaces were properly inherited |
| */ |
| g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE1)); |
| g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE2)); |
| g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE3)); |
| g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE4)); |
| |
| /* Check that all the overridden interfaces were properly overridden |
| */ |
| g_assert (interface_is_derived (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE5)); |
| |
| return 0; |
| } |