mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
merged in docs form the gobject tutorial
This commit is contained in:
parent
e8ae00303b
commit
9ce3590d4e
@ -1,3 +1,15 @@
|
||||
2005-04-22 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* gobject/Makefile.am:
|
||||
* gobject/gobject-docs.sgml:
|
||||
* gobject/tut_gobject.xml:
|
||||
* gobject/tut_gsignal.xml:
|
||||
* gobject/tut_gtype.xml:
|
||||
* gobject/tut_howto.xml:
|
||||
* gobject/tut_intro.xml:
|
||||
* gobject/tut_tools.xml:
|
||||
merged in docs form the gobject tutorial
|
||||
|
||||
2005-03-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/tmpl/arrays_pointer.sgml: Clarify the docs for
|
||||
|
@ -34,14 +34,21 @@ GTKDOC_LIBS = \
|
||||
# Extra options to supply to gtkdoc-mkdb
|
||||
MKDB_OPTIONS=
|
||||
|
||||
# Images to copy into HTML directory
|
||||
HTML_IMAGES =
|
||||
|
||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE)
|
||||
content_files = version.xml \
|
||||
glib-mkenums.xml \
|
||||
glib-genmarshal.xml \
|
||||
gobject-query.xml
|
||||
gobject-query.xml \
|
||||
tut_gobject.xml \
|
||||
tut_gsignal.xml \
|
||||
tut_gtype.xml \
|
||||
tut_howto.xml \
|
||||
tut_intro.xml \
|
||||
tut_tools.xml
|
||||
|
||||
# Images to copy into HTML directory
|
||||
HTML_IMAGES = \
|
||||
$(srcdir)/images/glue.png
|
||||
|
||||
# Extra options to supply to gtkdoc-fixref
|
||||
FIXXREF_OPTIONS=--extra-dir=$(srcdir)/../glib/html
|
||||
|
@ -18,6 +18,14 @@
|
||||
<!ENTITY glib-genmarshal SYSTEM "glib-genmarshal.xml">
|
||||
<!ENTITY gobject-query SYSTEM "gobject-query.xml">
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
|
||||
<!ENTITY tutorial-Intro SYSTEM "tut_intro.xml">
|
||||
<!ENTITY tutorial-GType SYSTEM "tut_gtype.xml">
|
||||
<!ENTITY tutorial-GObject SYSTEM "tut_gobject.xml">
|
||||
<!ENTITY tutorial-GSignal SYSTEM "tut_gsignal.xml">
|
||||
<!ENTITY tutorial-HowTo SYSTEM "tut_howto.xml">
|
||||
<!ENTITY tutorial-Tools SYSTEM "tut_tools.xml">
|
||||
|
||||
]>
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
@ -28,48 +36,56 @@
|
||||
<preface>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Most modern programming languages come with their own native object
|
||||
systems and additional fundamental algorithmic language constructs.
|
||||
Just as GLib serves as an implementation of such fundamental
|
||||
types and algorithms (linked lists, hash tables and so forth), the
|
||||
GLib Object System provides the required implementations of a
|
||||
flexible extensible and intentionally easy to map (into other
|
||||
languages) object oriented framework for C.
|
||||
The substantial elements that are provided can be summarized as:
|
||||
<variablelist>
|
||||
<varlistentry><term></term><listitem><para>
|
||||
* A generic type system to register arbitrary single-inherited
|
||||
flat and deep derived types as well as interfaces for
|
||||
structured types.
|
||||
It takes care of creation, initialization and memory management
|
||||
of the assorted object and class structures, maintains
|
||||
parent/child relationships and deals with dynamic implementations
|
||||
of such types. That is, their type specific implementations are
|
||||
relocatable/unloadable during runtime.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term></term><listitem><para>
|
||||
* A collection of fundamental type implementations, such as integers,
|
||||
doubles, enums and structured types, to name a few.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term></term><listitem><para>
|
||||
* A sample fundamental type implementation to base object hierarchies
|
||||
upon - the GObject fundamental type.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term></term><listitem><para>
|
||||
* A signal system that allows very flexible user customization of
|
||||
virtual/overridable object methods and can serve as a powerful
|
||||
notification mechanism.
|
||||
</para></listitem></varlistentry>
|
||||
<varlistentry><term></term><listitem><para>
|
||||
* An extensible parameter/value system, supporting all the provided
|
||||
fundamental types that can be used to generically handle object
|
||||
properties or otherwise parameterized types.
|
||||
</para></listitem></varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
Most modern programming languages come with their own native object
|
||||
systems and additional fundamental algorithmic language constructs.
|
||||
Just as GLib serves as an implementation of such fundamental
|
||||
types and algorithms (linked lists, hash tables and so forth), the
|
||||
GLib Object System provides the required implementations of a
|
||||
flexible extensible and intentionally easy to map (into other
|
||||
languages) object oriented framework for C.
|
||||
The substantial elements that are provided can be summarized as:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
A generic type system to register arbitrary single-inherited
|
||||
flat and deep derived types as well as interfaces for
|
||||
structured types.
|
||||
It takes care of creation, initialization and memory management
|
||||
of the assorted object and class structures, maintains
|
||||
parent/child relationships and deals with dynamic implementations
|
||||
of such types. That is, their type specific implementations are
|
||||
relocatable/unloadable during runtime.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
A collection of fundamental type implementations, such as integers,
|
||||
doubles, enums and structured types, to name a few.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
A sample fundamental type implementation to base object hierarchies
|
||||
upon - the GObject fundamental type.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
A signal system that allows very flexible user customization of
|
||||
virtual/overridable object methods and can serve as a powerful
|
||||
notification mechanism.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
An extensible parameter/value system, supporting all the provided
|
||||
fundamental types that can be used to generically handle object
|
||||
properties or otherwise parameterized types.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</preface>
|
||||
|
||||
<reference>
|
||||
<part label="I">
|
||||
<title>Concepts</title>
|
||||
|
||||
&tutorial-Intro;
|
||||
&tutorial-GType;
|
||||
&tutorial-GObject;
|
||||
&tutorial-GSignal;
|
||||
</part>
|
||||
<reference label="II">
|
||||
<title>API Reference</title>
|
||||
|
||||
&gobject-GType;
|
||||
@ -87,13 +103,23 @@
|
||||
&gobject-Value-Arrays;
|
||||
|
||||
</reference>
|
||||
<reference>
|
||||
<reference label="III">
|
||||
<title>Tools Reference</title>
|
||||
|
||||
&glib-mkenums;
|
||||
&glib-genmarshal;
|
||||
&gobject-query;
|
||||
</reference>
|
||||
<part label="IV">
|
||||
<title>Tutorial</title>
|
||||
|
||||
&tutorial-HowTo;
|
||||
</part>
|
||||
<part label="V">
|
||||
<title>Related Tools</title>
|
||||
|
||||
&tutorial-Tools;
|
||||
</part>
|
||||
|
||||
<index>
|
||||
<title>Index</title>
|
||||
|
@ -1,16 +1,16 @@
|
||||
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||
|
||||
<chapter id="chapter-gobject">
|
||||
<title>GObject: what brings everything together.</title>
|
||||
<title>The GObject base class</title>
|
||||
|
||||
<para>
|
||||
The two previous chapters discussed the details of Glib's Dynamic Type System
|
||||
and its signal control system. The GObject library also contains an implementation
|
||||
for a base fundamental type named <type>GObject</type>.
|
||||
for a base fundamental type named <type><link linkend="GObject">GObject</link></type>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<type>GObject</type> is a fundamental classed instantiable type. It implements:
|
||||
<type><link linkend="GObject">GObject</link></type> is a fundamental classed instantiable type. It implements:
|
||||
<itemizedlist>
|
||||
<listitem><para>Memory management with reference counting</para></listitem>
|
||||
<listitem><para>Construction/Destruction of instances</para></listitem>
|
||||
@ -18,7 +18,7 @@
|
||||
<listitem><para>Easy use of signals</para></listitem>
|
||||
</itemizedlist>
|
||||
All the GTK+ objects and all of the objects in Gnome libraries which use the glib type
|
||||
system inherit from <type>GObject</type> which is why it is important to understand
|
||||
system inherit from <type><link linkend="GObject">GObject</link></type> which is why it is important to understand
|
||||
the details of how it works.
|
||||
</para>
|
||||
|
||||
@ -26,13 +26,13 @@
|
||||
<title>Object instanciation</title>
|
||||
|
||||
<para>
|
||||
The <function>g_object_new</function> family of functions can be used to instantiate any
|
||||
The <function><link linkend="g-object-new">g_object_new</link></function> family of functions can be used to instantiate any
|
||||
GType which inherits from the GObject base type. All these functions make sure the class
|
||||
and instance structures have been correctly initialized by glib's type system and
|
||||
then invoke at one point or another the constructor class method which is used to:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Allocate and clear memory through <function>g_type_create_instance</function>,
|
||||
Allocate and clear memory through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Initialize the object' instance with the construction properties.
|
||||
@ -155,7 +155,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once <function>g_object_new</function> has obtained a reference to an initialized
|
||||
Once <function><link linkend="g-object-new">g_object_new</link></function> has obtained a reference to an initialized
|
||||
class structure, it invokes its constructor method to create an instance of the new
|
||||
object. Since it has just been overridden by <function>maman_bar_class_init</function>
|
||||
to <function>maman_bar_constructor</function>, the latter is called and, because it
|
||||
@ -164,34 +164,34 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
to save the original constructor in a static variable from <function>maman_bar_class_init</function>
|
||||
and then to re-use it from <function>maman_bar_constructor</function>. This is clearly possible
|
||||
and very simple but I was told it was not nice and the prefered way is to use the
|
||||
<function>g_type_class_peek</function> and <function>g_type_class_peek_parent</function> functions.
|
||||
<function><link linkend="g-type-class-peek">g_type_class_peek</link></function> and <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> functions.
|
||||
</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
|
||||
through <function>g_type_create_instance</function>
|
||||
through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
|
||||
which means that the instance_init function is invoked at this point if one
|
||||
was registered. After instance_init returns, the object is fully initialized and should be
|
||||
ready to answer any user-request. When <function>g_type_create_instance</function>
|
||||
ready to answer any user-request. When <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
|
||||
returns, <function>g_object_constructor</function> sets the construction properties
|
||||
(ie: the properties which were given to <function>g_object_new</function>) and returns
|
||||
(ie: 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...
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The process described above might seem a bit complicated (it <emphasis>is</emphasis> actually
|
||||
overly complicated in my opinion..) but it can be summarized easily by the table below which
|
||||
lists the functions invoked by <function>g_object_new</function> and their order of
|
||||
lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and their order of
|
||||
invocation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The array below lists the functions invoked by <function>g_object_new</function> and
|
||||
The array below lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and
|
||||
their order of invocation:
|
||||
|
||||
<table id="gobject-construction-table">
|
||||
<title><function>g_object_new</function></title>
|
||||
<title><function><link linkend="g-object-new">g_object_new</link></function></title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="*" colnum="1" align="left"/>
|
||||
<colspec colwidth="*" colnum="2" align="left"/>
|
||||
@ -207,7 +207,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>First call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>target type's base_init function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
base_init is invoked once for each class structure.</entry>
|
||||
@ -217,7 +217,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>target type's class_init function</entry>
|
||||
<entry>On target type's class structure</entry>
|
||||
<entry>
|
||||
@ -227,19 +227,19 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>interface' base_init function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>interface' interface_init function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Each call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>target type's class constructor method: GObjectClass->constructor</entry>
|
||||
<entry>On object's instance</entry>
|
||||
<entry>
|
||||
@ -250,7 +250,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Each call to <function>g_object_new</function> for target type</entry>
|
||||
<entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
|
||||
<entry>type's instance_init function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
the instance_init provided for each type is invoked once for each instance
|
||||
@ -270,7 +270,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
Readers should feel concerned about one little twist in the order in which functions
|
||||
are invoked: while, technically, the class' constructor method is called
|
||||
<emphasis>before</emphasis> the GType's instance_init function (since
|
||||
<function>g_type_create_instance</function> which calls instance_init is called by
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> which calls instance_init is called by
|
||||
<function>g_object_constructor</function> which is the top-level class
|
||||
constructor method and to which users are expected to chain to), the user's code
|
||||
which runs in a user-provided constructor will always run <emphasis>after</emphasis>
|
||||
@ -322,19 +322,19 @@ void g_object_run_dispose (GObject *object);
|
||||
<title>Reference count</title>
|
||||
|
||||
<para>
|
||||
The functions <function>g_object_ref</function>/<function>g_object_unref</function> respectively
|
||||
The functions <function><link linkend="g-object-ref">g_object_ref</link></function>/<function><link linkend="g-object-unref">g_object_unref</link></function> respectively
|
||||
increase and decrease the reference count. None of these function is thread-safe.
|
||||
The reference count is, unsurprisingly, initialized to one by
|
||||
<function>g_object_new</function> which means that the caller
|
||||
<function><link linkend="g-object-new">g_object_new</link></function> which means that the caller
|
||||
is currenly the sole owner of the newly-created reference.
|
||||
When the reference count reaches zero, that is,
|
||||
when <function>g_object_unref</function> is called by the last client holding
|
||||
when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding
|
||||
a reference to the object, the <emphasis>dispose</emphasis> and the
|
||||
<emphasis>finalize</emphasis> class methods are invoked.
|
||||
</para>
|
||||
<para>
|
||||
Finally, after <emphasis>finalize</emphasis> is invoked,
|
||||
<function>g_type_free_instance</function> is called to free the object instance.
|
||||
<function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is called to free the object instance.
|
||||
Depending on the memory allocation policy decided when the type was registered (through
|
||||
one of the <function>g_type_register_*</function> functions), the object's instance
|
||||
memory will be freed or returned to the object pool for this type.
|
||||
@ -346,7 +346,7 @@ void g_object_run_dispose (GObject *object);
|
||||
<para>
|
||||
The table below summarizes the destruction process of a GObject:
|
||||
<table id="gobject-destruction-table">
|
||||
<title><function>g_object_unref</function></title>
|
||||
<title><function><link linkend="g-object-unref">g_object_unref</link></function></title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="*" colnum="1" align="left"/>
|
||||
<colspec colwidth="*" colnum="2" align="left"/>
|
||||
@ -362,7 +362,7 @@ void g_object_run_dispose (GObject *object);
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function> for an instance
|
||||
<entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
|
||||
of target type</entry>
|
||||
<entry>target type's dispose class function</entry>
|
||||
<entry>GObject instance</entry>
|
||||
@ -376,7 +376,7 @@ void g_object_run_dispose (GObject *object);
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function> for an instance
|
||||
<entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
|
||||
of target type
|
||||
</entry>
|
||||
<entry>target type's finalize class function</entry>
|
||||
@ -392,28 +392,28 @@ void g_object_run_dispose (GObject *object);
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function> for the last
|
||||
<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' interface_finalize function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function>for the last
|
||||
<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' base_finalize function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function> for the last
|
||||
<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>On target type's class structure</entry>
|
||||
<entry>Never used in practice. Unlikely you will need it.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_object_unref</function> for the last
|
||||
<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>On the inheritance tree of classes from fundamental type to target type.
|
||||
@ -432,7 +432,7 @@ void g_object_run_dispose (GObject *object);
|
||||
|
||||
<para>
|
||||
Weak References are used to monitor object finalization:
|
||||
<function>g_object_weak_ref</function> adds a monitoring callback which does
|
||||
<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
|
||||
object finalization (since dispose can run more than once during object
|
||||
@ -440,13 +440,13 @@ void g_object_run_dispose (GObject *object);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_object_weak_unref</function> can be used to remove a monitoring
|
||||
<function><link linkend="g-object-weak-unref">g_object_weak_unref</link></function> can be used to remove a monitoring
|
||||
callback from the object.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Weak References are also used to implement <function>g_object_add_weak_pointer</function>
|
||||
and <function>g_object_remove_weak_pointer</function>. These functions add a weak reference
|
||||
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>
|
||||
@ -473,7 +473,7 @@ void g_object_run_dispose (GObject *object);
|
||||
<para>
|
||||
This two-step destruction process is very useful to break reference counting cycles.
|
||||
While the detection of the cycles is up to the external code, once the cycles have been
|
||||
detected, the external code can invoke <function>g_object_dispose</function> which
|
||||
detected, the external code can invoke <function><link linkend="g-object-dispose">g_object_dispose</link></function> which
|
||||
will indeed break any existing cycles since it will run the dispose handler associated
|
||||
to the object and thus release all references to other objects.
|
||||
</para>
|
||||
@ -483,7 +483,7 @@ void g_object_run_dispose (GObject *object);
|
||||
we stated a bit sooner: 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>g_object_dispose</function> on one of the
|
||||
do this would be to invoke <function><link linkend="g-object-dispose">g_object_dispose</link></function> on one of the
|
||||
objects.
|
||||
</para>
|
||||
|
||||
@ -512,7 +512,7 @@ void g_object_run_dispose (GObject *object);
|
||||
One of GObject's nice features is its generic get/set mechanism for object
|
||||
properties. When an object
|
||||
is instanciated, the object's class_init handler should be used to register
|
||||
the object's properties with <function>g_object_class_install_property</function>
|
||||
the object's properties with <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>
|
||||
(implemented in <filename>gobject.c</filename>).
|
||||
</para>
|
||||
|
||||
@ -635,9 +635,9 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_object_set_property</function> first ensures a property
|
||||
<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 class_init handler. If so, it calls
|
||||
<function>object_set_property</function> which first walks the class hierarchy,
|
||||
<function><link linkend="object-set-property">object_set_property</link></function> which first 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 if that of the associated property.
|
||||
@ -646,7 +646,7 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
||||
<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,
|
||||
<function>g_value_transform</function> will try to transform the input signed char into
|
||||
<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
|
||||
<footnote>
|
||||
@ -658,46 +658,46 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After transformation, the <type>GValue</type> is validated by
|
||||
<function>g_param_value_validate</function> which makes sure the user's
|
||||
data stored in the <type>GValue</type> matches the characteristics specified by
|
||||
the property's <type>GParamSpec</type>. Here, the <type>GParamSpec</type> we
|
||||
After transformation, the <type><link linkend="GValue">GValue</link></type> is validated by
|
||||
<function><link linkend="g-param-value-validate">g_param_value_validate</link></function> which makes sure the user's
|
||||
data stored in the <type><link linkend="GValue">GValue</link></type> matches the characteristics specified by
|
||||
the property's <type><link linkend="GParamSpec">GParamSpec</link></type>. Here, the <type><link linkend="GParamSpec">GParamSpec</link></type> we
|
||||
provided in class_init has a validation function which makes sure that the GValue
|
||||
contains a value which respects the minimum and maximum bounds of the
|
||||
<type>GParamSpec</type>. In the example above, the client's GValue does not
|
||||
<type><link linkend="GParamSpec">GParamSpec</link></type>. In the example above, the client's GValue does not
|
||||
respect these constraints (it is set to 11, while the maximum is 10). As such, the
|
||||
<function>g_object_set_property</function> function will return with an error.
|
||||
<function><link linkend="g-object-set-property">g_object_set_property</link></function> function will return with an error.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the user's GValue had been set to a valid value, <function>object_set_property</function>
|
||||
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
|
||||
<function>foo_set_property</function> after having retrieved from the
|
||||
<type>GParamSpec</type> the <emphasis>param_id</emphasis>
|
||||
<type><link linkend="GParamSpec">GParamSpec</link></type> the <emphasis>param_id</emphasis>
|
||||
<footnote>
|
||||
<para>
|
||||
It should be noted that the param_id used here need only to uniquely identify each
|
||||
<type>GParamSpec</type> within the <type>FooClass</type> such that the switch
|
||||
<type><link linkend="GParamSpec">GParamSpec</link></type> within the <type><link linkend="FooClass">FooClass</link></type> such that the switch
|
||||
used in the set and get methods actually works. Of course, this locally-unique
|
||||
integer is purely an optimization: it would have been possible to use a set of
|
||||
<emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements.
|
||||
</para>
|
||||
</footnote>
|
||||
which had been stored by
|
||||
<function>g_object_class_install_property</function>.
|
||||
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once the property has been set by the object's set_property class method, the code path
|
||||
returns to <function>g_object_set_property</function> which calls
|
||||
<function>g_object_notify_queue_thaw</function>. This function makes sure that
|
||||
returns to <function><link linkend="g-object-set-property">g_object_set_property</link></function> which calls
|
||||
<function><link linkend="g-object-notify-queue-thaw">g_object_notify_queue_thaw</link></function>. This function 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>g_object_freeze_notify</function>.
|
||||
parameter unless notifications were frozen by <function><link linkend="g-object-freeze-notify">g_object_freeze_notify</link></function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_object_thaw_notify</function> can be used to re-enable notification of
|
||||
<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
|
||||
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
|
||||
@ -710,8 +710,8 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
||||
|
||||
|
||||
<para>
|
||||
It is interesting to note that the <function>g_object_set</function> and
|
||||
<function>g_object_set_valist</function> (vararg version) functions can be used to set
|
||||
It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
|
||||
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
|
||||
multiple properties at once. The client code shown above can then be re-written as:
|
||||
<programlisting>
|
||||
MamanBar *foo;
|
||||
@ -725,16 +725,16 @@ g_object_set (G_OBJECT (foo),
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Of course, the _get versions are also available: <function>g_object_get</function>
|
||||
and <function>g_object_get_valist</function> (vararg version) can be used to get numerous
|
||||
Of course, the _get 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> (vararg version) can be used to get numerous
|
||||
properties at once.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Really attentive readers now understand how <function>g_object_new</function>,
|
||||
<function>g_object_newv</function> and <function>g_object_new_valist</function>
|
||||
Really attentive readers now understand 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>g_object_set</function> on each pair of parameters only after the object has been successfully constructed.
|
||||
<function><link linkend="g-object-set">g_object_set</link></function> on each pair of parameters only after the object has been successfully constructed.
|
||||
Of course, the "notify" signal will be emitted for each property set.
|
||||
</para>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||
<chapter id="chapter-signal">
|
||||
<title>Signals</title>
|
||||
<title>The GObject messaging system</title>
|
||||
|
||||
<sect1 id="closure">
|
||||
<title>Closures</title>
|
||||
@ -28,7 +28,7 @@ return_type function_callback (... , gpointer user_data);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <type>GClosure</type> structure represents the common functionality of all
|
||||
The <type><link linkend="GClosure">GClosure</link></type> structure represents the common functionality of all
|
||||
closure implementations: there exist a different Closure implementation for
|
||||
each separate runtime which wants to use the GObject type system.
|
||||
<footnote><para>
|
||||
@ -39,27 +39,27 @@ return_type function_callback (... , gpointer user_data);
|
||||
it behaves as a normal C object for GTK+ and as a normal Python object for
|
||||
python code.
|
||||
</para></footnote>
|
||||
The GObject library provides a simple <type>GCClosure</type> type which
|
||||
The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
|
||||
is a specific implementation of closures to be used with C/C++ callbacks.
|
||||
</para>
|
||||
<para>
|
||||
A <type>GClosure</type> provides simple services:
|
||||
A <type><link linkend="GClosure">GClosure</link></type> provides simple services:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Invocation (<function>g_closure_invoke</function>): this is what closures
|
||||
Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
|
||||
were created for: they hide the details of callback invocation from the
|
||||
callback invocator.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Notification: the closure notifies listeners of certain events such as
|
||||
closure invocation, closure invalidation and closure finalization. Listeners
|
||||
can be registered with <function>g_closure_add_finalize_notifier</function>
|
||||
(finalization notification), <function>g_closure_add_invalidate_notifier</function>
|
||||
can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
|
||||
(finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
|
||||
(invalidation notification) and
|
||||
<function>g_closure_add_marshal_guards</function> (invocation notification).
|
||||
<function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
|
||||
There exist symmetric de-registration functions for finalization and invalidation
|
||||
events (<function>g_closure_remove_finalize_notifier</function> and
|
||||
<function>g_closure_remove_invalidate_notifier</function>) but not for the invocation
|
||||
events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
|
||||
<function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
|
||||
process.
|
||||
<footnote><para>
|
||||
Closures are refcounted and notify listeners of their destruction in a two-stage
|
||||
@ -74,8 +74,8 @@ return_type function_callback (... , gpointer user_data);
|
||||
|
||||
<para>
|
||||
If you are using C or C++
|
||||
to connect a callback to a given event, you will either use the simple <type>GCClosure</type>s
|
||||
which have a pretty minimal API or the even simpler <function>g_signal_connect</function>
|
||||
to connect a callback to a given event, you will either use the simple <type><link linkend="GCClosure">GCClosure</link></type>s
|
||||
which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
||||
functions (which will be presented a bit later :).
|
||||
<programlisting>
|
||||
GClosure* g_cclosure_new (GCallback callback_func,
|
||||
@ -90,16 +90,16 @@ GClosure* g_signal_type_cclosure_new (GType itype,
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_cclosure_new</function> will create a new closure which can invoke the
|
||||
<function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
|
||||
user-provided callback_func with the user-provided user_data as last parameter. When the closure
|
||||
is finalized (second stage of the destruction process), it will invoke the destroy_data function
|
||||
if the user has supplied one.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_cclosure_new_swap</function> will create a new closure which can invoke the
|
||||
<function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
|
||||
user-provided callback_func with the user-provided user_data as first parameter (instead of being the
|
||||
last parameter as with <function>g_cclosure_new</function>). When the closure
|
||||
last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
|
||||
is finalized (second stage of the destruction process), it will invoke the destroy_data
|
||||
function if the user has supplied one.
|
||||
</para>
|
||||
@ -200,8 +200,8 @@ return_type function_callback (gpointer instance, ... , gpointer user_data);
|
||||
<title>Signal registration</title>
|
||||
|
||||
<para>
|
||||
To register a new signal on an existing type, we can use any of <function>g_signal_newv</function>,
|
||||
<function>g_signal_new_valist</function> or <function>g_signal_new</function> functions:
|
||||
To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
|
||||
<function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
|
||||
<programlisting>
|
||||
guint g_signal_newv (const gchar *signal_name,
|
||||
GType itype,
|
||||
@ -280,13 +280,13 @@ guint g_signal_newv (const gchar *signal_name,
|
||||
of a given signal on all the instances of the type which supports that signal.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can use <function>g_signal_override_class_closure</function> which
|
||||
You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
|
||||
overrides the class_closure of a given type. It is possible to call this function
|
||||
only on a derived type of the type on which the signal was registered.
|
||||
This function is of use only to language bindings.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can register a closure with the <function>g_signal_connect</function>
|
||||
You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
||||
family of functions. This is an instance-specific operation: the closure
|
||||
will be invoked only during emission of a given signal on a given instance.
|
||||
</para></listitem>
|
||||
@ -295,8 +295,8 @@ guint g_signal_newv (const gchar *signal_name,
|
||||
emission hooks are invoked whenever a given signal is emitted whatever the instance on
|
||||
which it is emitted. Emission hooks are used for example to get all mouse_clicked
|
||||
emissions in an application to be able to emit the small mouse click sound.
|
||||
Emission hooks are connected with <function>g_signal_add_emission_hook</function>
|
||||
and removed with <function>g_signal_remove_emission_hook</function>.
|
||||
Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
|
||||
and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -308,7 +308,7 @@ guint g_signal_newv (const gchar *signal_name,
|
||||
<title>Signal emission</title>
|
||||
|
||||
<para>
|
||||
Signal emission is done through the use of the <function>g_signal_emit</function> family
|
||||
Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
|
||||
of functions.
|
||||
<programlisting>
|
||||
void g_signal_emitv (const GValue *instance_and_params,
|
||||
@ -369,8 +369,8 @@ void g_signal_emitv (const GValue *instance_and_pa
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
|
||||
with the <function>g_signal_connect</function> family of
|
||||
functions, and if they are not blocked (with the <function>g_signal_handler_block</function>
|
||||
with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of
|
||||
functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
|
||||
family of functions) they are run here, from first to last connected.
|
||||
Jump to <emphasis>RUN_LAST</emphasis> state.
|
||||
</para></listitem>
|
||||
@ -398,7 +398,7 @@ void g_signal_emitv (const GValue *instance_and_pa
|
||||
<para>
|
||||
If, at any point during emission (except in RUN_CLEANUP state), one of the
|
||||
closures or emission hook stops the signal emission with
|
||||
<function>g_signal_stop</function>, emission jumps to CLEANUP state.
|
||||
<function><link linkend="g-signal-stop">g_signal_stop</link></function>, emission jumps to CLEANUP state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -416,7 +416,7 @@ void g_signal_emitv (const GValue *instance_and_pa
|
||||
|
||||
<para>
|
||||
If no accumulator function was provided, the value returned by the last handler
|
||||
run will be returned by <function>g_signal_emit</function>.
|
||||
run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
@ -432,11 +432,11 @@ void g_signal_emitv (const GValue *instance_and_pa
|
||||
|
||||
<para>
|
||||
Of the three main connection functions,
|
||||
only one has an explicit detail parameter as a <type>GQuark</type>
|
||||
only one has an explicit detail parameter as a <type><link linkend="GQuark">GQuark</link></type>
|
||||
<footnote>
|
||||
<para>A GQuark is an integer which uniquely represents a string. It is possible to transform
|
||||
back and forth between the integer and string representations with the functions
|
||||
<function>g_quark_from_string</function> and <function>g_quark_to_string</function>.
|
||||
<function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
|
||||
</para>
|
||||
</footnote>:
|
||||
<programlisting>
|
||||
@ -469,7 +469,7 @@ gulong g_signal_connect_data (gpointer instance,
|
||||
|
||||
<para>
|
||||
Of the four main signal emission functions, three have an explicit detail parameter as a
|
||||
<type>GQuark</type> again:
|
||||
<type><link linkend="GQuark">GQuark</link></type> again:
|
||||
<programlisting>
|
||||
void g_signal_emitv (const GValue *instance_and_params,
|
||||
guint signal_id,
|
||||
@ -491,7 +491,7 @@ void g_signal_emit_by_name (gpointer instance,
|
||||
...);
|
||||
</programlisting>
|
||||
The format of the detailed_signal parameter is exactly the same as the format used by
|
||||
the <function>g_signal_connect</function> functions: <emphasis>signal_name::detail_name</emphasis>.
|
||||
the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -42,19 +42,19 @@ GType g_type_register_fundamental (GType type_id,
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_type_register_static</function> and
|
||||
<function>g_type_register_fundamental</function>
|
||||
<function><link linkend="g-type-register-static">g_type_register_static</link></function> and
|
||||
<function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function>
|
||||
are the C functions, defined in
|
||||
<filename>gtype.h</filename> and implemented in <filename>gtype.c</filename>
|
||||
which you should use to register a new type in the program's type system.
|
||||
which you should use to register a new <type><link linkend="GType">GType</link></type> in the program's type system.
|
||||
It is not likely you will ever need to use
|
||||
<function>g_type_register_fundamental</function> (you have to be Tim Janik
|
||||
<function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function> (you have to be Tim Janik
|
||||
to do that) but in case you want to, the last chapter explains how to create
|
||||
new fundamental types.
|
||||
<footnote>
|
||||
<para>
|
||||
Please, note that there exist another registration function: the
|
||||
<function>g_type_register_dynamic</function>. We will not discuss this
|
||||
<function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>. We will not discuss this
|
||||
function here since its use is very similar to the <function>_static</function>
|
||||
version.
|
||||
</para>
|
||||
@ -64,7 +64,7 @@ GType g_type_register_fundamental (GType type_id,
|
||||
<para>
|
||||
Fundamental types are top-level types which do not derive from any other type
|
||||
while other non-fundamental types derive from other types.
|
||||
Upon initialization by <function>g_type_init</function>, the type system not
|
||||
Upon initialization by <function><link linkend="g-type-init">g_type_init</link></function>, the type system not
|
||||
only initializes its internal data structures but it also registers a number of core
|
||||
types: some of these are fundamental types. Others are types derived from these
|
||||
fundamental types.
|
||||
@ -74,37 +74,37 @@ GType g_type_register_fundamental (GType type_id,
|
||||
Fundamental and non-Fundamental types are defined by:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
class size: the class_size field in <type>GTypeInfo</type>.
|
||||
class size: the class_size field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
class initialization functions (C++ constructor): the base_init and
|
||||
class_init fields in <type>GTypeInfo</type>.
|
||||
class_init fields in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
class destruction functions (C++ destructor): the base_finalize and
|
||||
class_finalize fields in <type>GTypeInfo</type>.
|
||||
class_finalize fields in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
instance size (C++ parameter to new): the instance_size field in
|
||||
<type>GTypeInfo</type>.
|
||||
<type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
instanciation policy (C++ type of new operator): the n_preallocs
|
||||
field in <type>GTypeInfo</type>.
|
||||
field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
copy functions (C++ copy operators): the value_table field in
|
||||
<type>GTypeInfo</type>.
|
||||
<type><link linkend="GTypeInfo">GTypeInfo</link></type>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
XXX: <type>GTypeFlags</type>.
|
||||
XXX: <type><link linkend="GTypeFlags">GTypeFlags</link></type>.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
Fundamental types are also defined by a set of <type>GTypeFundamentalFlags</type>
|
||||
which are stored in a <type>GTypeFundamentalInfo</type>.
|
||||
Fundamental types are also defined by a set of <type><link linkend="GTypeFundamentalFlags">GTypeFundamentalFlags</link></type>
|
||||
which are stored in a <type><link linkend="GTypeFundamentalInfo">GTypeFundamentalInfo</link></type>.
|
||||
Non-Fundamental types are furthermore defined by the type of their parent which is
|
||||
passed as the parent_type parameter to <function>g_type_register_static</function>
|
||||
and <function>g_type_register_dynamic</function>.
|
||||
passed as the parent_type parameter to <function><link linkend="g-type-register-static">g_type_register_static</link></function>
|
||||
and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>.
|
||||
</para>
|
||||
|
||||
<sect1 id="gtype-copy">
|
||||
@ -117,17 +117,17 @@ GType g_type_register_fundamental (GType type_id,
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <type>GValue</type> structure is used as an abstract container for all of these
|
||||
The <type><link linkend="GValue">GValue</link></type> structure is used as an abstract container for all of these
|
||||
types. Its simplistic API (defined in <filename>gobject/gvalue.h</filename>) can be
|
||||
used to invoke the value_table functions registered
|
||||
during type registration: for example <function>g_value_copy</function> copies the
|
||||
content of a <type>GValue</type> to another <type>GValue</type>. This is similar
|
||||
during type registration: for example <function><link linkend="g-value-copy">g_value_copy</link></function> copies the
|
||||
content of a <type><link linkend="GValue">GValue</link></type> to another <type><link linkend="GValue">GValue</link></type>. This is similar
|
||||
to a C++ assignment which invokes the C++ copy operator to modify the default
|
||||
bit-by-bit copy semantics of C++/C structures/classes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following code shows how you can copy around a 64 bit integer, as well as a <type>GObject</type>
|
||||
The following code shows how you can copy around a 64 bit integer, as well as a <type><link linkend="GObject">GObject</link></type>
|
||||
instance pointer (sample code for this is located in the source tarball for this document in
|
||||
<filename>sample/gtype/test.c</filename>):
|
||||
<programlisting>
|
||||
@ -322,7 +322,7 @@ GType maman_bar_get_type (void)
|
||||
|
||||
<para>
|
||||
To register such a type in the type system, you just need to fill the
|
||||
<type>GTypeInfo</type> structure with zeros since these types are also most of the time
|
||||
<type><link linkend="GTypeInfo">GTypeInfo</link></type> structure with zeros since these types are also most of the time
|
||||
fundamental:
|
||||
<programlisting>
|
||||
GTypeInfo info = {
|
||||
@ -356,9 +356,9 @@ GType maman_bar_get_type (void)
|
||||
<para>
|
||||
Having non-instantiable types might seem a bit useless: what good is a type
|
||||
if you cannot instanciate an instance of that type ? Most of these types
|
||||
are used in conjunction with <type>GValue</type>s: a GValue is initialized
|
||||
are used in conjunction with <type><link linkend="GValue">GValue</link></type>s: a GValue is initialized
|
||||
with an integer or a string and it is passed around by using the registered
|
||||
type's value_table. <type>GValue</type>s (and by extension these trivial fundamental
|
||||
type's value_table. <type><link linkend="GValue">GValue</link></type>s (and by extension these trivial fundamental
|
||||
types) are most useful when used in conjunction with object properties and signals.
|
||||
</para>
|
||||
|
||||
@ -370,7 +370,7 @@ GType maman_bar_get_type (void)
|
||||
<para>
|
||||
Types which are registered with a class and are declared instantiable are
|
||||
what most closely resembles an <emphasis>object</emphasis>.
|
||||
Although <type>GObject</type>s (detailed in <xref linkend="chapter-gobject"/>)
|
||||
Although <type><link linkend="GObject">GObject</link></type>s (detailed in <xref linkend="chapter-gobject"/>)
|
||||
are the most well known type of instantiable
|
||||
classed types, other kinds of similar objects used as the base of an inheritance
|
||||
hierarchy have been externally developped and they are all built on the fundamental
|
||||
@ -428,8 +428,8 @@ maman_bar_get_type (void)
|
||||
<para>
|
||||
Every object must define two structures: its class structure and its
|
||||
instance structure. All class structures must contain as first member
|
||||
a <type>GTypeClass</type> structure. All instance structures must contain as first
|
||||
member a <type>GTypeInstance</type> structure. The declaration of these C types,
|
||||
a <type><link linkend="GTypeClass">GTypeClass</link></type> structure. All instance structures must contain as first
|
||||
member a <type><link linkend="GTypeInstance">GTypeInstance</link></type> structure. The declaration of these C types,
|
||||
coming from <filename>gtype.h</filename> is shown below:
|
||||
<programlisting>
|
||||
struct _GTypeClass
|
||||
@ -496,12 +496,12 @@ B *b;
|
||||
|
||||
<para>
|
||||
Instanciation of these types can be done with
|
||||
<function>g_type_create_instance</function>:
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
||||
<programlisting>
|
||||
GTypeInstance* g_type_create_instance (GType type);
|
||||
void g_type_free_instance (GTypeInstance *instance);
|
||||
</programlisting>
|
||||
<function>g_type_create_instance</function> will lookup the type information
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will lookup the type information
|
||||
structure associated to the type requested. Then, the instance size and instanciation
|
||||
policy (if the n_preallocs field is set to a non-zero value, the type system allocates
|
||||
the object's instance structures in chunks rather than mallocing for every instance)
|
||||
@ -514,9 +514,9 @@ void g_type_free_instance (GTypeInstance *instance);
|
||||
a class structure: it allocates a buffer to hold the object's class structure and
|
||||
initializes it. It first copies the parent's class structure over this structure
|
||||
(if there is no parent, it initializes it to zero). It then invokes the
|
||||
base_class_initialization functions (<type>GBaseInitFunc</type>) from topmost
|
||||
base_class_initialization functions (<type><link linkend="GBaseInitFunc">GBaseInitFunc</link></type>) from topmost
|
||||
fundamental object to bottom-most most derived object. The object's class_init
|
||||
(<type>GClassInitFunc</type>) function is invoked afterwards to complete
|
||||
(<type><link linkend="GClassInitFunc">GClassInitFunc</link></type>) function is invoked afterwards to complete
|
||||
initialization of the class structure.
|
||||
Finally, the object's interfaces are initialized (we will discuss interface initialization
|
||||
in more detail later).
|
||||
@ -531,12 +531,12 @@ The class initialization process is entirely implemented in
|
||||
<para>
|
||||
Once the type system has a pointer to an initialized class structure, it sets the object's
|
||||
instance class pointer to the object's class structure and invokes the object's
|
||||
instance_init (<type>GInstanceInitFunc</type>)functions, from top-most fundamental
|
||||
instance_init (<type><link linkend="GInstanceInitFunc">GInstanceInitFunc</link></type>)functions, from top-most fundamental
|
||||
type to bottom-most most derived type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Object instance destruction through <function>g_type_free_instance</function> is very simple:
|
||||
Object instance destruction through <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is very simple:
|
||||
the instance structure is returned to the instance pool if there is one and if this was the
|
||||
last living instance of the object, the class is destroyed.
|
||||
</para>
|
||||
@ -552,8 +552,8 @@ The class initialization process is entirely implemented in
|
||||
in Gtype) is the symmetric process of the initialization: interfaces are
|
||||
destroyed first.
|
||||
Then, the most derived
|
||||
class_finalize (<type>ClassFinalizeFunc</type>) function is invoked. The
|
||||
base_class_finalize (<type>GBaseFinalizeFunc</type>) functions are
|
||||
class_finalize (<type><link linkend="ClassFinalizeFunc">ClassFinalizeFunc</link></type>) function is invoked. The
|
||||
base_class_finalize (<type><link linkend="GBaseFinalizeFunc">GBaseFinalizeFunc</link></type>) functions are
|
||||
Finally invoked from bottom-most most-derived type to top-most fundamental type and
|
||||
the class structure is freed.
|
||||
</para>
|
||||
@ -597,39 +597,39 @@ The class initialization process is entirely implemented in
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>First call to <function>g_type_create_instance</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
|
||||
<entry>type's base_init function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
base_init is invoked once for each class structure.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_type_create_instance</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
|
||||
<entry>target type's class_init function</entry>
|
||||
<entry>On target type's class structure</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_type_create_instance</function> for target type</entry>
|
||||
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
|
||||
<entry colspan="2">interface initialization, see
|
||||
<xref linkend="gtype-non-instantiable-classed-init"/></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Each call to <function>g_type_create_instance</function> for target type</entry>
|
||||
<entry>Each call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
|
||||
<entry>target type's instance_init function</entry>
|
||||
<entry>On object's instance</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_type_free_instance</function> for target type</entry>
|
||||
<entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
|
||||
<entry colspan="2">interface destruction, see
|
||||
<xref linkend="gtype-non-instantiable-classed-dest"/></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_type_free_instance</function> for target type</entry>
|
||||
<entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
|
||||
<entry>target type's class_finalize function</entry>
|
||||
<entry>On target type's class structure</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_type_free_instance</function> for target type</entry>
|
||||
<entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
|
||||
<entry>type's base_finalize function</entry>
|
||||
<entry>On the inheritance tree of classes from fundamental type to target type.
|
||||
base_init is invoked once for each class structure.</entry>
|
||||
@ -647,7 +647,7 @@ The class initialization process is entirely implemented in
|
||||
<para>
|
||||
GType's Interfaces are very similar to Java's interfaces. To declare one of these
|
||||
you have to register a non-instantiable classed type which derives from
|
||||
<type>GTypeInterface</type>. The following piece of code declares such an interface.
|
||||
<type><link linkend="GTypeInterface">GTypeInterface</link></type>. The following piece of code declares such an interface.
|
||||
<programlisting>
|
||||
#define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ())
|
||||
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
|
||||
@ -684,7 +684,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
|
||||
|
||||
<para>
|
||||
An interface is defined by only one structure which must contain as first member
|
||||
a <type>GTypeInterface</type> structure. The interface structure is expected to
|
||||
a <type><link linkend="GTypeInterface">GTypeInterface</link></type> structure. The interface structure is expected to
|
||||
contain the function pointers of the interface methods. It is good style to
|
||||
define helper functions for each of the interface methods which simply call
|
||||
the interface' method directly: <function>maman_ibaz_do_action</function>
|
||||
@ -694,7 +694,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
|
||||
<para>
|
||||
Once an interface type is registered, you must register implementations for these
|
||||
interfaces. The function named <function>maman_baz_get_type</function> registers
|
||||
a new GType named MamanBaz which inherits from <type>GObject</type> and which
|
||||
a new GType named MamanBaz which inherits from <type><link linkend="GObject">GObject</link></type> and which
|
||||
implements the interface <type>MamanIBaz</type>.
|
||||
<programlisting>
|
||||
static void maman_baz_do_action (MamanIbaz *self)
|
||||
@ -745,10 +745,11 @@ maman_baz_get_type (void)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>g_type_add_interface_static</function> records in the type system that
|
||||
<function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> records in the type system that
|
||||
a given type implements also <type>FooInterface</type>
|
||||
(<function>foo_interface_get_type</function> returns the type of
|
||||
<type>FooInterface</type>). The <type>GInterfaceInfo</type> structure holds
|
||||
<type>FooInterface</type>).
|
||||
The <type><link linkend="GInterfaceInfo">GInterfaceInfo</link></type> structure holds
|
||||
information about the implementation of the interface:
|
||||
<programlisting>
|
||||
struct _GInterfaceInfo
|
||||
@ -819,7 +820,7 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
<para>
|
||||
The above process can be summarized as follows:
|
||||
<table>
|
||||
<title><function>Interface Initialization</function></title>
|
||||
<title>Interface Initialization</title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="*" colnum="1" align="left"/>
|
||||
<colspec colwidth="*" colnum="2" align="left"/>
|
||||
@ -835,7 +836,7 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>First call to <function>g_type_create_instance</function> for type
|
||||
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
|
||||
implementing interface</entry>
|
||||
<entry>interface' base_init function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
@ -844,7 +845,7 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
twice.).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>First call to <function>g_type_create_instance</function> for type
|
||||
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
|
||||
implementing interface</entry>
|
||||
<entry>interface' interface_init function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
@ -891,7 +892,7 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
<para>
|
||||
The above process can be summarized as follows:
|
||||
<table>
|
||||
<title><function>Interface Finalization</function></title>
|
||||
<title>Interface Finalization</title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="*" colnum="1" align="left"/>
|
||||
<colspec colwidth="*" colnum="2" align="left"/>
|
||||
@ -906,13 +907,13 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>Last call to <function>g_type_free_instance</function> for type
|
||||
<entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for type
|
||||
implementing interface</entry>
|
||||
<entry>interface' interface_finalize function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Last call to <function>g_type_free_instance</function>for type
|
||||
<entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function>for type
|
||||
implementing interface</entry>
|
||||
<entry>interface' base_finalize function</entry>
|
||||
<entry>On interface' vtable</entry>
|
||||
|
@ -1,17 +1,16 @@
|
||||
<chapter id="howto">
|
||||
<title>How To ?</title>
|
||||
|
||||
<partintro>
|
||||
<para>
|
||||
This chapter tries to answer the real-life questions of users and presents
|
||||
the most common scenario use-cases I could come up with.
|
||||
The use-cases are presented from most likely to less likely.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
<!--
|
||||
Howto GObject
|
||||
-->
|
||||
|
||||
<sect1 id="howto-gobject">
|
||||
<chapter id="howto-gobject">
|
||||
<title>How To define and implement a new GObject ?</title>
|
||||
|
||||
<para>
|
||||
@ -23,13 +22,13 @@
|
||||
<filename>sample/gobject</filename> directory:
|
||||
<itemizedlist>
|
||||
<listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from
|
||||
<type>GObject</type> and which shows how to declare different types of methods on the object.
|
||||
<type><link linkend="GObject">GObject</link></type> and which shows how to declare different types of methods on the object.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>maman-subbar.{h|c}</filename>: this is the source for a object which derives from
|
||||
<type>MamanBar</type> and which shows how to override some of its parent's methods.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>maman-foo.{h|c}</filename>: this is the source for an object which derives from
|
||||
<type>GObject</type> and which declares a signal.
|
||||
<type><link linkend="GObject">GObject</link></type> and which declares a signal.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>test.c</filename>: this is the main source which instantiates an instance of
|
||||
type and exercises their API.
|
||||
@ -37,7 +36,7 @@
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<sect2 id="howto-gobject-header">
|
||||
<sect1 id="howto-gobject-header">
|
||||
<title>Boilerplate header code</title>
|
||||
|
||||
<para>
|
||||
@ -186,7 +185,7 @@ static void maman_bar_init(GTypeInstance *instance, gpointer g_class) {
|
||||
<listitem><para>
|
||||
A similar alternative, available since Glib version 2.4, is to define a private structure in the .c file,
|
||||
declare it as a private structure in <function>class_init</function> using
|
||||
<function>g_type_class_add_private</function> and declare a macro to allow convenient access to this structure.
|
||||
<function><link linkend="g-type-class-add-private">g_type_class_add_private</link></function> and declare a macro to allow convenient access to this structure.
|
||||
A private structure will then be attached to each newly created object by the GObject system.
|
||||
You dont need to free or allocate the private structure, only the objects or pointers that it may contain.
|
||||
<programlisting>
|
||||
@ -238,9 +237,9 @@ maman_bar_get_private_field (MamanBar *self)
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-gobject-code">
|
||||
<sect1 id="howto-gobject-code">
|
||||
<title>Boilerplate code</title>
|
||||
|
||||
<para>
|
||||
@ -297,9 +296,9 @@ maman_bar_get_type (void)
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-gobject-construction">
|
||||
<sect1 id="howto-gobject-construction">
|
||||
<title>Object Construction</title>
|
||||
|
||||
<para>
|
||||
@ -320,7 +319,7 @@ maman_bar_get_type (void)
|
||||
|
||||
<para>
|
||||
Construction properties will be set only after all instance_init functions have run.
|
||||
No object reference will be returned to the client of <function>g_object_new></function>
|
||||
No object reference will be returned to the client of <function><link linkend="g-object-new>">g_object_new></link></function>
|
||||
until all the construction properties have been set.
|
||||
</para>
|
||||
|
||||
@ -343,14 +342,14 @@ maman_bar_init (GTypeInstance *instance,
|
||||
And make sure that you set <function>maman_bar_init</function> as the type's instance_init function
|
||||
in <function>maman_bar_get_type</function>. Make sure the code builds and runs: create an instance
|
||||
of the object and make sure <function>maman_bar_init</function> is called (add a
|
||||
<function>g_print</function> call in it).
|
||||
<function><link linkend="g-print">g_print</link></function> call in it).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Now, if you need special construction properties, install the properties in the class_init function,
|
||||
override the set and get methods and implement the get and set methods as described in
|
||||
<xref linkend="gobject-properties"/>. Make sure that these properties use a construct only
|
||||
<type>GParamSpec</type> by setting the param spec's flag field to G_PARAM_CONSTRUCT_ONLY: this helps
|
||||
<type><link linkend="GParamSpec">GParamSpec</link></type> by setting the param spec's flag field to G_PARAM_CONSTRUCT_ONLY: this helps
|
||||
GType ensure that these properties are not set again later by malicious user code.
|
||||
<programlisting>
|
||||
static void
|
||||
@ -375,7 +374,7 @@ bar_class_init (MamanBarClass *klass)
|
||||
</programlisting>
|
||||
If you need this, make sure you can build and run code similar to the code shown above. Make sure
|
||||
your construct properties can set correctly during construction, make sure you cannot set them
|
||||
afterwards and make sure that if your users do not call <function>g_object_new</function>
|
||||
afterwards and make sure that if your users do not call <function><link linkend="g-object-new">g_object_new</link></function>
|
||||
with the required construction properties, these will be initialized with the default values.
|
||||
</para>
|
||||
|
||||
@ -392,14 +391,14 @@ bar_class_init (MamanBarClass *klass)
|
||||
use of this feature. As such, to initialize your object instances, use by default the base_init function
|
||||
and construction properties.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-gobject-destruction">
|
||||
<sect1 id="howto-gobject-destruction">
|
||||
<title>Object Destruction</title>
|
||||
|
||||
<para>
|
||||
Again, it is often difficult to figure out which mechanism to use to hook into the object's
|
||||
destruction process: when the last <function>g_object_unref</function> function call is made,
|
||||
destruction process: when the last <function><link linkend="g-object-unref">g_object_unref</link></function> function call is made,
|
||||
a lot of things happen as described in <xref linkend="gobject-destruction-table"/>.
|
||||
</para>
|
||||
|
||||
@ -487,9 +486,9 @@ if (self->private->dispose_has_run) {
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-gobject-methods">
|
||||
<sect1 id="howto-gobject-methods">
|
||||
<title>Object methods</title>
|
||||
|
||||
<para>
|
||||
@ -511,7 +510,7 @@ if (self->private->dispose_has_run) {
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<sect2>
|
||||
<title>Non-virtual public methods</title>
|
||||
|
||||
<para>
|
||||
@ -530,9 +529,9 @@ void maman_bar_do_action (MamanBar *self, /* parameters */)
|
||||
</para>
|
||||
|
||||
<para>There is really nothing scary about this.</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect3>
|
||||
<sect2>
|
||||
<title>Virtual public methods</title>
|
||||
|
||||
<para>
|
||||
@ -606,9 +605,9 @@ void maman_bar_do_action_two (MamanBar *self, /* parameters */)
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect3>
|
||||
<sect2>
|
||||
<title>Virtual private Methods</title>
|
||||
|
||||
<para>
|
||||
@ -674,10 +673,10 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-gobject-chainup">
|
||||
<sect1 id="howto-gobject-chainup">
|
||||
<title>Chaining up</title>
|
||||
|
||||
<para>Chaining up is often loosely defined by the following set of conditions:
|
||||
@ -720,7 +719,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||
</footnote>
|
||||
</para>
|
||||
|
||||
<para>The function <function>g_type_class_peek_parent</function> is used to access the original parent
|
||||
<para>The function <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> is used to access the original parent
|
||||
class structure. Its input is a pointer to the class of the derived object and it returns a pointer
|
||||
to the original parent class structure. The code below shows how you could use it:
|
||||
<programlisting>
|
||||
@ -738,14 +737,14 @@ b_method_to_call (B *obj, int a)
|
||||
}
|
||||
</programlisting>
|
||||
A lot of people who use this idiom in GTK+ store the parent class structure pointer in a global static
|
||||
variable to avoid the costly call to <function>g_type_class_peek_parent</function> for each function call.
|
||||
variable to avoid the costly call to <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> for each function call.
|
||||
Typically, the class_init callback initializes the global static variable. <filename>gtk/gtkhscale.c</filename>
|
||||
does this.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
End Howto GObject
|
||||
@ -756,10 +755,10 @@ b_method_to_call (B *obj, int a)
|
||||
Howto Interfaces
|
||||
-->
|
||||
|
||||
<sect1 id="howto-interface">
|
||||
<chapter id="howto-interface">
|
||||
<title>How To define and implement Interfaces ?</title>
|
||||
|
||||
<sect2 id="howto-interface-define">
|
||||
<sect1 id="howto-interface-define">
|
||||
<title>How To define Interfaces ?</title>
|
||||
|
||||
<para>
|
||||
@ -800,8 +799,8 @@ void maman_ibaz_do_action (MamanIbaz *self);
|
||||
|
||||
#endif /*MAMAN_IBAZ_H*/
|
||||
</programlisting>
|
||||
This code is almost exactly similar to the code for a normal <type>GType</type>
|
||||
which derives from a <type>GObject</type> except for a few details:
|
||||
This code is almost exactly similar to the code for a normal <type><link linkend="GType">GType</link></type>
|
||||
which derives from a <type><link linkend="GObject">GObject</link></type> except for a few details:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
The <function>_GET_CLASS</function> macro is not implemented with
|
||||
@ -870,9 +869,9 @@ void maman_ibaz_do_action (MamanIbaz *self)
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-interface-implement">
|
||||
<sect1 id="howto-interface-implement">
|
||||
<title>How To define and implement an implementation of an Interface ?</title>
|
||||
|
||||
<para>
|
||||
@ -954,8 +953,8 @@ maman_baz_get_type (void)
|
||||
}
|
||||
</programlisting>
|
||||
This function is very much like all the similar functions we looked at previously. The only interface-specific
|
||||
code present here is the call to <function>g_type_add_interface_static</function> which is used to inform
|
||||
the type system that this just-registered <type>GType</type> also implements the interface
|
||||
code present here is the call to <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> which is used to inform
|
||||
the type system that this just-registered <type><link linkend="GType">GType</link></type> also implements the interface
|
||||
<function>MAMAN_TYPE_IBAZ</function>.
|
||||
</para>
|
||||
|
||||
@ -986,9 +985,9 @@ baz_instance_init (GTypeInstance *instance,
|
||||
but it could :)
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2>
|
||||
<sect1>
|
||||
<title>Interface definition prerequisites</title>
|
||||
|
||||
<para>To specify that an interface requires the presence of other interfaces when implemented,
|
||||
@ -1085,7 +1084,7 @@ maman_bar_get_type (void)
|
||||
}
|
||||
</programlisting>
|
||||
It is very important to notice that the order in which interface implementations are added to the main object
|
||||
is not random: <function>g_type_interface_static</function> must be invoked first on the interfaces which have
|
||||
is not random: <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> must be invoked first on the interfaces which have
|
||||
no prerequisites and then on the others.
|
||||
</para>
|
||||
|
||||
@ -1095,16 +1094,16 @@ maman_bar_get_type (void)
|
||||
and <filename>sample/interface/maman-bar.{h|c}</filename>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect2 id="howto-interface-properties">
|
||||
<sect1 id="howto-interface-properties">
|
||||
<title>Interface Properties</title>
|
||||
|
||||
<para>Starting from version 2.4 of glib, gobject interfaces can also have properties.
|
||||
Declaration of the interface properties is similar to declaring the properties of
|
||||
ordinary gobject types as explained in <xref linkend="gobject-properties"/>,
|
||||
except that <function>g_object_interface_install_property</function> is used to
|
||||
declare the properties instead of <function>g_object_class_install_property</function>.
|
||||
except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
|
||||
declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
|
||||
</para>
|
||||
|
||||
<para>To include a property named 'name' of type <type>string</type> in the
|
||||
@ -1150,8 +1149,8 @@ maman_ibaz_base_init (gpointer g_class)
|
||||
An implementer shall declare and define it's properties in the usual way as
|
||||
explained in <xref linkend="gobject-properties"/>, except for one small
|
||||
change: it shall declare the properties of the interface it implements using
|
||||
<function>g_object_class_override_property</function> instead of
|
||||
<function>g_object_class_install_property</function>. The following code snipet
|
||||
<function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function> instead of
|
||||
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. The following code snipet
|
||||
shows the modifications needed in the <type>MamanBaz</type> declaration and
|
||||
implementation above:
|
||||
<programlisting>
|
||||
@ -1260,10 +1259,10 @@ maman_baz_get_property (GObject * object, guint prop_id,
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
End Howto Interfaces
|
||||
@ -1275,7 +1274,7 @@ maman_baz_get_property (GObject * object, guint prop_id,
|
||||
-->
|
||||
|
||||
|
||||
<sect1 id="howto-signals">
|
||||
<chapter id="howto-signals">
|
||||
<title>Howto create and use signals</title>
|
||||
|
||||
|
||||
@ -1292,7 +1291,7 @@ maman_baz_get_property (GObject * object, guint prop_id,
|
||||
just emit events which can be received by numerous clients.
|
||||
</para>
|
||||
|
||||
<sect2 id="howto-simple-signals">
|
||||
<sect1 id="howto-simple-signals">
|
||||
<title>Simple use of signals</title>
|
||||
|
||||
<para>The most basic use of signals is to implement simple event notification: for example, if we have a
|
||||
@ -1352,10 +1351,10 @@ The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
|
||||
needed closures that one can use.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect2>
|
||||
<sect1>
|
||||
<title>How to provide more flexibility to users ?</title>
|
||||
|
||||
<para>The previous implementation does the job but the signal facility of GObject can be used to provide
|
||||
@ -1440,8 +1439,8 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
||||
|
||||
<para>The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before
|
||||
and after the file write is completed: since the default signal handler which does the write itself runs during the
|
||||
RUN_LAST phase of the signal emission, it will run after all handlers connected with <function>g_signal_connect</function>
|
||||
and before all handlers connected with <function>g_signal_connect_after</function>. If you intent to write a GObject
|
||||
RUN_LAST phase of the signal emission, it will run after all handlers connected with <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
||||
and before all handlers connected with <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function>. If you intent to write a GObject
|
||||
which emits signals, I would thus urge you to create all your signals with the G_SIGNAL_RUN_LAST such that your users
|
||||
have a maximum of flexibility as to when to get the event. Here, we combined it with G_SIGNAL_NO_RECURSE and
|
||||
G_SIGNAL_NO_HOOKS to ensure our users will not try to do really weird things with our GObject. I strongly advise you
|
||||
@ -1492,7 +1491,7 @@ Complex Write event after: 0xbfffe280, 50
|
||||
</para>
|
||||
|
||||
|
||||
<sect3>
|
||||
<sect2>
|
||||
<title>How most people do the same thing with less code</title>
|
||||
|
||||
<para>For many historic reasons related to how the ancestor of GObject used to work in GTK+ 1.x versions,
|
||||
@ -1510,13 +1509,13 @@ Complex Write event after: 0xbfffe280, 50
|
||||
</para>
|
||||
</footnote>
|
||||
way to create a signal with a default handler than to create
|
||||
a closure by hand and to use the <function>g_signal_newv</function>.
|
||||
a closure by hand and to use the <function><link linkend="g-signal-newv">g_signal_newv</link></function>.
|
||||
</para>
|
||||
|
||||
<para>For example, <function>g_signal_new</function> can be used to create a signal which uses a default
|
||||
<para>For example, <function><link linkend="g-signal-new">g_signal_new</link></function> can be used to create a signal which uses a default
|
||||
handler which is stored in the class structure of the object. More specifically, the class structure
|
||||
contains a function pointer which is accessed during signal emission to invoke the default handler and
|
||||
the user is expected to provide to <function>g_signal_new</function> the offset from the start of the
|
||||
the user is expected to provide to <function><link linkend="g-signal-new">g_signal_new</link></function> the offset from the start of the
|
||||
class structure to the function pointer.
|
||||
<footnote>
|
||||
<para>I would like to point out here that the reason why the default handler of a signal is named everywhere
|
||||
@ -1550,7 +1549,7 @@ maman_file_simple_class_init (gpointer g_class,
|
||||
|
||||
klass->write = default_write_signal_handler;
|
||||
</programlisting>
|
||||
Finally, the signal is created with <function>g_signal_new</function> in the same class_init function:
|
||||
Finally, the signal is created with <function><link linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
|
||||
<programlisting>
|
||||
klass->write_signal_id =
|
||||
g_signal_new ("write",
|
||||
@ -1565,7 +1564,7 @@ klass->write_signal_id =
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_UINT);
|
||||
</programlisting>
|
||||
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function>G_STRUCT_OFFSET</function>
|
||||
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
|
||||
macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the
|
||||
<type>MamanFileSimpleClass</type> class structure.
|
||||
<footnote>
|
||||
@ -1586,24 +1585,24 @@ klass->write_signal_id =
|
||||
</para>
|
||||
|
||||
<para>If you have doubts about which method to use, I would advise you to use the second one which
|
||||
involves <function>g_signal_new</function> rather than <function>g_signal_newv</function>:
|
||||
involves <function><link linkend="g-signal-new">g_signal_new</link></function> rather than <function><link linkend="g-signal-newv">g_signal_newv</link></function>:
|
||||
it is better to write code which looks like the vast majority of other GTK+/Gobject code than to
|
||||
do it your own way. However, now, you know why.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
|
||||
<sect2>
|
||||
<sect1>
|
||||
<title>How users can abuse signals (and why some think it is good)</title>
|
||||
|
||||
<para>Now that you know how to create signals to which the users can connect easily and at any point in
|
||||
the signal emission process thanks to <function>g_signal_connect</function>,
|
||||
<function>g_signal_connect_after</function> and G_SIGNAL_RUN_LAST, it is time to look into how your
|
||||
the signal emission process thanks to <function><link linkend="g-signal-connect">g_signal_connect</link></function>,
|
||||
<function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function> and G_SIGNAL_RUN_LAST, it is time to look into how your
|
||||
users can and will screw you. This is also interesting to know how you too, can screw other people.
|
||||
This will make you feel good and eleet.
|
||||
</para>
|
||||
@ -1625,7 +1624,7 @@ klass->write_signal_id =
|
||||
</para>
|
||||
|
||||
<para>If all you want to do is to stop the signal emission from one of the callbacks you connected yourself,
|
||||
you can call <function>g_signal_stop_by_name</function>. Its use is very simple which is why I won't detail
|
||||
you can call <function><link linkend="g-signal-stop-by-name">g_signal_stop_by_name</link></function>. Its use is very simple which is why I won't detail
|
||||
it further.
|
||||
</para>
|
||||
|
||||
@ -1640,12 +1639,12 @@ klass->write_signal_id =
|
||||
which is why I won't bother to show exactly how to do it here again.</para>
|
||||
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!--
|
||||
<sect3>
|
||||
<sect2>
|
||||
<title>Warning on signal creation and default closure</title>
|
||||
|
||||
<para>
|
||||
@ -1655,10 +1654,10 @@ klass->write_signal_id =
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Usually, the <function>g_signal_new</function> function is preferred over
|
||||
<function>g_signal_newv</function>. When <function>g_signal_new</function>
|
||||
Usually, the <function><link linkend="g-signal-new">g_signal_new</link></function> function is preferred over
|
||||
<function><link linkend="g-signal-newv">g_signal_newv</link></function>. When <function><link linkend="g-signal-new">g_signal_new</link></function>
|
||||
is used, the default closure is exported as a class function. For example,
|
||||
<filename>gobject.h</filename> contains the declaration of <type>GObjectClass</type>
|
||||
<filename>gobject.h</filename> contains the declaration of <type><link linkend="GObjectClass">GObjectClass</link></type>
|
||||
whose notify class function is the default handler for the <emphasis>notify</emphasis>
|
||||
signal:
|
||||
<programlisting>
|
||||
@ -1676,7 +1675,7 @@ struct _GObjectClass
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<filename>gobject.c</filename>'s <function>g_object_do_class_init</function> function
|
||||
<filename>gobject.c</filename>'s <function><link linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
|
||||
registers the <emphasis>notify</emphasis> signal and initializes this class function
|
||||
to NULL:
|
||||
<programlisting>
|
||||
@ -1699,7 +1698,7 @@ g_object_do_class_init (GObjectClass *class)
|
||||
1, G_TYPE_PARAM);
|
||||
}
|
||||
</programlisting>
|
||||
<function>g_signal_new</function> creates a <type>GClosure</type> which de-references the
|
||||
<function><link linkend="g-signal-new">g_signal_new</link></function> creates a <type><link linkend="GClosure">GClosure</link></type> which de-references the
|
||||
type's class structure to access the class function pointer and invoke it if it not NULL. The
|
||||
class function is ignored it is set to NULL.
|
||||
</para>
|
||||
@ -1721,20 +1720,13 @@ g_object_do_class_init (GObjectClass *class)
|
||||
supposedly more efficient.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
</sect2>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<sect1 id="howto-doc">
|
||||
<capter1 id="howto-doc">
|
||||
<title>How to generate API documentation for your type ?</title>
|
||||
|
||||
</sect1>
|
||||
-->
|
||||
|
||||
</chapter>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-->
|
||||
|
@ -1,5 +1,5 @@
|
||||
<chapter>
|
||||
<title>Introduction</title>
|
||||
<title>Background</title>
|
||||
|
||||
<para>
|
||||
GObject, and its lower-level type system, GType, are used by GTK+ and most Gnome libraries to
|
||||
@ -18,7 +18,7 @@ the solution choosen by GLib.
|
||||
</para>
|
||||
|
||||
<para>The following chapters go into greater detail into how GType and GObject work and
|
||||
how you can use them as a C programmer. I personally find it useful to keep in mind that
|
||||
how you can use them as a C programmer. It is useful to keep in mind that
|
||||
allowing access to C objects from other interpreted languages was one of the major design
|
||||
goals: this can often explain the sometimes rather convoluted APIs and features present
|
||||
in this library.
|
||||
|
@ -1,35 +1,55 @@
|
||||
<chapter id="tools">
|
||||
<title>GObject related tools</title>
|
||||
<partintro>
|
||||
<para>
|
||||
Several useful developer tools have been build around GObject technology.
|
||||
Next sections briefly introduce them and link to the respective project pages.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
<sect1 id="tools-refdb">
|
||||
<title>Debugging reference count problems</title>
|
||||
|
||||
<para>
|
||||
The reference counting scheme used by GObject does solve quite
|
||||
a few memory management problems but also introduces new sources of bugs.
|
||||
In large applications, finding the exact spot where a the reference count
|
||||
of an Object is not properly handled can be very difficult. Hopefully,
|
||||
there exist at a too named <ulink url="http://refdbg.sf.net/">refdbg/</ulink>
|
||||
which can be used to automate the task of tracking down the location
|
||||
of invalid code with regard to reference counting. This application
|
||||
intercepts the reference counting calls and tries to detect invalid behavior.
|
||||
It suports a filter-rule mechanism to let you trace only the objects you are
|
||||
interested in and it can be used together with gdb.
|
||||
</para>
|
||||
</sect1>
|
||||
<chapter id="tools-gob">
|
||||
<title>GObject builder</title>
|
||||
|
||||
<para>
|
||||
Writing gobjects can be a tedious task. It requires a lot of typing and just
|
||||
doing copy and paste needs care. On obvious idea is to use some sort of
|
||||
templates for the class skelletons. Then a tool could generate the real c
|
||||
files from them.
|
||||
<ulink url="http://www.5z.com/jirka/gob.html">GOB/</ulink> (or GOB2) is suc
|
||||
h a tool. It is a preprocessor for making GObjects with inline C code so
|
||||
that generated files are not edited.
|
||||
Syntax is inspired by Java and Yacc or Lex. The implementation is
|
||||
intentionally kept simple, and no C actual code parsing is done.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="tools-refdb">
|
||||
<title>Debugging reference count problems</title>
|
||||
|
||||
<para>
|
||||
The reference counting scheme used by GObject does solve quite
|
||||
a few memory management problems but also introduces new sources of bugs.
|
||||
In large applications, finding the exact spot where a the reference count
|
||||
of an Object is not properly handled can be very difficult. Hopefully,
|
||||
there exist at a too named <ulink url="http://refdbg.sf.net/">refdbg/</ulink>
|
||||
which can be used to automate the task of tracking down the location
|
||||
of invalid code with regard to reference counting. This application
|
||||
intercepts the reference counting calls and tries to detect invalid behavior.
|
||||
It suports a filter-rule mechanism to let you trace only the objects you are
|
||||
interested in and it can be used together with gdb.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<sect1 id="tools-gtkdoc">
|
||||
<title>Writing API docs</title>
|
||||
<chapter id="tools-gtkdoc">
|
||||
<title>Writing API docs</title>
|
||||
|
||||
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME
|
||||
libraries is built with a combination of complex tools. Typically, the part of
|
||||
the documentation which describes the behavior of each function is extracted
|
||||
from the specially-formatted source code comments by a tool named gtk-doc which
|
||||
generates docbook xml and merges this docbook xml with a set of master xml
|
||||
docbook files. These xml docbook files are finally processed with xsltproc
|
||||
(a small program part of the libxslt library) to generate the final html
|
||||
output. Other tools can be used to generate pdf output from the source xml.
|
||||
The following code excerpt shows what these comments look like.
|
||||
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME
|
||||
libraries is built with a combination of complex tools. Typically, the part of
|
||||
the documentation which describes the behavior of each function is extracted
|
||||
from the specially-formatted source code comments by a tool named gtk-doc which
|
||||
generates docbook xml and merges this docbook xml with a set of master xml
|
||||
docbook files. These xml docbook files are finally processed with xsltproc
|
||||
(a small program part of the libxslt library) to generate the final html
|
||||
output. Other tools can be used to generate pdf output from the source xml.
|
||||
The following code excerpt shows what these comments look like.
|
||||
<programlisting>
|
||||
/**
|
||||
* gtk_widget_freeze_child_notify:
|
||||
@ -45,14 +65,12 @@ gtk_widget_freeze_child_notify (GtkWidget *widget)
|
||||
{
|
||||
...
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The great thoroughful
|
||||
<ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink>
|
||||
on how to setup and use gtk-doc in your
|
||||
project is provided on the gnome developer website.
|
||||
gtk-doc generates
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</para>
|
||||
<para>
|
||||
The great thoroughful
|
||||
<ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink>
|
||||
on how to setup and use gtk-doc in your
|
||||
project is provided on the gnome developer website.
|
||||
gtk-doc generates
|
||||
</para>
|
||||
</chapter>
|
||||
|
Loading…
Reference in New Issue
Block a user