=== Released 2.2.0 ===
[platform/upstream/glib.git] / gobject / gtype.c
index f9d0edd..9742239 100644 (file)
@@ -16,6 +16,7 @@
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#include        <config.h>
 #include       "gtype.h"
 
 /*
@@ -1145,6 +1146,17 @@ type_iface_add_prerequisite_W (TypeNode *iface,
     type_iface_add_prerequisite_W (lookup_type_node_I (dependants[i]), prerequisite_node);
 }
 
+/**
+ * g_type_interface_add_prerequisite:
+ * @interface_type: #GType value of an interface type.
+ * @prerequisite_type: #GType value of an interface or instantiatable type.
+ * 
+ * Adds @prerequisite_type to the list of prerequisites of @interface_type.
+ * This means that any type implementing @interface_type must also implement
+ * @prerequisite_type. Prerequisites can be thought of as an alternative to
+ * interface derivation (which GType doesn't support). An interface can have
+ * at most one instantiatable prerequisite type.
+ **/
 void
 g_type_interface_add_prerequisite (GType interface_type,
                                   GType prerequisite_type)
@@ -1229,6 +1241,8 @@ g_type_interface_add_prerequisite (GType interface_type,
  * 
  * Return value: a newly-allocated zero-terminated array of #GType containing 
  * the prerequisites of @interface_type
+ *
+ * Since: 2.2
  **/
 GType* /* free result */
 g_type_interface_prerequisites (GType  interface_type,
@@ -1241,20 +1255,30 @@ g_type_interface_prerequisites (GType  interface_type,
   iface = lookup_type_node_I (interface_type);
   if (iface)
     {
-      GType *prerequisites;
-      guint i;
+      GType *types;
+      TypeNode *inode = NULL;
+      guint i, n = 0;
       
       G_READ_LOCK (&type_rw_lock);
-      prerequisites = g_new (GType, IFACE_NODE_N_PREREQUISITES (iface) + 1);
+      types = g_new0 (GType, IFACE_NODE_N_PREREQUISITES (iface) + 1);
       for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
-       prerequisites[i] = IFACE_NODE_PREREQUISITES (iface)[i];
-      prerequisites[i] = 0;
+       {
+         GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
+         TypeNode *node = lookup_type_node_I (prerequisite);
+         if (node->is_instantiatable &&
+             (!inode || type_node_is_a_L (node, inode)))
+           inode = node;
+         else
+           types[n++] = NODE_TYPE (node);
+       }
+      if (inode)
+       types[n++] = NODE_TYPE (inode);
       
       if (n_prerequisites)
-       *n_prerequisites = IFACE_NODE_N_PREREQUISITES (iface);
+       *n_prerequisites = n;
       G_READ_UNLOCK (&type_rw_lock);
       
-      return prerequisites;
+      return types;
     }
   else
     {
@@ -1600,34 +1624,33 @@ type_class_init_Wm (TypeNode   *node,
 static void
 type_data_finalize_class_ifaces_Wm (TypeNode *node)
 {
-  IFaceEntry *entry;
   guint i;
-  
+
   g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);
-  
+
   g_message ("finalizing interfaces for %sClass `%s'",
             type_descriptive_name_I (NODE_FUNDAMENTAL_TYPE (node)),
             type_descriptive_name_I (NODE_TYPE (node)));
-  
-  for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
-    if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&
-       CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable->g_instance_type == NODE_TYPE (node))
-      entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
-  while (entry)
+
+ reiterate:
+  for (i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
     {
-      if (!type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))
+      IFaceEntry *entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
+      if (entry->vtable)
        {
-         /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
-          * iface vtable came from parent
-          */
-         entry->vtable = NULL;
+          if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))
+            {
+              /* refetch entries, IFACES_ENTRIES might be modified */
+              goto reiterate;
+            }
+          else
+            {
+              /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
+               * iface vtable came from parent
+               */
+              entry->vtable = NULL;
+            }
        }
-      
-      /* refetch entry, IFACES_ENTRIES might be modified */
-      for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
-       if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&
-           CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable->g_instance_type == NODE_TYPE (node))
-         entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
     }
 }
 
@@ -1937,6 +1960,16 @@ g_type_add_interface_static (GType                 instance_type,
   G_WRITE_UNLOCK (&type_rw_lock);
 }
 
+/**
+ * g_type_add_interface_dynamic:
+ * @instance_type: the #GType value of an instantiable type.
+ * @interface_type: the #GType value of an interface type.
+ * @plugin: the #GTypePlugin structure to retrieve the #GInterfaceInfo from.
+ * 
+ * Adds the dynamic @interface_type to @instantiable_type. The information
+ * contained in the #GTypePlugin structure pointed to by @plugin
+ * is used to manage the relationship.
+ **/
 void
 g_type_add_interface_dynamic (GType        instance_type,
                              GType        interface_type,
@@ -2127,6 +2160,19 @@ g_type_interface_peek (gpointer instance_class,
   return vtable;
 }
 
+/**
+ * g_type_interface_peek_parent:
+ * @g_iface: A #GTypeInterface structure.
+ * 
+ * Returns the corresponding #GTypeInterface structure of the parent type
+ * of the instance type to which @g_iface belongs. This is useful when 
+ * deriving the implementation of an interface from the parent type and 
+ * then possibly overriding some methods. 
+ * 
+ * Return value: The corresponding #GTypeInterface structure of the parent type
+ * of the instance type to which @g_iface belongs, or %NULL if the parent type
+ * doesn't conform to the interface.
+ **/
 gpointer
 g_type_interface_peek_parent (gpointer g_iface)
 {
@@ -2415,6 +2461,16 @@ type_get_qdata_L (TypeNode *node,
   return NULL;
 }
 
+/**
+ * g_type_get_qdata:
+ * @type: a #GType
+ * @quark: a #GQuark id to identify the data
+ * 
+ * Obtains data which has previously been attached to @type
+ * with g_type_set_qdata().
+ * 
+ * Return value: the data, or %NULL if no data was found
+ **/
 gpointer
 g_type_get_qdata (GType  type,
                  GQuark quark)
@@ -2472,6 +2528,14 @@ type_set_qdata_W (TypeNode *node,
   qdata[i].data = data;
 }
 
+/**
+ * g_type_set_qdata:
+ * @type: a #GType 
+ * @quark: a #GQuark id to identify the data
+ * @data: the data
+ * 
+ * Attaches arbitrary data to a type.
+ **/
 void
 g_type_set_qdata (GType    type,
                  GQuark   quark,
@@ -2508,6 +2572,18 @@ type_add_flags_W (TypeNode  *node,
   type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags));
 }
 
+/**
+ * g_type_query:
+ * @type: the #GType value of a static, classed type.
+ * @query: A user provided structure that is filled in with constant values 
+ *         upon success.
+ * 
+ * Queries the type system for information about a specific type. 
+ * This function will fill in a user-provided structure to hold type-specific 
+ * information. If an invalid #GType is passed in, the @type member of the 
+ * #GTypeQuery is 0. All members filled into the #GTypeQuery structure should
+ * be considered constant and have to be left untouched.
+ **/
 void
 g_type_query (GType       type,
              GTypeQuery *query)
@@ -2583,6 +2659,19 @@ g_type_get_plugin (GType type)
   return node ? node->plugin : NULL;
 }
 
+/**
+ * g_type_interface_get_plugin:
+ * @instance_type: the #GType value of an instantiatable type.
+ * @interface_type: the #GType value of an interface type.
+ * 
+ * Returns the #GTypePlugin structure for the dynamic interface 
+ * @interface_type which has been added to @instance_type, or 
+ * %NULL if @interface_type has not been added to @instance_type or does 
+ * not have a #GTypePlugin structure. See g_type_add_interface_dynamic().
+ * 
+ * Return value: the #GTypePlugin for the dynamic interface @interface_type
+ * of @instance_type.
+ **/
 GTypePlugin*
 g_type_interface_get_plugin (GType instance_type,
                             GType interface_type)
@@ -2704,9 +2793,6 @@ g_type_check_instance_cast (GTypeInstance *type_instance,
        g_warning ("invalid unclassed pointer in cast to `%s'",
                   type_descriptive_name_I (iface_type));
     }
-  else
-    g_warning ("invalid cast from (NULL) pointer to `%s'",
-              type_descriptive_name_I (iface_type));
   
   return type_instance;
 }