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
|