Add g_type_add/remove_interface_check(), which allows inserting a
authorOwen Taylor <otaylor@redhat.com>
Thu, 2 Oct 2003 05:24:21 +0000 (05:24 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 2 Oct 2003 05:24:21 +0000 (05:24 +0000)
Thu Oct  2 01:16:50 2003  Owen Taylor  <otaylor@redhat.com>

        * gtype.[ch]: Add g_type_add/remove_interface_check(),
        which allows inserting a post-interface-initialization
        check.

        * testgobject.c: Fix a deprecated usage.

gobject/ChangeLog
gobject/gtype.c
gobject/gtype.h
gobject/testgobject.c

index 2b56336846488243cd7dbb0db53d6f73b36a6943..74d62b400a9de9b8e18ffb3f528afc9fbbd2ec7b 100644 (file)
@@ -1,3 +1,11 @@
+Thu Oct  2 01:16:50 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtype.[ch]: Add g_type_add/remove_interface_check(),
+       which allows inserting a post-interface-initialization
+       check.
+
+       * testgobject.c: Fix a deprecated usage.
+
 Mon Sep 29 10:51:01 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gtype.[ch]: Add g_type_default_interface_ref/peek/unref
index 0ffdb6e554594abed75b583d51c8391c3705151e..41d81c41b9f923e0093687aa837cf74e22418217 100644 (file)
@@ -286,11 +286,17 @@ typedef struct {
   gpointer            cache_data;
   GTypeClassCacheFunc cache_func;
 } ClassCacheFunc;
+typedef struct {
+  gpointer                check_data;
+  GTypeInterfaceCheckFunc check_func;
+} IFaceCheckFunc;
 
 
 /* --- variables --- */
 static guint           static_n_class_cache_funcs = 0;
 static ClassCacheFunc *static_class_cache_funcs = NULL;
+static guint           static_n_iface_check_funcs = 0;
+static IFaceCheckFunc *static_iface_check_funcs = NULL;
 static GQuark          static_quark_type_flags = 0;
 static GQuark          static_quark_iface_holder = 0;
 static GQuark          static_quark_dependants_array = 0;
@@ -1642,6 +1648,8 @@ type_iface_vtable_base_init_Wm (TypeNode *iface,
 
   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
   
+  entry->init_state = IFACE_INIT;
+
   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
   if (pnode)   /* want to copy over parent iface contents */
     {
@@ -1673,16 +1681,15 @@ type_iface_vtable_iface_init_Wm (TypeNode *iface,
                                 TypeNode *node)
 {
   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
-  IFaceHolder *iholder;
+  IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
   GTypeInterface *vtable = NULL;
+  guint i;
   
-  iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node));
-  if (!iholder)
-    return;
-
   /* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */
-  g_assert (iface->data && entry && iholder->info);
+  g_assert (iface->data && entry && iholder && iholder->info);
   
+  entry->init_state = INITIALIZED;
+      
   vtable = entry->vtable;
 
   if (iholder->info->interface_init)
@@ -1692,6 +1699,16 @@ type_iface_vtable_iface_init_Wm (TypeNode *iface,
        iholder->info->interface_init (vtable, iholder->info->interface_data);
       G_WRITE_LOCK (&type_rw_lock);
     }
+  
+  for (i = 0; i < static_n_iface_check_funcs; i++)
+    {
+      GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func;
+      gpointer check_data = static_iface_check_funcs[i].check_data;
+
+      G_WRITE_UNLOCK (&type_rw_lock);
+      check_func (check_data, (gpointer)vtable);
+      G_WRITE_LOCK (&type_rw_lock);      
+    }
 }
 
 static gboolean
@@ -1804,8 +1821,6 @@ type_class_init_Wm (TypeNode   *node,
       if (i == CLASSED_NODE_N_IFACES (node))
        break;
 
-      entry->init_state = IFACE_INIT;
-      
       if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node))
        {
          guint j;
@@ -1865,8 +1880,6 @@ type_class_init_Wm (TypeNode   *node,
       if (i == CLASSED_NODE_N_IFACES (node))
        break;
 
-      entry->init_state = INITIALIZED;
-      
       type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node);
       
       /* As in the loop above, additional initialized entries might be inserted
@@ -1891,29 +1904,12 @@ type_iface_vtable_init_Wm (TypeNode *node,
 {
   InitState class_state =
     node->data ? node->data->class.init_state : UNINITIALIZED;
-  InitState new_state = UNINITIALIZED;
   
   if (class_state >= BASE_IFACE_INIT)
-    {
-      type_iface_vtable_base_init_Wm (iface, node);
-      new_state = IFACE_INIT;
-    }
-
-  if (class_state >= IFACE_INIT)
-    {
-      type_iface_vtable_iface_init_Wm (iface, node);
-      new_state = INITIALIZED;
-    }
+    type_iface_vtable_base_init_Wm (iface, node);
   
-  if (class_state != UNINITIALIZED && class_state != INITIALIZED)
-    {
-      /* The interface was added while we were initializing the class
-       */
-      IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
-      g_assert (entry);
-      
-      entry->init_state = new_state;
-    }
+  if (class_state >= IFACE_INIT)
+    type_iface_vtable_iface_init_Wm (iface, node);
 }
 
 static void
@@ -2114,6 +2110,51 @@ g_type_remove_class_cache_func (gpointer            cache_data,
 }
 
 
+void
+g_type_add_interface_check (gpointer               check_data,
+                           GTypeInterfaceCheckFunc check_func)
+{
+  guint i;
+  
+  g_return_if_fail (check_func != NULL);
+  
+  G_WRITE_LOCK (&type_rw_lock);
+  i = static_n_iface_check_funcs++;
+  static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
+  static_iface_check_funcs[i].check_data = check_data;
+  static_iface_check_funcs[i].check_func = check_func;
+  G_WRITE_UNLOCK (&type_rw_lock);
+}
+
+void
+g_type_remove_interface_check (gpointer                check_data,
+                              GTypeInterfaceCheckFunc check_func)
+{
+  gboolean found_it = FALSE;
+  guint i;
+  
+  g_return_if_fail (check_func != NULL);
+  
+  G_WRITE_LOCK (&type_rw_lock);
+  for (i = 0; i < static_n_iface_check_funcs; i++)
+    if (static_iface_check_funcs[i].check_data == check_data &&
+       static_iface_check_funcs[i].check_func == check_func)
+      {
+       static_n_iface_check_funcs--;
+       g_memmove (static_iface_check_funcs + i,
+                  static_iface_check_funcs + i + 1,
+                  sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i));
+       static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs);
+       found_it = TRUE;
+       break;
+      }
+  G_WRITE_UNLOCK (&type_rw_lock);
+  
+  if (!found_it)
+    g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p",
+              check_func, check_data);
+}
+
 /* --- type registration --- */
 GType
 g_type_register_fundamental (GType                       type_id,
index 68f52128baf0e0e66f7f08ce0f30651f098a5866..66a7872bf51a2169f8d7884c161018527dd5bb1d 100644 (file)
@@ -218,6 +218,8 @@ typedef void   (*GInterfaceFinalizeFunc)     (gpointer         g_iface,
                                              gpointer         iface_data);
 typedef gboolean (*GTypeClassCacheFunc)             (gpointer         cache_data,
                                              GTypeClass      *g_class);
+typedef void     (*GTypeInterfaceCheckFunc)  (gpointer        func_data,
+                                             gpointer         g_iface);
 typedef enum    /*< skip >*/
 {
   G_TYPE_FLAG_CLASSED           = (1 << 0),
@@ -317,11 +319,18 @@ GType              g_type_fundamental_next        (void);
 GType           g_type_fundamental             (GType               type_id);
 GTypeInstance*   g_type_create_instance         (GType               type);
 void             g_type_free_instance           (GTypeInstance      *instance);
+
 void            g_type_add_class_cache_func    (gpointer            cache_data,
                                                 GTypeClassCacheFunc cache_func);
 void            g_type_remove_class_cache_func (gpointer            cache_data,
                                                 GTypeClassCacheFunc cache_func);
 void             g_type_class_unref_uncached    (gpointer            g_class);
+
+void             g_type_add_interface_check     (gpointer               check_data,
+                                                GTypeInterfaceCheckFunc check_func);
+void             g_type_remove_interface_check  (gpointer               check_data,
+                                                GTypeInterfaceCheckFunc chec_func);
+
 GTypeValueTable* g_type_value_table_peek        (GType              type);
 
 
index 6f7832a40f4b90a5da83cf697cae309797b6703f..16c4cc15abb0116a84dd95ede12968fcfb73b478 100644 (file)
@@ -242,7 +242,7 @@ test_signal_accumulator (GSignalInvocationHint *ihint,
   else
     result_string = NULL;
 
-  g_value_set_string_take_ownership (return_accu, result_string);
+  g_value_take_string (return_accu, result_string);
 
   return TRUE;
 }