commit first patches from stefan, work on the chaining up section

This commit is contained in:
Mathieu Lacage 2004-06-09 20:22:04 +00:00
parent 152329248d
commit 9af6ab55db
2 changed files with 56 additions and 33 deletions

View File

@ -17,7 +17,7 @@
<listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
<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
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
the details of how it works.
</para>
@ -53,12 +53,12 @@
<para>
The example below shows how <type>MamanBar</type> overrides the parent's constructor:
<programlisting>
#define MAMAN_BAR_TYPE (maman_bar_get_type ())
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_BAR_TYPE, MamanBar))
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_BAR_TYPE, MamanBarClass))
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_TYPE ((obj), MAMAN_BAR_TYPE))
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_BAR_TYPE))
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_BAR_TYPE, MamanBarClass))
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_TYPE ((obj), MAMAN_TYPE_BAR))
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
typedef struct _MamanBar MamanBar;
typedef struct _MamanBarClass MamanBarClass;
@ -74,7 +74,7 @@ struct _MamanBarClass {
/* class members */
};
/* used by MAMAN_BAR_TYPE */
/* used by MAMAN_TYPE_BAR */
GType maman_bar_get_type (void);
static GObject *
@ -88,7 +88,7 @@ maman_bar_constructor (GType type,
/* Invoke parent constructor. */
MamanBarClass *klass;
GObjectClass *parent_class;
klass = MAMAN_BAR_CLASS (g_type_class_peek (MAMAN_BAR_TYPE));
klass = MAMAN_BAR_CLASS (g_type_class_peek (MAMAN_TYPE_BAR));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
obj = parent_class->constructor (type,
n_construct_properties,
@ -142,7 +142,7 @@ GType maman_bar_get_type (void)
</programlisting>
If the user instantiates an object <type>MamanBar</type> with:
<programlisting>
MamanBar *bar = g_object_new (MAMAN_BAR_TYPE, NULL);
MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</programlisting>
If this is the first instantiation of such an object, the <function>maman_b_class_init</function>
function will be invoked after any <function>maman_b_base_class_init</function> function.
@ -504,7 +504,8 @@ void g_object_run_dispose (GObject *object);
<title>Object properties</title>
<para>
One of GObject's nice features is its generic get/set mechanism. When an 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>
(implemented in <filename>gobject.c</filename>).
@ -620,7 +621,7 @@ maman_bar_class_init (gpointer g_class,
GObject *bar;
GValue val = {0,};
bar = g_object_new (MAMAN_SUBBAR_TYPE, NULL);
bar = g_object_new (MAMAN_TYPE_SUBBAR, NULL);
g_value_init (&amp;val, G_TYPE_CHAR);
g_value_set_char (&amp;val, 11);
g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
@ -699,6 +700,10 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
can only be delayed by the notification freezing mechanism.
</para>
<sect2 id="gobject-multi-properties">
<title>Accessing multiple properties at once</title>
<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
@ -728,6 +733,11 @@ g_object_set (G_OBJECT (foo),
Of course, the "notify" signal will be emitted for each property set.
</para>
</sect2>
<!-- @todo tell here about how to pass use handle properties in derived classe -->
</sect1>
</chapter>

View File

@ -291,7 +291,7 @@ maman_bar_init (GTypeInstance *instance,
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
pspec by setting the param spec's flag field to G_PARAM_CONSTRUCT_ONLY: this helps
<type>GParamSpec</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
@ -439,7 +439,7 @@ if (self->private->dispose_has_run) {
</para>
<sect3>
<title>non-virtual public methods</title>
<title>Non-virtual public methods</title>
<para>
These are the simplest: you want to provide a simple method which can act on your object. All you need
@ -460,7 +460,7 @@ void maman_bar_do_action (MamanBar *self, /* parameters */)
</sect3>
<sect3>
<title>Virtual Public methods</title>
<title>Virtual public methods</title>
<para>
This is the preferred way to create polymorphic GObjects. All you need to do is to
@ -536,7 +536,7 @@ void maman_bar_do_action_two (MamanBar *self, /* parameters */)
</sect3>
<sect3>
<title>Virtual Private Methods</title>
<title>Virtual private Methods</title>
<para>
These are very similar to Virtual Public methods. They just don't have a public function to call the
@ -628,6 +628,19 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
</sect3>
</sect2>
<sect2 id="howto-gobject-chainup">
<title>Chaining up</title>
<p>Chaining up is commonly used to implement the Chain Of Responsability pattern in C++: each class in a
given inheritance hierarchy is expected to override the same method and then call from within each method
the overriden method of the parent. Personally, I am not sure this is a very smart idea (a detailed explanation
of why I think it is a bad idea would take too much space for this document) but I can show you how to do it and
here is an example.
</p>
<p>To invoke the parent method XXX</p>
</sect2>
</sect1>
@ -661,12 +674,12 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
#include &lt;glib-object.h&gt;
#define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ())
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
#define MAMAN_IBAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_IBAZ_TYPE, MamanIbazClass))
#define MAMAN_IS_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_IBAZ_TYPE))
#define MAMAN_IS_IBAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_IBAZ_TYPE))
#define MAMAN_IBAZ_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_IBAZ_TYPE, MamanIbazClass))
#define MAMAN_TYPE_IBAZ (maman_ibaz_get_type ())
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
#define MAMAN_IBAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_TYPE_IBAZ, MamanIbazClass))
#define MAMAN_IS_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
#define MAMAN_IS_IBAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_TYPE_IBAZ))
#define MAMAN_IBAZ_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_TYPE_IBAZ, MamanIbazClass))
typedef struct _MamanIbaz MamanIbaz; /* dummy object */
@ -774,12 +787,12 @@ void maman_ibaz_do_action (MamanIbaz *self)
#include &lt;glib-object.h>
#define MAMAN_BAZ_TYPE (maman_baz_get_type ())
#define MAMAN_BAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_BAZ_TYPE, Mamanbaz))
#define MAMAN_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_BAZ_TYPE, MamanbazClass))
#define MAMAN_IS_BAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_BAZ_TYPE))
#define MAMAN_IS_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_BAZ_TYPE))
#define MAMAN_BAZ_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MAMAN_BAZ_TYPE, MamanbazClass))
#define MAMAN_TYPE_BAZ (maman_baz_get_type ())
#define MAMAN_BAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAZ, Mamanbaz))
#define MAMAN_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_TYPE_BAZ, MamanbazClass))
#define MAMAN_IS_BAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAZ))
#define MAMAN_IS_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_TYPE_BAZ))
#define MAMAN_BAZ_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MAMAN_TYPE_BAZ, MamanbazClass))
typedef struct _MamanBaz MamanBaz;
@ -831,7 +844,7 @@ maman_baz_get_type (void)
"MamanBazType",
&amp;info, 0);
g_type_add_interface_static (type,
MAMAN_IBAZ_TYPE,
MAMAN_TYPE_IBAZ,
&amp;ibaz_info);
}
return type;
@ -840,7 +853,7 @@ maman_baz_get_type (void)
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
<function>MAMAN_IBAZ_TYPE</function>.
<function>MAMAN_TYPE_IBAZ</function>.
</para>
<para>
@ -889,7 +902,7 @@ baz_instance_init (GTypeInstance *instance,
<programlisting>
type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbar", &amp;info, 0);
/* Make the MamanIbar interface require MamanIbaz interface. */
g_type_interface_add_prerequisite (type, MAMAN_IBAZ_TYPE);
g_type_interface_add_prerequisite (type, MAMAN_TYPE_IBAZ);
</programlisting>
The code shown above adds the MamanIbaz interface to the list of prerequisites of MamanIbar while the
code below shows how an implementation can implement both interfaces and register their implementations:
@ -961,10 +974,10 @@ maman_bar_get_type (void)
"MamanBarType",
&amp;info, 0);
g_type_add_interface_static (type,
MAMAN_IBAZ_TYPE,
MAMAN_TYPE_IBAZ,
&amp;ibaz_info);
g_type_add_interface_static (type,
MAMAN_IBAR_TYPE,
MAMAN_TYPE_IBAR,
&amp;ibar_info);
}
return type;