Home | History | Annotate | Download | only in gobject
      1 /* GObject - GLib Type, Object, Parameter and Signal Library
      2  * Copyright (C) 2000 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 #include "config.h"
     21 
     22 #include "gtypeplugin.h"
     23 #include "gobjectalias.h"
     24 
     25 
     26 /**
     27  * SECTION:gtypeplugin
     28  * @short_description: An interface for dynamically loadable types
     29  * @see_also: #GTypeModule and g_type_register_dynamic().
     30  * @title: GTypePlugin
     31  *
     32  * The GObject type system supports dynamic loading of types. The
     33  * #GTypePlugin interface is used to handle the lifecycle of
     34  * dynamically loaded types.  It goes as follows:
     35  *
     36  * <orderedlist>
     37  * <listitem><para>
     38  *   The type is initially introduced (usually upon loading the module
     39  *   the first time, or by your main application that knows what modules
     40  *   introduces what types), like this:
     41  *   |[
     42  *   new_type_id = g_type_register_dynamic (parent_type_id,
     43  *                                                 "TypeName",
     44  *                                                 new_type_plugin,
     45  *                                                 type_flags);
     46  *   ]|
     47  *   where <literal>new_type_plugin</literal> is an implementation of the
     48  *   #GTypePlugin interface.
     49  * </para></listitem>
     50  * <listitem><para>
     51  *    The type's implementation is referenced, e.g. through
     52  *    g_type_class_ref() or through g_type_create_instance() (this is
     53  *    being called by g_object_new()) or through one of the above done on
     54  *    a type derived from <literal>new_type_id</literal>.
     55  * </para></listitem>
     56  * <listitem><para>
     57  *    This causes the type system to load the type's implementation by calling
     58  *    g_type_plugin_use() and g_type_plugin_complete_type_info() on
     59  *    <literal>new_type_plugin</literal>.
     60  * </para></listitem>
     61  * <listitem><para>
     62  *    At some point the type's implementation isn't required anymore, e.g. after
     63  *    g_type_class_unref() or g_type_free_instance() (called when the reference
     64  *    count of an instance drops to zero).
     65  * </para></listitem>
     66  * <listitem><para>
     67  *    This causes the type system to throw away the information retrieved from
     68  *    g_type_plugin_complete_type_info() and then it calls
     69  *    g_type_plugin_unuse() on <literal>new_type_plugin</literal>.
     70  * </para></listitem>
     71  * <listitem><para>
     72  *    Things may repeat from the second step.
     73  * </para></listitem>
     74  * </orderedlist>
     75  *
     76  * So basically, you need to implement a #GTypePlugin type that
     77  * carries a use_count, once use_count goes from zero to one, you need
     78  * to load the implementation to successfully handle the upcoming
     79  * g_type_plugin_complete_type_info() call. Later, maybe after
     80  * succeeding use/unuse calls, once use_count drops to zero, you can
     81  * unload the implementation again. The type system makes sure to call
     82  * g_type_plugin_use() and g_type_plugin_complete_type_info() again
     83  * when the type is needed again.
     84  *
     85  * #GTypeModule is an implementation of #GTypePlugin that already
     86  * implements most of this except for the actual module loading and
     87  * unloading. It even handles multiple registered types per module.
     88  */
     89 
     90 
     91 /* --- functions --- */
     92 GType
     93 g_type_plugin_get_type (void)
     94 {
     95   static GType type_plugin_type = 0;
     96 
     97   if (!type_plugin_type)
     98     {
     99       static const GTypeInfo type_plugin_info = {
    100 	sizeof (GTypePluginClass),
    101 	NULL,           /* base_init */
    102 	NULL,           /* base_finalize */
    103       };
    104 
    105       type_plugin_type = g_type_register_static (G_TYPE_INTERFACE, g_intern_static_string ("GTypePlugin"), &type_plugin_info, 0);
    106     }
    107 
    108   return type_plugin_type;
    109 }
    110 
    111 /**
    112  * g_type_plugin_use:
    113  * @plugin: a #GTypePlugin
    114  *
    115  * Calls the @use_plugin function from the #GTypePluginClass of
    116  * @plugin.  There should be no need to use this function outside of
    117  * the GObject type system itself.
    118  */
    119 void
    120 g_type_plugin_use (GTypePlugin *plugin)
    121 {
    122   GTypePluginClass *iface;
    123 
    124   g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
    125 
    126   iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
    127   iface->use_plugin (plugin);
    128 }
    129 
    130 /**
    131  * g_type_plugin_unuse:
    132  * @plugin: a #GTypePlugin
    133  *
    134  * Calls the @unuse_plugin function from the #GTypePluginClass of
    135  * @plugin.  There should be no need to use this function outside of
    136  * the GObject type system itself.
    137  */
    138 void
    139 g_type_plugin_unuse (GTypePlugin *plugin)
    140 {
    141   GTypePluginClass *iface;
    142 
    143   g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
    144 
    145   iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
    146   iface->unuse_plugin (plugin);
    147 }
    148 
    149 /**
    150  * g_type_plugin_complete_type_info:
    151  * @plugin: a #GTypePlugin
    152  * @g_type: the #GType whose info is completed
    153  * @info: the #GTypeInfo struct to fill in
    154  * @value_table: the #GTypeValueTable to fill in
    155  *
    156  * Calls the @complete_type_info function from the #GTypePluginClass of @plugin.
    157  * There should be no need to use this function outside of the GObject
    158  * type system itself.
    159  */
    160 void
    161 g_type_plugin_complete_type_info (GTypePlugin     *plugin,
    162 				  GType            g_type,
    163 				  GTypeInfo       *info,
    164 				  GTypeValueTable *value_table)
    165 {
    166   GTypePluginClass *iface;
    167 
    168   g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
    169   g_return_if_fail (info != NULL);
    170   g_return_if_fail (value_table != NULL);
    171 
    172   iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
    173   iface->complete_type_info (plugin,
    174 			     g_type,
    175 			     info,
    176 			     value_table);
    177 }
    178 
    179 /**
    180  * g_type_plugin_complete_interface_info:
    181  * @plugin: the #GTypePlugin
    182  * @instance_type: the #GType of an instantiable type to which the interface
    183  *  is added
    184  * @interface_type: the #GType of the interface whose info is completed
    185  * @info: the #GInterfaceInfo to fill in
    186  *
    187  * Calls the @complete_interface_info function from the
    188  * #GTypePluginClass of @plugin. There should be no need to use this
    189  * function outside of the GObject type system itself.
    190  */
    191 void
    192 g_type_plugin_complete_interface_info (GTypePlugin    *plugin,
    193 				       GType           instance_type,
    194 				       GType           interface_type,
    195 				       GInterfaceInfo *info)
    196 {
    197   GTypePluginClass *iface;
    198 
    199   g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
    200   g_return_if_fail (info != NULL);
    201 
    202   iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
    203   iface->complete_interface_info (plugin,
    204 				  instance_type,
    205 				  interface_type,
    206 				  info);
    207 }
    208 
    209 #define __G_TYPE_PLUGIN_C__
    210 #include "gobjectaliasdef.c"
    211