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