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:
Philip Withnall
2015-02-23 15:30:57 +00:00
parent a86ef242e4
commit ab9b52e69c
4 changed files with 243 additions and 292 deletions

View File

@@ -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 (&amp;val, G_TYPE_CHAR);
g_value_set_char (&amp;val, 11);
@@ -567,14 +569,15 @@ g_value_unset (&amp;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 (&amp;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 (&amp;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 (&amp;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>