summaryrefslogtreecommitdiff
path: root/docs/reference/gobject/tmpl/gtypeplugin.sgml
blob: 07b535f7e3d47525cc54423759e5c6abeabd3b7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<!-- ##### SECTION Title ##### -->
GTypePlugin

<!-- ##### SECTION Short_Description ##### -->
An interface for dynamically loadable types

<!-- ##### SECTION Long_Description ##### -->
<para>
The GObject type system supports dynamic loading of types. The #GTypePlugin 
interface is used to handle the lifecycle of dynamically loaded types. 
It goes as follows:
</para>
<para>
<orderedlist>
<listitem><para>
  The type is initially introduced (usually upon loading the module
  the first time, or by your main application that knows what modules
  introduces what types), like this:
<literal>new_type_id = g_type_register_dynamic (parent_type_id,
                                                "TypeName",
                                                new_type_plugin,
                                                type_flags);
</literal>
  where <literal>new_type_plugin</literal> is an implementation of the
  #GTypePlugin interface.
</para></listitem>
<listitem><para>  
   The type's implementation is referenced, e.g. through
   g_type_class_ref() or through g_type_create_instance() (this is 
   being called by g_object_new()) or through one of the above done on 
   a type derived from <literal>new_type_id</literal>.
</para></listitem>
<listitem><para>  
   This causes the type system to load the type's implementation by calling
   g_type_plugin_use() and g_type_plugin_complete_type_info() on 
   <literal>new_type_plugin</literal>.
</para></listitem>
<listitem><para>  
   At some point the type's implementation isn't required anymore, e.g. after
   g_type_class_unref() or g_type_free_instance() (called when the reference
   count of an instance drops to zero).
</para></listitem>
<listitem><para>  
   This causes the type system to throw away the information retrieved from
   g_type_plugin_complete_type_info() and then it calls
   g_type_plugin_unuse() on <literal>new_type_plugin</literal>.
</para></listitem>
<listitem><para>  
   Things may repeat from the second step.
</para></listitem>
</orderedlist>
</para>
<para>
So basically, you need to implement a #GTypePlugin type that carries a
use_count, once use_count goes from zero to one, you need to load the 
implementation to successfully handle the upcoming 
g_type_plugin_complete_type_info() call. Later, maybe after succeeding 
use/unuse calls, once use_count drops to zero, you can unload the 
implementation again. The type system makes sure to call g_type_plugin_use() 
and g_type_plugin_complete_type_info() again when the type is needed again.
</para>
<para>
#GTypeModule is an implementation of #GTypePlugin that already implements 
most of this except for the actual module loading and unloading. It even 
handles multiple registered types per module.
</para>

<!-- ##### SECTION See_Also ##### -->
<para>
#GTypeModule and g_type_register_dynamic().
</para>

<!-- ##### SECTION Stability_Level ##### -->


<!-- ##### STRUCT GTypePlugin ##### -->
<para>
The <structname>GTypePlugin</structname> typedef is used as a placeholder 
for objects that implement the <structname>GTypePlugin</structname> 
interface.
</para>


<!-- ##### STRUCT GTypePluginClass ##### -->
<para>
The #GTypePlugin interface is used by the type system in order to handle
the lifecycle of dynamically loaded types.
</para>

@use_plugin: Increases the use count of the plugin.
@unuse_plugin: Decreases the use count of the plugin.
@complete_type_info: Fills in the #GTypeInfo and 
  #GTypeValueTable structs for the type. The structs are initialized
  with <literal>memset(s, 0, sizeof (s))</literal> before calling 
  this function.
@complete_interface_info: Fills in missing parts of the #GInterfaceInfo 
  for the interface. The structs is initialized with 
  <literal>memset(s, 0, sizeof (s))</literal> before calling
  this function.

<!-- ##### USER_FUNCTION GTypePluginUse ##### -->
<para>
The type of the @use_plugin function of #GTypePluginClass, which gets called
to increase the use count of @plugin.
</para>

@plugin: the #GTypePlugin whose use count should be increased


<!-- ##### USER_FUNCTION GTypePluginUnuse ##### -->
<para>
The type of the @unuse_plugin function of #GTypePluginClass.
</para>

@plugin: the #GTypePlugin whose use count should be decreased


<!-- ##### USER_FUNCTION GTypePluginCompleteTypeInfo ##### -->
<para>
The type of the @complete_type_info function of #GTypePluginClass.
</para>

@plugin: the #GTypePlugin
@g_type: the #GType whose info is completed
@info: the #GTypeInfo struct to fill in
@value_table: the #GTypeValueTable to fill in


<!-- ##### USER_FUNCTION GTypePluginCompleteInterfaceInfo ##### -->
<para>
The type of the @complete_interface_info function of #GTypePluginClass.
</para>

@plugin: the #GTypePlugin
@instance_type: the #GType of an instantiable type to which the interface
  is added
@interface_type: the #GType of the interface whose info is completed
@info: the #GInterfaceInfo to fill in


<!-- ##### FUNCTION g_type_plugin_use ##### -->
<para>
Calls the @use_plugin function from the #GTypePluginClass of @plugin.
There should be no need to use this function outside of the GObject 
type system itself.
</para>

@plugin: a #GTypePlugin


<!-- ##### FUNCTION g_type_plugin_unuse ##### -->
<para>
Calls the @unuse_plugin function from the #GTypePluginClass of @plugin.
There should be no need to use this function outside of the GObject 
type system itself.
</para>

@plugin: a #GTypePlugin


<!-- ##### FUNCTION g_type_plugin_complete_type_info ##### -->
<para>
Calls the @complete_type_info function from the #GTypePluginClass of @plugin.
There should be no need to use this function outside of the GObject 
type system itself.
</para>

@plugin: a #GTypePlugin
@g_type: the #GType whose info is completed
@info: the #GTypeInfo struct to fill in
@value_table: the #GTypeValueTable to fill in


<!-- ##### FUNCTION g_type_plugin_complete_interface_info ##### -->
<para>
Calls the @complete_interface_info function from the #GTypePluginClass 
of @plugin. There should be no need to use this function outside of the 
GObject type system itself.
</para>

@plugin: the #GTypePlugin
@instance_type: the #GType of an instantiable type to which the interface
  is added
@interface_type: the #GType of the interface whose info is completed
@info: the #GInterfaceInfo to fill in