mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-01 23:13:40 +02:00
docs: General cleanups and rewording in the GObject concepts docs
• Remove copies of function declarations from the explanation — if people want those, they can follow links to the reference manual. • Add markup to make C code more defined. • Remove use of first person and irrelevant name dropping. https://bugzilla.gnome.org/show_bug.cgi?id=744060
This commit is contained in:
@@ -119,19 +119,21 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
order to find the parent class and chain up to the parent class
|
||||
constructor, we can use the <literal>maman_bar_parent_class</literal>
|
||||
pointer that has been set up for us by the
|
||||
<literal>G_DEFINE_TYPE</literal> macro.
|
||||
<link linkend="G-DEFINE-TYPE:CAPS"><literal>G_DEFINE_TYPE</literal></link>
|
||||
macro.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, at one point or another, <function>g_object_constructor</function> is invoked
|
||||
by the last constructor in the chain. This function allocates the object's instance' buffer
|
||||
by the last constructor in the chain. This function allocates the object's instance buffer
|
||||
through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
|
||||
which means that the <function>instance_init</function> function is invoked at this point if one
|
||||
was registered. After <function>instance_init</function> returns, the object is fully initialized and should be
|
||||
ready to answer any user-request. When <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
|
||||
ready to have its methods called by the user. When
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
|
||||
returns, <function>g_object_constructor</function> sets the construction properties
|
||||
(i.e. the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
|
||||
to the user's constructor which is then allowed to do useful instance initialization...
|
||||
to the user's constructor.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -163,10 +165,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<entry>target type's <function>base_init</function> function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
<function>base_init</function> is invoked once for each class structure.</entry>
|
||||
<entry>
|
||||
I have no real idea on how this can be used. If you have a good real-life
|
||||
example of how a class' <function>base_init</function> can be used, please, let me know.
|
||||
</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
|
||||
@@ -186,7 +185,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</row>
|
||||
<row>
|
||||
<!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
|
||||
<entry>interface's interface_init function</entry>
|
||||
<entry>interface's <function>interface_init</function> function</entry>
|
||||
<entry>On interface's vtable</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
@@ -327,7 +326,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<entry morerows="3">Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
|
||||
instance of target type
|
||||
</entry>
|
||||
<entry>interface's interface_finalize function</entry>
|
||||
<entry>interface's <function>interface_finalize</function> function</entry>
|
||||
<entry>On interface's vtable</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
@@ -335,7 +334,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function>for the last
|
||||
instance of target type
|
||||
</entry-->
|
||||
<entry>interface's base_finalize function</entry>
|
||||
<entry>interface's <function>base_finalize</function> function</entry>
|
||||
<entry>On interface's vtable</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
@@ -343,7 +342,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
|
||||
instance of target type
|
||||
</entry-->
|
||||
<entry>target type's class_finalize function</entry>
|
||||
<entry>target type's <function>class_finalize</function> function</entry>
|
||||
<entry>On target type's class structure</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
@@ -351,7 +350,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
|
||||
instance of target type
|
||||
</entry-->
|
||||
<entry>type's base_finalize function</entry>
|
||||
<entry>type's <function>base_finalize</function> function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
<function>base_init</function> is invoked once for each class structure.</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
@@ -367,7 +366,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
<title>Weak References</title>
|
||||
|
||||
<para>
|
||||
Weak References are used to monitor object finalization:
|
||||
Weak references are used to monitor object finalization:
|
||||
<function><link linkend="g-object-weak-ref">g_object_weak_ref</link></function> adds a monitoring callback which does
|
||||
not hold a reference to the object but which is invoked when the object runs
|
||||
its dispose method. As such, each weak ref can be invoked more than once upon
|
||||
@@ -381,12 +380,16 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Weak References are also used to implement <function><link linkend="g-object-add-weak-pointer">g_object_add_weak_pointer</link></function>
|
||||
Weak references are also used to implement <function><link linkend="g-object-add-weak-pointer">g_object_add_weak_pointer</link></function>
|
||||
and <function><link linkend="g-object-remove-weak-pointer">g_object_remove_weak_pointer</link></function>. These functions add a weak reference
|
||||
to the object they are applied to which makes sure to nullify the pointer given by the user
|
||||
when object is finalized.
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
Similarly, <link linkend="GWeakRef"><type>GWeakRef</type></link> can be
|
||||
used to implement weak references if thread safety is required.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="gobject-memory-cycles">
|
||||
@@ -398,7 +401,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
the first phase, executed in the dispose handler is supposed to release all references
|
||||
to other member objects. The second phase, executed by the finalize handler is supposed
|
||||
to complete the object's destruction process. Object methods should be able to run
|
||||
without program error (that is, without segfault :) in-between the two phases.
|
||||
without program error in-between the two phases.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -410,8 +413,8 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Attentive readers might now have understood one of the rules about the dispose handler
|
||||
we stated a bit sooner: the dispose handler can be invoked multiple times. Let's say we
|
||||
This explains one of the rules about the dispose handler stated earlier:
|
||||
the dispose handler can be invoked multiple times. Let's say we
|
||||
have a reference count cycle: object A references B which itself references object A.
|
||||
Let's say we have detected the cycle and we want to destroy the two objects. One way to
|
||||
do this would be to invoke <function><link linkend="g-object-run-dispose">g_object_run_dispose</link></function> on one of the
|
||||
@@ -442,13 +445,12 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
One of GObject's nice features is its generic get/set mechanism for object
|
||||
properties. When an object
|
||||
is instantiated, the object's <function>class_init</function> handler should be used to register
|
||||
the object's properties with <function><link linkend="g-object-class-install-properties">g_object_class_install_properties</link></function>
|
||||
(implemented in <filename>gobject.c</filename>).
|
||||
the object's properties with <function><link linkend="g-object-class-install-properties">g_object_class_install_properties</link></function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The best way to understand how object properties work is by looking at a real example
|
||||
on how it is used:
|
||||
of how it is used:
|
||||
<informalexample><programlisting>
|
||||
/************************************************/
|
||||
/* Implementation */
|
||||
@@ -552,7 +554,7 @@ maman_bar_class_init (MamanBarClass *klass)
|
||||
GObject *bar;
|
||||
GValue val = G_VALUE_INIT;
|
||||
|
||||
bar = g_object_new (MAMAN_TYPE_SUBBAR, NULL);
|
||||
bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
|
||||
g_value_init (&val, G_TYPE_CHAR);
|
||||
g_value_set_char (&val, 11);
|
||||
@@ -567,14 +569,15 @@ g_value_unset (&val);
|
||||
<para>
|
||||
<function><link linkend="g-object-set-property">g_object_set_property</link></function> first ensures a property
|
||||
with this name was registered in bar's <function>class_init</function> handler. If so it walks the class hierarchy,
|
||||
from bottom, most derived type, to top, fundamental type to find the class
|
||||
which registered that property. It then tries to convert the user-provided GValue
|
||||
into a GValue whose type is that of the associated property.
|
||||
from bottom-most most-derived type, to top-most fundamental type to find the class
|
||||
which registered that property. It then tries to convert the user-provided
|
||||
<link linkend="GValue"><type>GValue</type></link>
|
||||
into a <type>GValue</type> whose type is that of the associated property.
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
If the user provides a signed char GValue, as is shown
|
||||
here, and if the object's property was registered as an unsigned int,
|
||||
If the user provides a <type>signed char</type> <type>GValue</type>, as is shown
|
||||
here, and if the object's property was registered as an <type>unsigned int</type>,
|
||||
<function><link linkend="g-value-transform">g_value_transform</link></function> will try to transform the input signed char into
|
||||
an unsigned int. Of course, the success of the transformation depends on the availability
|
||||
of the required transform function. In practice, there will almost always be a transformation
|
||||
@@ -601,8 +604,9 @@ g_value_unset (&val);
|
||||
|
||||
<para>
|
||||
If the user's GValue had been set to a valid value, <function><link linkend="g-object-set-property">g_object_set_property</link></function>
|
||||
would have proceeded with calling the object's set_property class method. Here, since our
|
||||
implementation of Foo did override this method, the code path would jump to
|
||||
would have proceeded with calling the object's
|
||||
<function>set_property</function> class method. Here, since our
|
||||
implementation of <type>Foo</type> did override this method, execution would jump to
|
||||
<function>foo_set_property</function> after having retrieved from the
|
||||
<link linkend="GParamSpec"><type>GParamSpec</type></link> the <emphasis>param_id</emphasis>
|
||||
<footnote>
|
||||
@@ -619,7 +623,8 @@ g_value_unset (&val);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once the property has been set by the object's set_property class method, the code path
|
||||
Once the property has been set by the object's
|
||||
<function>set_property</function> class method, execution
|
||||
returns to <function><link linkend="g-object-set-property">g_object_set_property</link></function> which makes sure that
|
||||
the "notify" signal is emitted on the object's instance with the changed property as
|
||||
parameter unless notifications were frozen by <function><link linkend="g-object-freeze-notify">g_object_freeze_notify</link></function>.
|
||||
@@ -627,11 +632,14 @@ g_value_unset (&val);
|
||||
|
||||
<para>
|
||||
<function><link linkend="g-object-thaw-notify">g_object_thaw_notify</link></function> can be used to re-enable notification of
|
||||
property modifications through the "notify" signal. It is important to remember that
|
||||
property modifications through the
|
||||
<link linkend="GObject-notify"><type>“notify”</type></link> signal. It is important to remember that
|
||||
even if properties are changed while property change notification is frozen, the "notify"
|
||||
signal will be emitted once for each of these changed properties as soon as the property
|
||||
change notification is thawed: no property change is lost for the "notify" signal. Signal
|
||||
can only be delayed by the notification freezing mechanism.
|
||||
change notification is thawed: no property change is lost for the "notify"
|
||||
signal, although multiple notifications for a single property are
|
||||
compressed. Signals can only be delayed by the notification freezing
|
||||
mechanism.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -663,25 +671,28 @@ g_object_set (G_OBJECT (foo),
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Of course, the _get versions are also available: <function><link linkend="g-object-get">g_object_get</link></function>
|
||||
Equivalent <function>_get</function> versions are also available:
|
||||
<function><link linkend="g-object-get">g_object_get</link></function>
|
||||
and <function><link linkend="g-object-get-valist">g_object_get_valist</link></function> (variadic version) can be used to get numerous
|
||||
properties at once.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
These high level functions have one drawback - they don't provide a return result.
|
||||
These high level functions have one drawback — they don't provide a return value.
|
||||
One should pay attention to the argument types and ranges when using them.
|
||||
A known source of errors is to e.g. pass a gfloat instead of a gdouble and thus
|
||||
shifting all subsequent parameters by four bytes. Also forgetting the terminating
|
||||
NULL will lead to unexpected behaviour.
|
||||
A known source of errors is to pass a different type from what the
|
||||
property expects; for instance, passing an integer when the property
|
||||
expects a floating point value and thus shifting all subsequent parameters
|
||||
by some number of bytes. Also forgetting the terminating
|
||||
<literal>NULL</literal> will lead to undefined behaviour.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Really attentive readers now understand how <function><link linkend="g-object-new">g_object_new</link></function>,
|
||||
This explains how <function><link linkend="g-object-new">g_object_new</link></function>,
|
||||
<function><link linkend="g-object-newv">g_object_newv</link></function> and <function><link linkend="g-object-new-valist">g_object_new_valist</link></function>
|
||||
work: they parse the user-provided variable number of parameters and invoke
|
||||
<function><link linkend="g-object-set">g_object_set</link></function> on the parameters only after the object has been successfully constructed.
|
||||
Of course, the "notify" signal will be emitted for each property set.
|
||||
The "notify" signal will be emitted for each property set.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
Reference in New Issue
Block a user