mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
commit first patches from stefan, work on the chaining up section
This commit is contained in:
parent
152329248d
commit
9af6ab55db
@ -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 (&val, G_TYPE_CHAR);
|
||||
g_value_set_char (&val, 11);
|
||||
g_object_set_property (G_OBJECT (bar), "papa-number", &val);
|
||||
@ -699,6 +700,10 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &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>
|
||||
|
@ -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 <glib-object.h>
|
||||
|
||||
#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 <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",
|
||||
&info, 0);
|
||||
g_type_add_interface_static (type,
|
||||
MAMAN_IBAZ_TYPE,
|
||||
MAMAN_TYPE_IBAZ,
|
||||
&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", &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",
|
||||
&info, 0);
|
||||
g_type_add_interface_static (type,
|
||||
MAMAN_IBAZ_TYPE,
|
||||
MAMAN_TYPE_IBAZ,
|
||||
&ibaz_info);
|
||||
g_type_add_interface_static (type,
|
||||
MAMAN_IBAR_TYPE,
|
||||
MAMAN_TYPE_IBAR,
|
||||
&ibar_info);
|
||||
}
|
||||
return type;
|
||||
|
Loading…
Reference in New Issue
Block a user