mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-08 13:50:07 +02:00
Format XML to be more editable. Describe Interfaces better. Add a footnote
* gobject/tut_gobject.xml: * gobject/tut_gsignal.xml: * gobject/tut_gtype.xml: * gobject/tut_howto.xml: * gobject/tut_intro.xml: * gobject/tut_tools.xml: Format XML to be more editable. Describe Interfaces better. Add a footnote at first occurance of 'maman_'. svn path=/trunk/; revision=5334
This commit is contained in:
parent
bdca945da3
commit
8ec7d6ca3f
@ -1,3 +1,14 @@
|
|||||||
|
2007-02-11 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
|
* gobject/tut_gobject.xml:
|
||||||
|
* gobject/tut_gsignal.xml:
|
||||||
|
* gobject/tut_gtype.xml:
|
||||||
|
* gobject/tut_howto.xml:
|
||||||
|
* gobject/tut_intro.xml:
|
||||||
|
* gobject/tut_tools.xml:
|
||||||
|
Format XML to be more editable. Describe Interfaces better. Add a
|
||||||
|
footnote at first occurance of 'maman_'.
|
||||||
|
|
||||||
2007-02-08 Stefan Kost <ensonic@users.sf.net>
|
2007-02-08 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* gobject/tut_gobject.xml:
|
* gobject/tut_gobject.xml:
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?xml version='1.0' encoding="ISO-8859-1"?>
|
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
<chapter id="chapter-gobject">
|
<chapter id="chapter-gobject">
|
||||||
<title>The GObject base class</title>
|
<title>The GObject base class</title>
|
||||||
|
|
||||||
@ -541,7 +540,6 @@ maman_bar_instance_init (GTypeInstance *instance,
|
|||||||
MamanBar *self = (MamanBar *)instance;
|
MamanBar *self = (MamanBar *)instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maman_bar_set_property (GObject *object,
|
maman_bar_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
@ -721,7 +719,6 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
|||||||
<sect2 id="gobject-multi-properties">
|
<sect2 id="gobject-multi-properties">
|
||||||
<title>Accessing multiple properties at once</title>
|
<title>Accessing multiple properties at once</title>
|
||||||
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
|
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
|
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
|
||||||
@ -765,7 +762,6 @@ g_object_set (G_OBJECT (foo),
|
|||||||
|
|
||||||
<!-- @todo tell here about how to pass use handle properties in derived classe -->
|
<!-- @todo tell here about how to pass use handle properties in derived classe -->
|
||||||
|
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -48,8 +48,8 @@ return_type function_callback (... , gpointer user_data);
|
|||||||
<listitem><para>
|
<listitem><para>
|
||||||
Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></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
|
were created for: they hide the details of callback invocation from the
|
||||||
callback invocator.
|
callback invocator.</para>
|
||||||
</para></listitem>
|
</listitem>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Notification: the closure notifies listeners of certain events such as
|
Notification: the closure notifies listeners of certain events such as
|
||||||
closure invocation, closure invalidation and closure finalization. Listeners
|
closure invocation, closure invalidation and closure finalization. Listeners
|
||||||
@ -64,8 +64,8 @@ return_type function_callback (... , gpointer user_data);
|
|||||||
<footnote><para>
|
<footnote><para>
|
||||||
Closures are refcounted and notify listeners of their destruction in a two-stage
|
Closures are refcounted and notify listeners of their destruction in a two-stage
|
||||||
process: the invalidation notifiers are invoked before the finalization notifiers.
|
process: the invalidation notifiers are invoked before the finalization notifiers.
|
||||||
</para></footnote>
|
</para></footnote></para>
|
||||||
</para></listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -299,9 +299,6 @@ guint g_signal_newv (const gchar *signal_name,
|
|||||||
and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
|
and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="signal-emission">
|
<sect2 id="signal-emission">
|
||||||
@ -501,7 +498,8 @@ void g_signal_emit_by_name (gpointer instance,
|
|||||||
(even though they are connected to a signal which is being emitted).
|
(even though they are connected to a signal which is being emitted).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>This completely optional filtering mechanism is mainly used as an optimization for signals
|
<para>
|
||||||
|
This completely optional filtering mechanism is mainly used as an optimization for signals
|
||||||
which are often emitted for many different reasons: the clients can filter out which events they are
|
which are often emitted for many different reasons: the clients can filter out which events they are
|
||||||
interested into before the closure's marshalling code runs. For example, this is used extensively
|
interested into before the closure's marshalling code runs. For example, this is used extensively
|
||||||
by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
|
by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
|
||||||
@ -510,7 +508,8 @@ void g_signal_emit_by_name (gpointer instance,
|
|||||||
to only one property to filter most events before receiving them.
|
to only one property to filter most events before receiving them.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>As a simple rule, users can and should set the detail parameter to zero: this will disable completely
|
<para>
|
||||||
|
As a simple rule, users can and should set the detail parameter to zero: this will disable completely
|
||||||
this optional filtering.
|
this optional filtering.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -518,3 +517,4 @@ void g_signal_emit_by_name (gpointer instance,
|
|||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding="ISO-8859-1"?>
|
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||||
<chapter>
|
<chapter id="chapter-gtype">
|
||||||
<title>The Glib Dynamic Type System</title>
|
<title>The Glib Dynamic Type System</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -236,6 +236,13 @@ struct _GTypeValueTable
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>Use prefixing to avoid namespace conflicts with other projects.
|
<listitem><para>Use prefixing to avoid namespace conflicts with other projects.
|
||||||
If your library (or application) is named <emphasis>Maman</emphasis>,
|
If your library (or application) is named <emphasis>Maman</emphasis>,
|
||||||
|
<footnote>
|
||||||
|
<para>
|
||||||
|
<emphasis>Maman</emphasis> is the french word for <emphasis>mum</emphasis>
|
||||||
|
or <emphasis>mother</emphasis> - nothing more and nothing less.
|
||||||
|
</para>
|
||||||
|
</footnote>
|
||||||
|
|
||||||
prefix all your function names with <emphasis>maman_</emphasis>.
|
prefix all your function names with <emphasis>maman_</emphasis>.
|
||||||
For example: <function>maman_object_method</function>.
|
For example: <function>maman_object_method</function>.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
@ -496,6 +503,9 @@ B *b;
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<sect2 id="gtype-instantiable-classed-init-done">
|
||||||
|
<title>Initialization and Destruction</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Instanciation of these types can be done with
|
Instanciation of these types can be done with
|
||||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
||||||
@ -543,6 +553,7 @@ The class initialization process is entirely implemented in
|
|||||||
last living instance of the object, the class is destroyed.
|
last living instance of the object, the class is destroyed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Class destruction
|
Class destruction
|
||||||
<footnote>
|
<footnote>
|
||||||
@ -642,6 +653,8 @@ The class initialization process is entirely implemented in
|
|||||||
</table>
|
</table>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="gtype-non-instantiable-classed">
|
<sect1 id="gtype-non-instantiable-classed">
|
||||||
@ -650,6 +663,9 @@ The class initialization process is entirely implemented in
|
|||||||
<para>
|
<para>
|
||||||
GType's Interfaces are very similar to Java's interfaces. They allow
|
GType's Interfaces are very similar to Java's interfaces. They allow
|
||||||
to describe a common API that several classes will adhere to.
|
to describe a common API that several classes will adhere to.
|
||||||
|
Imagine the play, pause and stop buttons on hifi equipment - those can
|
||||||
|
be seen as a playback interface. Once you know what the do, you can
|
||||||
|
control your cd-player, mp3-player or anything that uses these symbols.
|
||||||
To declare an interfacce you have to register a non-instantiable
|
To declare an interfacce you have to register a non-instantiable
|
||||||
classed type which derives from
|
classed type which derives from
|
||||||
<type><link linkend="GTypeInterface">GTypeInterface</link></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.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
This chapter tries to answer the real-life questions of users and presents
|
This chapter tries to answer the real-life questions of users and presents
|
||||||
@ -6,10 +7,6 @@
|
|||||||
</para>
|
</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
|
|
||||||
<!--
|
|
||||||
Howto GObject
|
|
||||||
-->
|
|
||||||
|
|
||||||
<chapter id="howto-gobject">
|
<chapter id="howto-gobject">
|
||||||
<title>How To define and implement a new GObject?</title>
|
<title>How To define and implement a new GObject?</title>
|
||||||
|
|
||||||
@ -701,11 +698,13 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
|||||||
programming idiom is often used, this section attemps to explain how to implement it.
|
programming idiom is often used, this section attemps to explain how to implement it.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>To explicitely chain up to the implementation of the virtual method in the parent class,
|
<para>
|
||||||
|
To explicitely chain up to the implementation of the virtual method in the parent class,
|
||||||
you first need a handle to the original parent class structure. This pointer can then be used to
|
you first need a handle to the original parent class structure. This pointer can then be used to
|
||||||
access the original class function pointer and invoke it directly.
|
access the original class function pointer and invoke it directly.
|
||||||
<footnote>
|
<footnote>
|
||||||
<para>The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully
|
<para>
|
||||||
|
The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully
|
||||||
understand its meaning, you need to recall how class structures are initialized: for each object type,
|
understand its meaning, you need to recall how class structures are initialized: for each object type,
|
||||||
the class structure associated to this object is created by first copying the class structure of its
|
the class structure associated to this object is created by first copying the class structure of its
|
||||||
parent type (a simple <function>memcpy</function>) and then by invoking the class_init callback on
|
parent type (a simple <function>memcpy</function>) and then by invoking the class_init callback on
|
||||||
@ -743,15 +742,8 @@ b_method_to_call (B *obj, int a)
|
|||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
<!-- End Howto GObject -->
|
||||||
|
|
||||||
<!--
|
|
||||||
End Howto GObject
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Howto Interfaces
|
|
||||||
-->
|
|
||||||
|
|
||||||
<chapter id="howto-interface">
|
<chapter id="howto-interface">
|
||||||
<title>How To define and implement Interfaces?</title>
|
<title>How To define and implement Interfaces?</title>
|
||||||
@ -987,13 +979,15 @@ baz_instance_init (GTypeInstance *instance,
|
|||||||
<sect1>
|
<sect1>
|
||||||
<title>Interface definition prerequisites</title>
|
<title>Interface definition prerequisites</title>
|
||||||
|
|
||||||
<para>To specify that an interface requires the presence of other interfaces when implemented,
|
<para>
|
||||||
|
To specify that an interface requires the presence of other interfaces when implemented,
|
||||||
GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
|
GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
|
||||||
a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
|
a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
|
||||||
I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.
|
I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The mechanism described above is, in practice, very similar to Java's interface I1 extends
|
<para>
|
||||||
|
The mechanism described above is, in practice, very similar to Java's interface I1 extends
|
||||||
interface I2. The example below shows the GObject equivalent:
|
interface I2. The example below shows the GObject equivalent:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -1031,7 +1025,6 @@ ibaz_interface_init (gpointer g_iface,
|
|||||||
iface->do_action = (void (*) (MamanIbaz *self))ibaz_do_action;
|
iface->do_action = (void (*) (MamanIbaz *self))ibaz_do_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bar_instance_init (GTypeInstance *instance,
|
bar_instance_init (GTypeInstance *instance,
|
||||||
gpointer g_class)
|
gpointer g_class)
|
||||||
@ -1040,7 +1033,6 @@ bar_instance_init (GTypeInstance *instance,
|
|||||||
self->instance_member = 0x666;
|
self->instance_member = 0x666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
maman_bar_get_type (void)
|
maman_bar_get_type (void)
|
||||||
{
|
{
|
||||||
@ -1096,14 +1088,16 @@ maman_bar_get_type (void)
|
|||||||
<sect1 id="howto-interface-properties">
|
<sect1 id="howto-interface-properties">
|
||||||
<title>Interface Properties</title>
|
<title>Interface Properties</title>
|
||||||
|
|
||||||
<para>Starting from version 2.4 of glib, GObject interfaces can also have properties.
|
<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
|
Declaration of the interface properties is similar to declaring the properties of
|
||||||
ordinary GObject types as explained in <xref linkend="gobject-properties"/>,
|
ordinary GObject types as explained in <xref linkend="gobject-properties"/>,
|
||||||
except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
|
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>.
|
declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>To include a property named 'name' of type <type>string</type> in the
|
<para>
|
||||||
|
To include a property named 'name' of type <type>string</type> in the
|
||||||
<type>maman_ibaz</type> interface example code above, we only need to add one
|
<type>maman_ibaz</type> interface example code above, we only need to add one
|
||||||
<footnote>
|
<footnote>
|
||||||
<para>
|
<para>
|
||||||
@ -1139,13 +1133,15 @@ maman_ibaz_base_init (gpointer g_iface)
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>One point worth noting is that the declared property wasn't assigned an
|
<para>
|
||||||
|
One point worth noting is that the declared property wasn't assigned an
|
||||||
integer ID. The reason being that integer IDs of properities are utilized only
|
integer ID. The reason being that integer IDs of properities are utilized only
|
||||||
inside the get and set methods and since interfaces do not implement properties,
|
inside the get and set methods and since interfaces do not implement properties,
|
||||||
there is no need to assign integer IDs to interface properties.
|
there is no need to assign integer IDs to interface properties.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The story for the implementers of the interface is also quite trivial.
|
<para>
|
||||||
|
The story for the implementers of the interface is also quite trivial.
|
||||||
An implementer shall declare and define it's properties in the usual way as
|
An implementer shall declare and define it's properties in the usual way as
|
||||||
explained in <xref linkend="gobject-properties"/>, except for one small
|
explained in <xref linkend="gobject-properties"/>, except for one small
|
||||||
change: it shall declare the properties of the interface it implements using
|
change: it shall declare the properties of the interface it implements using
|
||||||
@ -1260,19 +1256,8 @@ maman_baz_get_property (GObject * object, guint prop_id,
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
<!-- End Howto Interfaces -->
|
||||||
<!--
|
|
||||||
End Howto Interfaces
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
start Howto Signals
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<chapter id="howto-signals">
|
<chapter id="howto-signals">
|
||||||
<title>Howto create and use signals</title>
|
<title>Howto create and use signals</title>
|
||||||
@ -1294,7 +1279,8 @@ maman_baz_get_property (GObject * object, guint prop_id,
|
|||||||
<sect1 id="howto-simple-signals">
|
<sect1 id="howto-simple-signals">
|
||||||
<title>Simple use of signals</title>
|
<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
|
<para>
|
||||||
|
The most basic use of signals is to implement simple event notification: for example, if we have a
|
||||||
MamanFile object, and if this object has a write method, we might wish to be notified whenever someone
|
MamanFile object, and if this object has a write method, we might wish to be notified whenever someone
|
||||||
uses this method. The code below shows how the user can connect a callback to the write signal. Full code
|
uses this method. The code below shows how the user can connect a callback to the write signal. Full code
|
||||||
for this simple example is located in <filename>sample/signal/maman-file.{h|c}</filename> and
|
for this simple example is located in <filename>sample/signal/maman-file.{h|c}</filename> and
|
||||||
@ -1350,25 +1336,26 @@ double underscore denote the parameter types.
|
|||||||
The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
|
The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
|
||||||
needed closures that one can use.
|
needed closures that one can use.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>How to provide more flexibility to users?</title>
|
<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
|
<para>
|
||||||
|
The previous implementation does the job but the signal facility of GObject can be used to provide
|
||||||
even more flexibility to this file change notification mechanism. One of the key ideas is to make the process
|
even more flexibility to this file change notification mechanism. One of the key ideas is to make the process
|
||||||
of writing data to the file part of the signal emission process to allow users to be notified either
|
of writing data to the file part of the signal emission process to allow users to be notified either
|
||||||
before or after the data is written to the file.
|
before or after the data is written to the file.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>To integrate the process of writing the data to the file into the signal emission mechanism, we can
|
<para>
|
||||||
|
To integrate the process of writing the data to the file into the signal emission mechanism, we can
|
||||||
register a default class closure for this signal which will be invoked during the signal emission, just like
|
register a default class closure for this signal which will be invoked during the signal emission, just like
|
||||||
any other user-connected signal handler.
|
any other user-connected signal handler.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The first step to implement this idea is to change the signature of the signal: we need to pass
|
<para>
|
||||||
|
The first step to implement this idea is to change the signature of the signal: we need to pass
|
||||||
around the buffer to write and its size. To do this, we use our own marshaller which will be generated
|
around the buffer to write and its size. To do this, we use our own marshaller which will be generated
|
||||||
through glib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains
|
through glib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains
|
||||||
the following single line:
|
the following single line:
|
||||||
@ -1380,7 +1367,8 @@ and use the Makefile provided in <filename>sample/signal/Makefile</filename> to
|
|||||||
<filename>maman-file-complex.c</filename>.
|
<filename>maman-file-complex.c</filename>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Once the marshaller is present, we register the signal and its marshaller in the class_init function
|
<para>
|
||||||
|
Once the marshaller is present, we register the signal and its marshaller in the class_init function
|
||||||
of the object <type>MamanFileComplex</type> (full source for this object is included in
|
of the object <type>MamanFileComplex</type> (full source for this object is included in
|
||||||
<filename>sample/signal/maman-file-complex.{h|c}</filename>):
|
<filename>sample/signal/maman-file-complex.{h|c}</filename>):
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -1423,7 +1411,8 @@ default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
|
<para>
|
||||||
|
Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
|
||||||
triggers the signal emission:
|
triggers the signal emission:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
|
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
|
||||||
@ -1437,7 +1426,8 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before
|
<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
|
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><link linkend="g-signal-connect">g_signal_connect</link></function>
|
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
|
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
|
||||||
@ -1592,11 +1582,9 @@ klass->write_signal_id =
|
|||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>How users can abuse signals (and why some think it is good)</title>
|
<title>How users can abuse signals (and why some think it is good)</title>
|
||||||
|
|
||||||
@ -1607,7 +1595,8 @@ klass->write_signal_id =
|
|||||||
This will make you feel good and eleet.
|
This will make you feel good and eleet.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The users can:
|
<para>
|
||||||
|
The users can:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>stop the emission of the signal at anytime</para></listitem>
|
<listitem><para>stop the emission of the signal at anytime</para></listitem>
|
||||||
<listitem><para>override the default handler of the signal if it is stored as a function
|
<listitem><para>override the default handler of the signal if it is stored as a function
|
||||||
@ -1616,28 +1605,32 @@ klass->write_signal_id =
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>In both cases, the original programmer should be as careful as possible to write code which is
|
<para>
|
||||||
|
In both cases, the original programmer should be as careful as possible to write code which is
|
||||||
resistant to the fact that the default handler of the signal might not able to run. This is obviously
|
resistant to the fact that the default handler of the signal might not able to run. This is obviously
|
||||||
not the case in the example used in the previous sections since the write to the file depends on whether
|
not the case in the example used in the previous sections since the write to the file depends on whether
|
||||||
or not the default handler runs (however, this might be your goal: to allow the user to prevent the file
|
or not the default handler runs (however, this might be your goal: to allow the user to prevent the file
|
||||||
write if he wishes to).
|
write if he wishes to).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>If all you want to do is to stop the signal emission from one of the callbacks you connected yourself,
|
<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><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
|
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.
|
it further.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>If the signal's default handler is just a class function pointer, it is also possible to override
|
<para>
|
||||||
|
If the signal's default handler is just a class function pointer, it is also possible to override
|
||||||
it yourself from the class_init function of a type which derives from the parent. That way, when the signal
|
it yourself from the class_init function of a type which derives from the parent. That way, when the signal
|
||||||
is emitted, the parent class will use the function provided by the child as a signal default handler.
|
is emitted, the parent class will use the function provided by the child as a signal default handler.
|
||||||
Of course, it is also possible (and recommended) to chain up from the child to the parent's default signal
|
Of course, it is also possible (and recommended) to chain up from the child to the parent's default signal
|
||||||
handler to ensure the integrity of the parent object.
|
handler to ensure the integrity of the parent object.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Overriding a class method and chaining up was demonstrated in <xref linkend="howto-gobject-methods"/>
|
<para>
|
||||||
which is why I won't bother to show exactly how to do it here again.</para>
|
Overriding a class method and chaining up was demonstrated in <xref linkend="howto-gobject-methods"/>
|
||||||
|
which is why I won't bother to show exactly how to do it here again.
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
@ -1723,10 +1716,3 @@ g_object_do_class_init (GObjectClass *class)
|
|||||||
</sect2>
|
</sect2>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<capter1 id="howto-doc">
|
|
||||||
<title>How to generate API documentation for your type?</title>
|
|
||||||
|
|
||||||
</chapter>
|
|
||||||
-->
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<chapter>
|
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||||
|
<chapter id="chapter-intro">
|
||||||
<title>Background</title>
|
<title>Background</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -11,13 +12,15 @@ or interpreted languages.</para></listitem>
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>A lot of programmers are used to work with compiled-only or dynamically interpreted-only
|
<para>
|
||||||
|
A lot of programmers are used to work with compiled-only or dynamically interpreted-only
|
||||||
languages and do not understand the challenges associated with cross-language interoperability.
|
languages and do not understand the challenges associated with cross-language interoperability.
|
||||||
This introduction tries to provide an insight into these challenges. describes briefly
|
This introduction tries to provide an insight into these challenges. describes briefly
|
||||||
the solution choosen by GLib.
|
the solution choosen by GLib.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The following chapters go into greater detail into how GType and GObject work and
|
<para>
|
||||||
|
The following chapters go into greater detail into how GType and GObject work and
|
||||||
how you can use them as a C programmer. It is 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
|
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
|
goals: this can often explain the sometimes rather convoluted APIs and features present
|
||||||
@ -43,7 +46,8 @@ the source code and executes it) maps the language types to the machine types of
|
|||||||
runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine).
|
runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Perl and Python which are interpreted languages do not really provide type definitions similar
|
<para>
|
||||||
|
Perl and Python which are interpreted languages do not really provide type definitions similar
|
||||||
to those used by C. Perl and Python programmers manipulate variables and the type of the variables
|
to those used by C. Perl and Python programmers manipulate variables and the type of the variables
|
||||||
is decided only upon the first assignment or upon the first use which forces a type on the variable.
|
is decided only upon the first assignment or upon the first use which forces a type on the variable.
|
||||||
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
|
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
|
||||||
@ -62,7 +66,8 @@ by the language are not intuitive.
|
|||||||
<sect1>
|
<sect1>
|
||||||
<title>Exporting a C API</title>
|
<title>Exporting a C API</title>
|
||||||
|
|
||||||
<para>C APIs are defined by a set of functions and global variables which are usually exported from a
|
<para>
|
||||||
|
C APIs are defined by a set of functions and global variables which are usually exported from a
|
||||||
binary. C functions have an arbitrary number of arguments and one return value. Each function is thus
|
binary. C functions have an arbitrary number of arguments and one return value. Each function is thus
|
||||||
uniquely identified by the function name and the set of C types which describe the function arguments
|
uniquely identified by the function name and the set of C types which describe the function arguments
|
||||||
and return value. The global variables exported by the API are similarly identified by their name and
|
and return value. The global variables exported by the API are similarly identified by their name and
|
||||||
@ -116,7 +121,8 @@ variables to return them to the python code.</para></listitem>
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The process described above is pretty complex and there are a lot of ways to make it entirely automatic
|
<para>
|
||||||
|
The process described above is pretty complex and there are a lot of ways to make it entirely automatic
|
||||||
and transparent to the C and the Python programmers:
|
and transparent to the C and the Python programmers:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported,
|
<listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported,
|
||||||
@ -127,7 +133,8 @@ C function.</para></listitem>
|
|||||||
imported, with a special compiler which
|
imported, with a special compiler which
|
||||||
reads the original function signature.</para></listitem>
|
reads the original function signature.</para></listitem>
|
||||||
<listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of
|
<listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of
|
||||||
all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis><footnote>
|
all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis>
|
||||||
|
<footnote>
|
||||||
<para>
|
<para>
|
||||||
There are numerous different implementations of dynamic type systems: all C++
|
There are numerous different implementations of dynamic type systems: all C++
|
||||||
compilers have one, Java and .NET have one too. A dynamic type system allows you
|
compilers have one, Java and .NET have one too. A dynamic type system allows you
|
||||||
@ -138,10 +145,8 @@ all the objects manipulated by the programmer. This so-called <emphasis>dynamic
|
|||||||
is that they all allow you to query for object metadata at runtime.
|
is that they all allow you to query for object metadata at runtime.
|
||||||
</para>
|
</para>
|
||||||
</footnote>
|
</footnote>
|
||||||
|
library is then used by special generic glue code to automatically convert function parameters and
|
||||||
library is then
|
function calling conventions between different runtime domains.</para></listitem>
|
||||||
used by special generic glue code to automatically convert function parameters and function calling conventions
|
|
||||||
between different runtime domains.</para></listitem>
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain
|
The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain
|
||||||
boundaries is written once: the figure below states this more clearly.
|
boundaries is written once: the figure below states this more clearly.
|
||||||
@ -161,7 +166,8 @@ C objects written with GType directly in Python or Perl, with a minimum amount o
|
|||||||
is no need to generate huge amounts of glue code either automatically or by hand.
|
is no need to generate huge amounts of glue code either automatically or by hand.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Although that goal was arguably laudable, its pursuit has had a major influence on
|
<para>
|
||||||
|
Although that goal was arguably laudable, its pursuit has had a major influence on
|
||||||
the whole GType/GObject library. C programmers are likely to be puzzled at the complexity
|
the whole GType/GObject library. C programmers are likely to be puzzled at the complexity
|
||||||
of the features exposed in the following chapters if they forget that the GType/GObject library
|
of the features exposed in the following chapters if they forget that the GType/GObject library
|
||||||
was not only designed to offer OO-like features to C programmers but also transparent
|
was not only designed to offer OO-like features to C programmers but also transparent
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version='1.0' encoding="ISO-8859-1"?>
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
Several useful developer tools have been build around GObject technology.
|
Several useful developer tools have been build around GObject technology.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user