mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 16:26:17 +01:00
docs: Various wording changes in the GObject how-to
• Consistently make all titles sentence case • Fix various typos • Remove an unnecessary footnote • Remove first person phrasing https://bugzilla.gnome.org/show_bug.cgi?id=744060
This commit is contained in:
parent
f1287a9b2f
commit
2e4700d52b
@ -16,11 +16,8 @@
|
|||||||
<title>How to define and implement a new GObject</title>
|
<title>How to define and implement a new GObject</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Clearly, this is one of the most common questions people ask: they just
|
This chapter focuses on the implementation of a subtype of GObject, for
|
||||||
want to crank code and implement a subclass of a GObject. Sometimes because
|
example to create a custom class hierarchy, or to subclass a GTK+ widget.
|
||||||
they want to create their own class hierarchy, sometimes because they want
|
|
||||||
to subclass one of GTK+'s widget. This chapter will focus on the
|
|
||||||
implementation of a subtype of GObject.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect1 id="howto-gobject-header">
|
<sect1 id="howto-gobject-header">
|
||||||
@ -261,7 +258,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="howto-gobject-construction">
|
<sect1 id="howto-gobject-construction">
|
||||||
<title>Object Construction</title>
|
<title>Object construction</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
People often get confused when trying to construct their GObjects because of the
|
People often get confused when trying to construct their GObjects because of the
|
||||||
@ -296,7 +293,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
As such, I would recommend writing the following code first:
|
You should write the following code first:
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||||
|
|
||||||
@ -365,10 +362,10 @@ bar_class_init (MamanBarClass *klass)
|
|||||||
of a type only after the properties passed to the constructors have been
|
of a type only after the properties passed to the constructors have been
|
||||||
set. This is possible through the use of the <function>constructor()</function>
|
set. This is possible through the use of the <function>constructor()</function>
|
||||||
class method as described in <xref linkend="gobject-instantiation"/> or,
|
class method as described in <xref linkend="gobject-instantiation"/> or,
|
||||||
more simply, using the <function>constructed()</function> class method
|
more simply, using the <function>constructed()</function> class method.
|
||||||
available since GLib 2.12. Note that the <function>constructed()</function>
|
Note that the <function>constructed()</function>
|
||||||
virtual function will only be invoked after the properties marked as
|
virtual function will only be invoked after the properties marked as
|
||||||
<function>G_PARAM_CONSTRUCT_ONLY</function>s or
|
<function>G_PARAM_CONSTRUCT_ONLY</function> or
|
||||||
<function>G_PARAM_CONSTRUCT</function> have been consumed, but
|
<function>G_PARAM_CONSTRUCT</function> have been consumed, but
|
||||||
before the regular properties passed to <function>g_object_new()</function>
|
before the regular properties passed to <function>g_object_new()</function>
|
||||||
have been set.
|
have been set.
|
||||||
@ -376,7 +373,7 @@ bar_class_init (MamanBarClass *klass)
|
|||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="howto-gobject-destruction">
|
<sect1 id="howto-gobject-destruction">
|
||||||
<title>Object Destruction</title>
|
<title>Object destruction</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Again, it is often difficult to figure out which mechanism to use to
|
Again, it is often difficult to figure out which mechanism to use to
|
||||||
@ -387,11 +384,12 @@ bar_class_init (MamanBarClass *klass)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The destruction process of your object might be split in two different
|
The destruction process of your object is in two phases: dispose and
|
||||||
phases: dispose and the finalize. This split is necessary to handle
|
finalize. This split is necessary to handle
|
||||||
potential cycles due to the nature of the reference counting mechanism
|
potential cycles due to the nature of the reference counting mechanism
|
||||||
used by GObject, as well as dealing with temporary vivification of
|
used by GObject, as well as dealing with temporary revival of
|
||||||
instances in case of signal emission during the destruction sequence.
|
instances in case of signal emission during the destruction sequence.
|
||||||
|
See <xref linkend="gobject-memory-cycles"/> for more information.
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
struct _MamanBarPrivate
|
struct _MamanBarPrivate
|
||||||
{
|
{
|
||||||
@ -463,7 +461,7 @@ maman_bar_init (MamanBar *self);
|
|||||||
It is possible that object methods might be invoked after dispose is
|
It is possible that object methods might be invoked after dispose is
|
||||||
run and before finalize runs. GObject does not consider this to be a
|
run and before finalize runs. GObject does not consider this to be a
|
||||||
program error: you must gracefully detect this and neither crash nor
|
program error: you must gracefully detect this and neither crash nor
|
||||||
warn the user, by having a disposed instance revert to an inhert state.
|
warn the user, by having a disposed instance revert to an inert state.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
@ -494,8 +492,8 @@ maman_bar_init (MamanBar *self);
|
|||||||
<title>Non-virtual public methods</title>
|
<title>Non-virtual public methods</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
These are the simplest: you want to provide a simple method which
|
These are the simplest, providing a simple method which
|
||||||
can act on your object. All you need to do is to provide a function
|
acts on the object. Provide a function
|
||||||
prototype in the header and an implementation of that prototype
|
prototype in the header and an implementation of that prototype
|
||||||
in the source file.
|
in the source file.
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
@ -572,7 +570,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Please, note that it is possible for you to provide a default
|
It is possible to provide a default
|
||||||
implementation for this class method in the object's
|
implementation for this class method in the object's
|
||||||
<function>class_init</function> function: initialize the
|
<function>class_init</function> function: initialize the
|
||||||
<function>klass->do_action</function> field to a pointer to the
|
<function>klass->do_action</function> field to a pointer to the
|
||||||
@ -716,17 +714,19 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
|||||||
<listitem><para>Parent class A defines a public virtual method named <function>foo</function> and
|
<listitem><para>Parent class A defines a public virtual method named <function>foo</function> and
|
||||||
provides a default implementation.</para></listitem>
|
provides a default implementation.</para></listitem>
|
||||||
<listitem><para>Child class B re-implements method <function>foo</function>.</para></listitem>
|
<listitem><para>Child class B re-implements method <function>foo</function>.</para></listitem>
|
||||||
<listitem><para>In the method B::foo, the child class B calls its parent class method A::foo.</para></listitem>
|
<listitem><para>B’s implementation of <function>foo</function> calls (‘chains up to’) its parent class A’s implementation of <function>foo</function>.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
There are various uses to this idiom:
|
There are various uses of this idiom:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>You need to extend the behaviour of a class without modifying its code. You create
|
<listitem><para>You need to extend the behaviour of a class without modifying its code. You create
|
||||||
a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
|
a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
|
||||||
and chain up to ensure that the previous behaviour is not really modified, just extended.
|
and chain up to ensure that the previous behaviour is not really modified, just extended.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>You need to implement the Chain Of Responsibility pattern: each object of the inheritance
|
<listitem><para>You need to implement the
|
||||||
|
<ulink url="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">Chain
|
||||||
|
Of Responsibility pattern</ulink>: each object of the inheritance
|
||||||
tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
|
tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
|
||||||
they each handler is run in turn.</para></listitem>
|
each handler is run in turn.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -737,24 +737,22 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
|||||||
<footnote>
|
<footnote>
|
||||||
<para>
|
<para>
|
||||||
The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully
|
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, 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 with 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 <function>class_init</function> callback on
|
||||||
the resulting class structure. Since the class_init callback is responsible for overwriting the class structure
|
the resulting class structure. Since the <function>class_init</function> callback is responsible for overwriting the class structure
|
||||||
with the user re-implementations of the class methods, we cannot merely use the modified copy of the parent class
|
with the user re-implementations of the class methods, the modified copy of the parent class
|
||||||
structure stored in our derived instance. We want to get a copy of the class structure of an instance of the parent
|
structure stored in the derived instance cannot be used. A copy of the class structure of an instance of the parent
|
||||||
class.
|
class is needed.
|
||||||
</para>
|
</para>
|
||||||
</footnote>
|
</footnote>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>The function <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function>
|
<para>
|
||||||
is used to access the original parent class structure. Its input is a
|
Use the <function>parent_class</function> pointer created and initialized
|
||||||
pointer to the class of the derived object and it returns a pointer to
|
by the
|
||||||
the original parent class structure. Instead of using this function
|
<link linkend="G-DEFINE-TYPE:CAPS"><function>G_DEFINE_TYPE</function></link>
|
||||||
directly, though, use the <function>parent_class</function>
|
family of macros, for instance:
|
||||||
pointer created and initialized by the <function>G_DEFINE_TYPE_*</function> family of
|
|
||||||
macros, for instance:
|
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
b_method_to_call (B *obj, int a)
|
b_method_to_call (B *obj, int a)
|
||||||
@ -785,12 +783,13 @@ b_method_to_call (B *obj, int a)
|
|||||||
<title>Defining interfaces</title>
|
<title>Defining interfaces</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/>
|
The theory behind how GObject interfaces work is given in
|
||||||
but I feel it is needed to show exactly how to create an interface.
|
<xref linkend="gtype-non-instantiable-classed"/>; this section covers how to
|
||||||
|
define and implement an interface.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
As above, the first step is to get the header right. This interface
|
The first step is to get the header right. This interface
|
||||||
defines two methods:
|
defines two methods:
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
#ifndef __MAMAN_IBAZ_H__
|
#ifndef __MAMAN_IBAZ_H__
|
||||||
@ -896,56 +895,18 @@ maman_ibaz_do_something (MamanIbaz *self)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The first step is to define a normal GObject class, like:
|
The first step is to define a normal final GObject class exactly as in
|
||||||
<informalexample><programlisting>
|
<xref linkend="howto-gobject-header"/>.
|
||||||
#ifndef __MAMAN_BAZ_H__
|
|
||||||
#define __MAMAN_BAZ_H__
|
|
||||||
|
|
||||||
#include <glib-object.h>
|
|
||||||
|
|
||||||
#define MAMAN_TYPE_BAZ (maman_baz_get_type ())
|
|
||||||
#define MAMAN_BAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAZ, Mamanbaz))
|
|
||||||
#define MAMAN_IS_BAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAZ))
|
|
||||||
#define MAMAN_BAZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAZ, MamanbazClass))
|
|
||||||
#define MAMAN_IS_BAZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAZ))
|
|
||||||
#define MAMAN_BAZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAZ, MamanbazClass))
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _MamanBaz MamanBaz;
|
|
||||||
typedef struct _MamanBazClass MamanBazClass;
|
|
||||||
|
|
||||||
struct _MamanBaz
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
gint instance_member;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MamanBazClass
|
|
||||||
{
|
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType maman_baz_get_type (void);
|
|
||||||
|
|
||||||
#endif /* __MAMAN_BAZ_H__ */
|
|
||||||
</programlisting></informalexample>
|
|
||||||
<!-- Ha ha! "nothing weird or scary". I actually laughed out loud. Oh boy.
|
|
||||||
The fact that we're so intimate with GObject that all this doesn't look
|
|
||||||
wierd, that's the scary thing. :) -->
|
|
||||||
There is clearly nothing specifically weird or scary about this header:
|
|
||||||
it does not define any weird API or derive from a weird type.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The second step is to implement <type>MamanBaz</type> by defining
|
The second step is to implement <type>MamanBaz</type> by defining
|
||||||
its <type>GType</type>. Instead of using
|
it using
|
||||||
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>,
|
|
||||||
use
|
|
||||||
<function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
|
<function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
|
||||||
and the
|
and
|
||||||
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
|
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
|
||||||
macros.
|
instead of
|
||||||
|
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>:
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
static void maman_ibaz_interface_init (MamanIbazInterface *iface);
|
static void maman_ibaz_interface_init (MamanIbazInterface *iface);
|
||||||
|
|
||||||
@ -953,8 +914,8 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
|||||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
||||||
maman_ibaz_interface_init))
|
maman_ibaz_interface_init))
|
||||||
</programlisting></informalexample>
|
</programlisting></informalexample>
|
||||||
This definition is very much like all the similar functions we looked
|
This definition is very much like all the similar functions seen
|
||||||
at previously. The only interface-specific code present here is the call to
|
previously. The only interface-specific code present here is the use of
|
||||||
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
|
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -1111,14 +1072,9 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
To include a property named 'name' of type <type>string</type> in the
|
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
|
<type>MamanIbaz</type> interface example code above, we only need to
|
||||||
add one
|
add one call in <function>maman_ibaz_default_init</function> as shown
|
||||||
<footnote>
|
below:
|
||||||
<para>
|
|
||||||
That really is one line extended to six for the sake of clarity
|
|
||||||
</para>
|
|
||||||
</footnote>
|
|
||||||
line in the <function>maman_ibaz_default_init</function> as shown below:
|
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_ibaz_default_init (MamanIbazInteface *iface)
|
maman_ibaz_default_init (MamanIbazInteface *iface)
|
||||||
@ -1136,9 +1092,10 @@ maman_ibaz_default_init (MamanIbazInteface *iface)
|
|||||||
<para>
|
<para>
|
||||||
One point worth noting is that the declared property wasn't assigned an
|
One point worth noting is that the declared property wasn't assigned an
|
||||||
integer ID. The reason being that integer IDs of properties are used
|
integer ID. The reason being that integer IDs of properties are used
|
||||||
only inside the get and set methods and since interfaces do not
|
only inside the <function>get_property</function> and
|
||||||
implement properties, there is no need to assign integer IDs to
|
<function>set_property</function> virtual methods. Since interfaces
|
||||||
interface properties.
|
declare but do not <emphasis>implement</emphasis> properties, there is no
|
||||||
|
need to assign integer IDs to them.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -1226,10 +1183,10 @@ maman_baz_class_init (MamanBazClass *klass)
|
|||||||
<title>Overriding interface methods</title>
|
<title>Overriding interface methods</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If a base class already implements an interface, and in a derived
|
If a base class already implements an interface and a derived
|
||||||
class you wish to implement the same interface overriding only certain
|
class needs to implement the same interface but needs to override certain
|
||||||
methods of that interface, you just reimplement the interface and
|
methods, you must reimplement the interface and set only the interface
|
||||||
set only the interface methods you wish to override.
|
methods which need overriding.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -1283,9 +1240,9 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If you wish to call the base class implementation of an interface
|
To call the base class implementation of an interface
|
||||||
method from an derived class where than interface method has been
|
method from an derived class where than interface method has been
|
||||||
overridden then you can stash away the pointer returned from
|
overridden, stash away the pointer returned from
|
||||||
<function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
|
<function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
|
||||||
in a global variable.
|
in a global variable.
|
||||||
</para>
|
</para>
|
||||||
@ -1339,7 +1296,7 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
<title>How to create and use signals</title>
|
<title>How to create and use signals</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The signal system which was built in GType is pretty complex and
|
The signal system in GType is pretty complex and
|
||||||
flexible: it is possible for its users to connect at runtime any
|
flexible: it is possible for its users to connect at runtime any
|
||||||
number of callbacks (implemented in any language for which a binding
|
number of callbacks (implemented in any language for which a binding
|
||||||
exists)
|
exists)
|
||||||
@ -1350,24 +1307,24 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
</footnote>
|
</footnote>
|
||||||
to any signal and to stop the emission of any signal at any
|
to any signal and to stop the emission of any signal at any
|
||||||
state of the signal emission process. This flexibility makes it
|
state of the signal emission process. This flexibility makes it
|
||||||
possible to use GSignal for much more than just emit signals which
|
possible to use GSignal for much more than just emitting signals to
|
||||||
can be received by numerous clients.
|
multiple clients.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect1 id="howto-simple-signals">
|
<sect1 id="howto-simple-signals">
|
||||||
<title>Simple use of signals</title>
|
<title>Simple use of signals</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The most basic use of signals is to implement simple event
|
The most basic use of signals is to implement event
|
||||||
notification: for example, if we have a MamanFile object, and
|
notification. For example, given a <type>MamanFile</type> object with
|
||||||
if this object has a write method, we might wish to be notified
|
a <function>write</function> method, a signal could be emitted whenever
|
||||||
whenever someone has changed something via our MamanFile instance.
|
the file is changed using that method.
|
||||||
The code below shows how the user can connect a callback to the
|
The code below shows how the user can connect a callback to the
|
||||||
"changed" signal.
|
"changed" signal.
|
||||||
<informalexample><programlisting>
|
<informalexample><programlisting>
|
||||||
file = g_object_new (MAMAN_FILE_TYPE, NULL);
|
file = g_object_new (MAMAN_FILE_TYPE, NULL);
|
||||||
|
|
||||||
g_signal_connect (file, "changed", G_CALLBACK (changed_event), NULL);
|
g_signal_connect (file, "changed", (GCallback) changed_event, NULL);
|
||||||
|
|
||||||
maman_file_write (file, buffer, strlen (buffer));
|
maman_file_write (file, buffer, strlen (buffer));
|
||||||
</programlisting></informalexample>
|
</programlisting></informalexample>
|
||||||
@ -1396,32 +1353,26 @@ maman_file_write (MamanFile *self,
|
|||||||
const guchar *buffer,
|
const guchar *buffer,
|
||||||
gssize size)
|
gssize size)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (MAMAN_IS_FILE (self));
|
||||||
|
g_return_if_fail (buffer != NULL || size == 0);
|
||||||
|
|
||||||
/* First write data. */
|
/* First write data. */
|
||||||
|
|
||||||
/* Then, notify user of data written. */
|
/* Then, notify user of data written. */
|
||||||
g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
|
g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
|
||||||
}
|
}
|
||||||
</programlisting></informalexample>
|
</programlisting></informalexample>
|
||||||
As shown above, you can safely set the details parameter to zero if
|
As shown above, the details parameter can safely be set to zero if no
|
||||||
you do not know what it can be used for. For a discussion of what you
|
detail needs to be conveyed. For a discussion of what it can be used for,
|
||||||
could used it for, see <xref linkend="signal-detail"/>
|
see <xref linkend="signal-detail"/>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The signature of the signal handler in the above example is defined as
|
The C signal marshaller should always be
|
||||||
<function>g_cclosure_marshal_VOID__VOID</function>. Its name follows
|
<function>g_cclosure_marshal_generic</function>, which implements generic
|
||||||
a simple convention which encodes the function parameter and return value
|
conversion of arrays of parameters to C callback invocations. GLib used to
|
||||||
types in the function name. Specifically, the value in front of the
|
use type-specific generated marshallers, but that has been deprecated in
|
||||||
double underscore is the type of the return value, while the value(s)
|
favour of the generic marshaller.
|
||||||
after the double underscore denote the parameter types.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The header <filename>gobject/gmarshal.h</filename> defines a set of
|
|
||||||
commonly needed closures that one can use. If you want to have complex
|
|
||||||
marshallers for your signals you should probably use glib-genmarshal
|
|
||||||
to autogenerate them from a file containing their return and
|
|
||||||
parameter types.
|
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
Loading…
Reference in New Issue
Block a user