1 /* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 2001, 2003 Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General 15 * Public License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 #undef G_LOG_DOMAIN 21 #define G_LOG_DOMAIN "TestIfaceInherit" 22 23 #undef G_DISABLE_ASSERT 24 #undef G_DISABLE_CHECKS 25 #undef G_DISABLE_CAST_CHECKS 26 27 #include <glib-object.h> 28 29 #include "testcommon.h" 30 #include "testmodule.h" 31 32 /* This test tests inheritance of interface. We two object 33 * class BaseObject and DerivedObject we add an interface 34 * to BaseObject: 35 * 36 * I1) Before DerivedObject is registered 37 * I2) After DerivedObject is registered, but before 38 * DerivedObject is class initialized 39 * I3) During DerivedObject's class_init 40 * I4) After DerivedObject's class init 41 * 42 * We also do some tests of overriding. 43 * 44 * I5) We add an interface to BaseObject, then add the same 45 * interface to DerivedObject. (Note that this is only legal 46 * before DerivedObject's class_init; the results of 47 * g_type_interface_peek() are not allowed to change from one 48 * non-NULL vtable to another non-NULL vtable) 49 */ 50 51 /* 52 * BaseObject, a parent class for DerivedObject 53 */ 54 #define BASE_TYPE_OBJECT (base_object_get_type ()) 55 typedef struct _BaseObject BaseObject; 56 typedef struct _BaseObjectClass BaseObjectClass; 57 58 struct _BaseObject 59 { 60 GObject parent_instance; 61 }; 62 struct _BaseObjectClass 63 { 64 GObjectClass parent_class; 65 }; 66 67 static GType base_object_get_type (); 68 static GType derived_object_get_type (); 69 70 /* 71 * DerivedObject, the child class of DerivedObject 72 */ 73 #define DERIVED_TYPE_OBJECT (derived_object_get_type ()) 74 typedef struct _DerivedObject DerivedObject; 75 typedef struct _DerivedObjectClass DerivedObjectClass; 76 77 struct _DerivedObject 78 { 79 BaseObject parent_instance; 80 }; 81 struct _DerivedObjectClass 82 { 83 BaseObjectClass parent_class; 84 }; 85 86 /* 87 * The interfaces 88 */ 89 typedef struct _TestIfaceClass TestIfaceClass; 90 typedef struct _TestIfaceClass TestIface1Class; 91 typedef struct _TestIfaceClass TestIface2Class; 92 typedef struct _TestIfaceClass TestIface3Class; 93 typedef struct _TestIfaceClass TestIface4Class; 94 typedef struct _TestIfaceClass TestIface5Class; 95 96 struct _TestIfaceClass 97 { 98 GTypeInterface base_iface; 99 guint val; 100 }; 101 102 #define TEST_TYPE_IFACE1 (test_iface1_get_type ()) 103 #define TEST_TYPE_IFACE2 (test_iface2_get_type ()) 104 #define TEST_TYPE_IFACE3 (test_iface3_get_type ()) 105 #define TEST_TYPE_IFACE4 (test_iface4_get_type ()) 106 #define TEST_TYPE_IFACE5 (test_iface5_get_type ()) 107 108 static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL) 109 static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL) 110 static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL) 111 static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL) 112 static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL) 113 114 static void 115 add_interface (GType object_type, 116 GType iface_type, 117 GInterfaceInitFunc init_func) 118 { 119 GInterfaceInfo iface_info = { NULL, NULL, NULL }; 120 121 iface_info.interface_init = init_func; 122 123 g_type_add_interface_static (object_type, iface_type, &iface_info); 124 } 125 126 static void 127 init_base_interface (TestIfaceClass *iface) 128 { 129 iface->val = 21; 130 } 131 132 static void 133 add_base_interface (GType object_type, 134 GType iface_type) 135 { 136 add_interface (object_type, iface_type, 137 (GInterfaceInitFunc)init_base_interface); 138 } 139 140 static gboolean 141 interface_is_base (GType object_type, 142 GType iface_type) 143 { 144 gpointer g_class = g_type_class_peek (object_type); 145 TestIfaceClass *iface = g_type_interface_peek (g_class, iface_type); 146 return iface && iface->val == 21; 147 } 148 149 static void 150 init_derived_interface (TestIfaceClass *iface) 151 { 152 iface->val = 42; 153 } 154 155 static void 156 add_derived_interface (GType object_type, 157 GType iface_type) 158 { 159 add_interface (object_type, iface_type, 160 (GInterfaceInitFunc)init_derived_interface); 161 } 162 163 static gboolean 164 interface_is_derived (GType object_type, 165 GType iface_type) 166 { 167 gpointer g_class = g_type_class_peek (object_type); 168 TestIfaceClass *iface = g_type_interface_peek (g_class, iface_type); 169 return iface && iface->val == 42; 170 } 171 172 static void 173 derived_object_class_init (BaseObjectClass *class) 174 { 175 add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE3); 176 } 177 178 static DEFINE_TYPE(BaseObject, base_object, 179 NULL, NULL, NULL, 180 G_TYPE_OBJECT) 181 static DEFINE_TYPE(DerivedObject, derived_object, 182 derived_object_class_init, NULL, NULL, 183 BASE_TYPE_OBJECT) 184 185 int 186 main (int argc, 187 char *argv[]) 188 { 189 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | 190 G_LOG_LEVEL_WARNING | 191 G_LOG_LEVEL_CRITICAL); 192 g_type_init (); 193 194 /* Register BaseObject */ 195 BASE_TYPE_OBJECT; 196 197 add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE5); 198 199 /* Class init BaseObject */ 200 g_type_class_ref (BASE_TYPE_OBJECT); 201 202 add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE1); 203 204 /* Register DerivedObject */ 205 DERIVED_TYPE_OBJECT; 206 207 add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE2); 208 add_derived_interface (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE5); 209 210 /* Class init DerivedObject */ 211 g_type_class_ref (DERIVED_TYPE_OBJECT); 212 213 add_base_interface (BASE_TYPE_OBJECT, TEST_TYPE_IFACE4); 214 215 /* Check that all the non-overridden interfaces were properly inherited 216 */ 217 g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE1)); 218 g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE2)); 219 g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE3)); 220 g_assert (interface_is_base (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE4)); 221 222 /* Check that all the overridden interfaces were properly overridden 223 */ 224 g_assert (interface_is_derived (DERIVED_TYPE_OBJECT, TEST_TYPE_IFACE5)); 225 226 return 0; 227 } 228