Migrating docs.
[platform/upstream/glib.git] / gobject / gtypemodule.c
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 Public
15  * 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  * SECTION:gtypemodule
21  * @Short_description: Type loading modules
22  * @See_also:<variablelist>
23  * <varlistentry>
24  * <term>#GTypePlugin</term>
25  * <listitem><para>The abstract type loader interface.</para></listitem>
26  * </varlistentry>
27  * <varlistentry>
28  * <term>#GModule</term>
29  * <listitem><para>Portable mechanism for dynamically loaded modules.</para></listitem>
30  * </varlistentry>
31  * </variablelist>
32  * @Title: GTypeModule
33  * 
34  * #GTypeModule provides a simple implementation of the #GTypePlugin
35  * interface. The model of #GTypeModule is a dynamically loaded module
36  * which implements some number of types and interface
37  * implementations. When the module is loaded, it registers its types
38  * and interfaces using g_type_module_register_type() and
39  * g_type_module_add_interface().  As long as any instances of these
40  * types and interface implementations are in use, the module is kept
41  * loaded. When the types and interfaces are gone, the module may be
42  * unloaded. If the types and interfaces become used again, the module
43  * will be reloaded. Note that the last unref can not happen in module
44  * code, since that would lead to the caller's code being unloaded before
45  * g_object_unref() returns to it.
46  * 
47  * Keeping track of whether the module should be loaded or not is done by
48  * using a use count - it starts at zero, and whenever it is greater than
49  * zero, the module is loaded. The use count is maintained internally by
50  * the type system, but also can be explicitly controlled by
51  * g_type_module_use() and g_type_module_unuse(). Typically, when loading
52  * a module for the first type, g_type_module_use() will be used to load
53  * it so that it can initialize its types. At some later point, when the
54  * module no longer needs to be loaded except for the type
55  * implementations it contains, g_type_module_unuse() is called.
56  * 
57  * #GTypeModule does not actually provide any implementation of module
58  * loading and unloading. To create a particular module type you must
59  * derive from #GTypeModule and implement the load and unload functions
60  * in #GTypeModuleClass.
61  */
62
63 #include <stdlib.h>
64
65 #include "gtypeplugin.h"
66 #include "gtypemodule.h"
67 #include "gobjectalias.h"
68
69 typedef struct _ModuleTypeInfo ModuleTypeInfo;
70 typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo;
71
72 struct _ModuleTypeInfo 
73 {
74   gboolean  loaded;
75   GType     type;
76   GType     parent_type;
77   GTypeInfo info;
78 };
79
80 struct _ModuleInterfaceInfo 
81 {
82   gboolean       loaded;
83   GType          instance_type;
84   GType          interface_type;
85   GInterfaceInfo info;
86 };
87
88 static void g_type_module_use_plugin              (GTypePlugin     *plugin);
89 static void g_type_module_complete_type_info      (GTypePlugin     *plugin,
90                                                    GType            g_type,
91                                                    GTypeInfo       *info,
92                                                    GTypeValueTable *value_table);
93 static void g_type_module_complete_interface_info (GTypePlugin     *plugin,
94                                                    GType            instance_type,
95                                                    GType            interface_type,
96                                                    GInterfaceInfo  *info);
97  
98 static gpointer parent_class = NULL;
99
100 static void
101 g_type_module_dispose (GObject *object)
102 {
103   GTypeModule *module = G_TYPE_MODULE (object);
104   
105   if (module->type_infos || module->interface_infos)
106     {
107       g_warning (G_STRLOC ": unsolicitated invocation of g_object_dispose() on GTypeModule");
108              
109       g_object_ref (object);
110     }
111
112   G_OBJECT_CLASS (parent_class)->dispose (object);
113 }
114
115 static void
116 g_type_module_finalize (GObject *object)
117 {
118   GTypeModule *module = G_TYPE_MODULE (object);
119
120   g_free (module->name);
121
122   G_OBJECT_CLASS (parent_class)->finalize (object);
123 }
124
125 static void
126 g_type_module_class_init (GTypeModuleClass *class)
127 {
128   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
129
130   parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
131   
132   gobject_class->dispose = g_type_module_dispose;
133   gobject_class->finalize = g_type_module_finalize;
134 }
135
136 static void
137 g_type_module_iface_init (GTypePluginClass *iface)
138 {
139   iface->use_plugin = g_type_module_use_plugin;
140   iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse;
141   iface->complete_type_info = g_type_module_complete_type_info;
142   iface->complete_interface_info = g_type_module_complete_interface_info;
143 }
144
145 GType
146 g_type_module_get_type (void)
147 {
148   static GType type_module_type = 0;
149
150   if (!type_module_type)
151     {
152       static const GTypeInfo type_module_info = {
153         sizeof (GTypeModuleClass),
154         NULL,           /* base_init */
155         NULL,           /* base_finalize */
156         (GClassInitFunc) g_type_module_class_init,
157         NULL,           /* class_finalize */
158         NULL,           /* class_data */
159         sizeof (GTypeModule),
160         0,              /* n_preallocs */
161         NULL,           /* instance_init */
162       };
163       static const GInterfaceInfo iface_info = {
164         (GInterfaceInitFunc) g_type_module_iface_init,
165         NULL,               /* interface_finalize */
166         NULL,               /* interface_data */
167       };
168
169       type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT);
170
171       g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
172     }
173   
174   return type_module_type;
175 }
176
177 /**
178  * g_type_module_set_name:
179  * @module: a #GTypeModule.
180  * @name: a human-readable name to use in error messages.
181  * 
182  * Sets the name for a #GTypeModule 
183  */
184 void
185 g_type_module_set_name (GTypeModule  *module,
186                         const gchar  *name)
187 {
188   g_return_if_fail (G_IS_TYPE_MODULE (module));
189
190   g_free (module->name);
191   module->name = g_strdup (name);
192 }
193
194 static ModuleTypeInfo *
195 g_type_module_find_type_info (GTypeModule *module,
196                               GType        type)
197 {
198   GSList *tmp_list = module->type_infos;
199   while (tmp_list)
200     {
201       ModuleTypeInfo *type_info = tmp_list->data;
202       if (type_info->type == type)
203         return type_info;
204       
205       tmp_list = tmp_list->next;
206     }
207
208   return NULL;
209 }
210
211 static ModuleInterfaceInfo *
212 g_type_module_find_interface_info (GTypeModule *module,
213                                    GType        instance_type,
214                                    GType        interface_type)
215 {
216   GSList *tmp_list = module->interface_infos;
217   while (tmp_list)
218     {
219       ModuleInterfaceInfo *interface_info = tmp_list->data;
220       if (interface_info->instance_type == instance_type &&
221           interface_info->interface_type == interface_type)
222         return interface_info;
223       
224       tmp_list = tmp_list->next;
225     }
226
227   return NULL;
228 }
229
230 /**
231  * g_type_module_use:
232  * @module: a #GTypeModule
233  * 
234  * Increases the use count of a #GTypeModule by one. If the
235  * use count was zero before, the plugin will be loaded.
236  * 
237  * Returns: %FALSE if the plugin needed to be loaded and
238  *  loading the plugin failed.
239  */
240 gboolean
241 g_type_module_use (GTypeModule *module)
242 {
243   g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
244
245   module->use_count++;
246   if (module->use_count == 1)
247     {
248       GSList *tmp_list;
249       
250       if (!G_TYPE_MODULE_GET_CLASS (module)->load (module))
251         {
252           module->use_count--;
253           return FALSE;
254         }
255
256       tmp_list = module->type_infos;
257       while (tmp_list)
258         {
259           ModuleTypeInfo *type_info = tmp_list->data;
260           if (!type_info->loaded)
261             {
262               g_warning ("plugin '%s' failed to register type '%s'\n",
263                          module->name ? module->name : "(unknown)",
264                          g_type_name (type_info->type));
265               return FALSE;
266             }
267           
268           tmp_list = tmp_list->next;
269         }
270     }
271  
272   return TRUE;
273 }
274
275 /**
276  * g_type_module_unuse:
277  * @module: a #GTypeModule
278  * 
279  * Decreases the use count of a #GTypeModule by one. If the
280  * result is zero, the module will be unloaded. (However, the
281  * #GTypeModule will not be freed, and types associated with the
282  * #GTypeModule are not unregistered. Once a #GTypeModule is 
283  * initialized, it must exist forever.)
284  */
285 void
286 g_type_module_unuse (GTypeModule *module)
287 {
288   g_return_if_fail (G_IS_TYPE_MODULE (module));
289   g_return_if_fail (module->use_count > 0);
290
291   module->use_count--;
292
293   if (module->use_count == 0)
294     {
295       GSList *tmp_list;
296
297       G_TYPE_MODULE_GET_CLASS (module)->unload (module);
298
299       tmp_list = module->type_infos;
300       while (tmp_list)
301         {
302           ModuleTypeInfo *type_info = tmp_list->data;
303           type_info->loaded = FALSE;
304
305           tmp_list = tmp_list->next;
306         }
307     }
308 }
309         
310 static void
311 g_type_module_use_plugin (GTypePlugin *plugin)
312 {
313   GTypeModule *module = G_TYPE_MODULE (plugin);
314
315   if (!g_type_module_use (module))
316     {
317       g_warning ("Fatal error - Could not reload previously loaded plugin '%s'\n",
318                  module->name ? module->name : "(unknown)");
319       exit (1);
320     }
321 }
322
323 static void
324 g_type_module_complete_type_info (GTypePlugin     *plugin,
325                                   GType            g_type,
326                                   GTypeInfo       *info,
327                                   GTypeValueTable *value_table)
328 {
329   GTypeModule *module = G_TYPE_MODULE (plugin);
330   ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type);
331
332   *info = module_type_info->info;
333   
334   if (module_type_info->info.value_table)
335     *value_table = *module_type_info->info.value_table;
336 }
337
338 static void 
339 g_type_module_complete_interface_info (GTypePlugin    *plugin,
340                                        GType           instance_type,
341                                        GType           interface_type,
342                                        GInterfaceInfo *info)
343 {
344   GTypeModule *module = G_TYPE_MODULE (plugin);
345   ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
346
347   *info = module_interface_info->info;
348 }
349
350 /**
351  * g_type_module_register_type:
352  * @module: a #GTypeModule
353  * @parent_type: the type for the parent class
354  * @type_name: name for the type
355  * @type_info: type information structure
356  * @flags: flags field providing details about the type
357  * 
358  * Looks up or registers a type that is implemented with a particular
359  * type plugin. If a type with name @type_name was previously registered,
360  * the #GType identifier for the type is returned, otherwise the type
361  * is newly registered, and the resulting #GType identifier returned.
362  * 
363  * When reregistering a type (typically because a module is unloaded
364  * then reloaded, and reinitialized), @module and @parent_type must
365  * be the same as they were previously.
366  * 
367  * As long as any instances of the type exist, the type plugin will
368  * not be unloaded.
369  * 
370  * Returns: the new or existing type ID
371  */
372 GType
373 g_type_module_register_type (GTypeModule     *module,
374                              GType            parent_type,
375                              const gchar     *type_name,
376                              const GTypeInfo *type_info,
377                              GTypeFlags       flags)
378 {
379   ModuleTypeInfo *module_type_info = NULL;
380   GType type;
381   
382   g_return_val_if_fail (module != NULL, 0);
383   g_return_val_if_fail (type_name != NULL, 0);
384   g_return_val_if_fail (type_info != NULL, 0);
385
386   type = g_type_from_name (type_name);
387   if (type)
388     {
389       GTypePlugin *old_plugin = g_type_get_plugin (type);
390
391       if (old_plugin != G_TYPE_PLUGIN (module))
392         {
393           g_warning ("Two different plugins tried to register '%s'.", type_name);
394           return 0;
395         }
396     }
397
398   if (type)
399     {
400       module_type_info = g_type_module_find_type_info (module, type);
401
402       if (module_type_info->parent_type != parent_type)
403         {
404           const gchar *parent_type_name = g_type_name (parent_type);
405           
406           g_warning ("Type '%s' recreated with different parent type.\n"
407                      "(was '%s', now '%s')", type_name,
408                      g_type_name (module_type_info->parent_type),
409                      parent_type_name ? parent_type_name : "(unknown)");
410           return 0;
411         }
412
413       if (module_type_info->info.value_table)
414         g_free ((GTypeValueTable *) module_type_info->info.value_table);
415     }
416   else
417     {
418       module_type_info = g_new (ModuleTypeInfo, 1);
419       
420       module_type_info->parent_type = parent_type;
421       module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags);
422       
423       module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
424     }
425
426   module_type_info->loaded = TRUE;
427   module_type_info->info = *type_info;
428   if (type_info->value_table)
429     module_type_info->info.value_table = g_memdup (type_info->value_table,
430                                                    sizeof (GTypeValueTable));
431
432   return module_type_info->type;
433 }
434
435 /**
436  * g_type_module_add_interface:
437  * @module: a #GTypeModule
438  * @instance_type: type to which to add the interface.
439  * @interface_type: interface type to add
440  * @interface_info: type information structure
441  * 
442  * Registers an additional interface for a type, whose interface
443  * lives in the given type plugin. If the interface was already registered
444  * for the type in this plugin, nothing will be done. 
445  * 
446  * As long as any instances of the type exist, the type plugin will
447  * not be unloaded.
448  */
449 void
450 g_type_module_add_interface (GTypeModule          *module,
451                              GType                 instance_type,
452                              GType                 interface_type,
453                              const GInterfaceInfo *interface_info)
454 {
455   ModuleInterfaceInfo *module_interface_info = NULL;
456   
457   g_return_if_fail (module != NULL);
458   g_return_if_fail (interface_info != NULL);
459
460   if (g_type_is_a (instance_type, interface_type))
461     {
462       GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
463                                                              interface_type);
464
465       if (!old_plugin)
466         {
467           g_warning ("Interface '%s' for '%s' was previously registered statically or for a parent type.",
468                      g_type_name (interface_type), g_type_name (instance_type));
469           return;
470         }
471       else if (old_plugin != G_TYPE_PLUGIN (module))
472         {
473           g_warning ("Two different plugins tried to register interface '%s' for '%s'.",
474                      g_type_name (interface_type), g_type_name (instance_type));
475           return;
476         }
477       
478       module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
479
480       g_assert (module_interface_info);
481     }
482   else
483     {
484       module_interface_info = g_new (ModuleInterfaceInfo, 1);
485       
486       module_interface_info->instance_type = instance_type;
487       module_interface_info->interface_type = interface_type;
488       
489       g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module));
490       
491       module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info);
492     }
493   
494   module_interface_info->loaded = TRUE;
495   module_interface_info->info = *interface_info;
496 }
497
498 /**
499  * g_type_module_register_enum:
500  * @module: a #GTypeModule
501  * @name: name for the type
502  * @const_static_values: an array of #GEnumValue structs for the possible
503  *  enumeration values. The array is terminated by a struct with all 
504  *  members being 0.
505  * 
506  * Looks up or registers an enumeration that is implemented with a particular
507  * type plugin. If a type with name @type_name was previously registered,
508  * the #GType identifier for the type is returned, otherwise the type
509  * is newly registered, and the resulting #GType identifier returned.
510  * 
511  * As long as any instances of the type exist, the type plugin will
512  * not be unloaded.
513  * 
514  * Since: 2.6
515  * Returns: the new or existing type ID
516  */
517 GType
518 g_type_module_register_enum (GTypeModule      *module,
519                              const gchar      *name,
520                              const GEnumValue *const_static_values)
521 {
522   GTypeInfo enum_type_info = { 0, };
523
524   g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0);
525   g_return_val_if_fail (name != NULL, 0);
526   g_return_val_if_fail (const_static_values != NULL, 0);
527
528   g_enum_complete_type_info (G_TYPE_ENUM,
529                              &enum_type_info, const_static_values);
530
531   return g_type_module_register_type (G_TYPE_MODULE (module),
532                                       G_TYPE_ENUM, name, &enum_type_info, 0);
533 }
534
535 /**
536  * g_type_module_register_flags:
537  * @module: a #GTypeModule
538  * @name: name for the type
539  * @const_static_values: an array of #GFlagsValue structs for the possible
540  *  flags values. The array is terminated by a struct with all 
541  *  members being 0.
542  * 
543  * Looks up or registers a flags type that is implemented with a particular
544  * type plugin. If a type with name @type_name was previously registered,
545  * the #GType identifier for the type is returned, otherwise the type
546  * is newly registered, and the resulting #GType identifier returned.
547  * 
548  * As long as any instances of the type exist, the type plugin will
549  * not be unloaded.
550  * 
551  * Since: 2.6
552  * Returns: the new or existing type ID
553  */
554 GType
555 g_type_module_register_flags (GTypeModule      *module,
556                              const gchar       *name,
557                              const GFlagsValue *const_static_values)
558 {
559   GTypeInfo flags_type_info = { 0, };
560
561   g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0);
562   g_return_val_if_fail (name != NULL, 0);
563   g_return_val_if_fail (const_static_values != NULL, 0);
564
565   g_flags_complete_type_info (G_TYPE_FLAGS,
566                              &flags_type_info, const_static_values);
567
568   return g_type_module_register_type (G_TYPE_MODULE (module),
569                                       G_TYPE_FLAGS, name, &flags_type_info, 0);
570 }
571
572
573 #define __G_TYPE_MODULE_C__
574 #include "gobjectaliasdef.c"