Home | History | Annotate | Download | only in gobject
      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 "TestIfaceCheck"
     22 
     23 #undef G_DISABLE_ASSERT
     24 #undef G_DISABLE_CHECKS
     25 #undef G_DISABLE_CAST_CHECKS
     26 
     27 #include <string.h>
     28 
     29 #include <glib-object.h>
     30 
     31 #include "testcommon.h"
     32 
     33 /* This test tests g_type_add_interface_check_func(), which allows
     34  * installing a post-initialization check function.
     35  */
     36 
     37 #define TEST_TYPE_IFACE           (test_iface_get_type ())
     38 #define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass))
     39 typedef struct _TestIfaceClass  TestIfaceClass;
     40 
     41 struct _TestIfaceClass
     42 {
     43   GTypeInterface base_iface;
     44   GString *history;
     45 };
     46 
     47 static void
     48 test_iface_base_init (TestIfaceClass *iface)
     49 {
     50   iface->history = g_string_new (iface->history ? iface->history->str : NULL);
     51 }
     52 
     53 static DEFINE_IFACE(TestIface, test_iface, test_iface_base_init, NULL)
     54 
     55 /*
     56  * TestObject1
     57  */
     58 #define TEST_TYPE_OBJECT1         (test_object1_get_type ())
     59 typedef struct _GObject           TestObject1;
     60 typedef struct _GObjectClass      TestObject1Class;
     61 
     62 static DEFINE_TYPE_FULL (TestObject1, test_object1,
     63 			 NULL, NULL, NULL,
     64 			 G_TYPE_OBJECT,
     65 			 INTERFACE (NULL, TEST_TYPE_IFACE))
     66 
     67 /*
     68  * TestObject2
     69  */
     70 #define TEST_TYPE_OBJECT2         (test_object2_get_type ())
     71 typedef struct _GObject           TestObject2;
     72 typedef struct _GObjectClass      TestObject2Class;
     73 
     74 static DEFINE_TYPE_FULL (TestObject2, test_object2,
     75 			 NULL, NULL, NULL,
     76 			 G_TYPE_OBJECT,
     77 			 INTERFACE (NULL, TEST_TYPE_IFACE))
     78 
     79 /*
     80  * TestObject3
     81  */
     82 #define TEST_TYPE_OBJECT3         (test_object3_get_type ())
     83 typedef struct _GObject           TestObject3;
     84 typedef struct _GObjectClass      TestObject3Class;
     85 
     86 static DEFINE_TYPE_FULL (TestObject3, test_object3,
     87 			 NULL, NULL, NULL,
     88 			 G_TYPE_OBJECT,
     89 			 INTERFACE (NULL, TEST_TYPE_IFACE))
     90 
     91 /*
     92  * TestObject4
     93  */
     94 #define TEST_TYPE_OBJECT4         (test_object4_get_type ())
     95 typedef struct _GObject           TestObject4;
     96 typedef struct _GObjectClass      TestObject4Class;
     97 
     98 
     99 static DEFINE_TYPE_FULL (TestObject4, test_object4,
    100 			 NULL, NULL, NULL,
    101 			 G_TYPE_OBJECT, {})
    102 
    103 static void
    104 check_func (gpointer check_data,
    105 	    gpointer g_iface)
    106 {
    107   TestIfaceClass *iface = g_iface;
    108 
    109   g_string_append (iface->history, check_data);
    110 }
    111 
    112 int
    113 main (int   argc,
    114       char *argv[])
    115 {
    116   TestIfaceClass *iface;
    117   GObject *object;
    118   char *string1 = "A";
    119   char *string2 = "B";
    120 
    121   g_type_init ();
    122 
    123   /* Basic check of interfaces added before class_init time
    124    */
    125   g_type_add_interface_check (string1, check_func);
    126 
    127   object = g_object_new (TEST_TYPE_OBJECT1, NULL);
    128   iface = TEST_IFACE_GET_CLASS (object);
    129     g_assert (strcmp (iface->history->str, "A") == 0);
    130   g_object_unref (object);
    131 
    132   /* Add a second check function
    133    */
    134   g_type_add_interface_check (string2, check_func);
    135 
    136   object = g_object_new (TEST_TYPE_OBJECT2, NULL);
    137   iface = TEST_IFACE_GET_CLASS (object);
    138   g_assert (strcmp (iface->history->str, "AB") == 0);
    139   g_object_unref (object);
    140 
    141   /* Remove the first check function
    142    */
    143   g_type_remove_interface_check (string1, check_func);
    144 
    145   object = g_object_new (TEST_TYPE_OBJECT3, NULL);
    146   iface = TEST_IFACE_GET_CLASS (object);
    147   g_assert (strcmp (iface->history->str, "B") == 0);
    148   g_object_unref (object);
    149 
    150   /* Test interfaces added after class_init time
    151    */
    152   g_type_class_ref (TEST_TYPE_OBJECT4);
    153   {
    154     static GInterfaceInfo const iface = {
    155       NULL, NULL, NULL
    156     };
    157 
    158     g_type_add_interface_static (TEST_TYPE_OBJECT4, TEST_TYPE_IFACE, &iface);
    159   }
    160 
    161   object = g_object_new (TEST_TYPE_OBJECT4, NULL);
    162   iface = TEST_IFACE_GET_CLASS (object);
    163   g_assert (strcmp (iface->history->str, "B") == 0);
    164   g_object_unref (object);
    165 
    166   return 0;
    167 }
    168