Re: howto write an interface
- From: David Nečas <yeti physics muni cz>
- To: joel krähemann <joel weedlight ch>
- Cc: gtk-list gnome org
- Subject: Re: howto write an interface
- Date: Tue, 7 Sep 2010 09:32:19 +0200
On Mon, Sep 06, 2010 at 09:05:37PM +0200, joel krähemann wrote:
> Hi, I want to write an interface with glib-object. The situation is a
> parent object implements the interface, but the subclass should
> overwrite the function pointers in the interface. The parent class
> contains the following code in the function ags_recall_get_type:
>
> ...
>
> static const GInterfaceInfo ags_connectable_interface_info = {
> (GInterfaceInitFunc) ags_recall_connectable_interface_init,
> NULL, /* interface_finalize */
> NULL, /* interface_data */
> };
>
> ...
>
> g_type_add_interface_static(ags_type_recall,
> AGS_TYPE_CONNECTABLE,
> &ags_connectable_interface_info);
>
> ...
>
> AgsRecall has subclasses which should overwrite the functions, but I
> don't know what's the proper way in the subclass to do so. How do I tell
> GInterface to call a function of the subclass to overwrite?
> One more, is it correct to make an object cast on the interface e.g.
> (where AgsConnectable is an interface which is implemented by
> AgsRecall):
>
> void
> ags_recall_connect(AgsConnectable connectable)
> {
> AGS_RECALL(connectable);
>
> ...
> }
This sounds somehow backwards.
1) You define an interface, with a virtual table, i.e. struct
AgsConnectableInterface, containing the method connect():
struct _AgsConnectableInterface {
GTypeInterface parent;
void (*connect)(AgsConnectable *connectable);
};
2) Then standard macros AGS_TYPE_CONNECTABLE, AGS_CONNECTABLE,
AGS_IS_CONNECTABLE, AGS_CONNECTABLE_GET_INTERFACE, see the docs.
3) Methods of this interface, e.g. ags_connectable_connect(), get
AgsConnectable* as the argument and look up the virtual method to call:
void
ags_connectable_connect(AgsConnectable *connectable)
{
void (*connect_method)(AgsConnectable*);
g_return_if_fail(AGS_IS_CONNECTABLE(connectable));
connect_method = AGS_CONNECTABLE_GET_INTERFACE(connectable)->connect;
g_return_if_fail(connect_method);
connect_method(connectable);
}
There is no public ags_recall_connect() as this makes no sense. To
invoke the connect() method of AgsRecall (or any other class
implementing the interface) you call
ags_connectable_connect(AGS_CONNECTABLE(recall));
4) Each class implementing the interface, including subclasses of
something that already implements the interface, does
{
static const GInterfaceInfo ags_connectable_interface_info = {
(GInterfaceInitFunc)ags_recall_connectable_init, NULL, NULL
};
g_type_add_interface_static(g_define_type_id,
AGS_TYPE_CONNECTABLE,
&ags_connectable_interface_info);
}
in the type init function ags_recall_type_init().
5) Function ags_recall_connectable_init() gets the virtual table
AgsConnectableInterface as the argument and fills it:
static void
ags_recall_connectable_init(AgsConnectableInterface *iface)
{
iface->connect = ags_recall_connect;
}
where ags_recall_connect() is a static function implementing the method,
not public.
Yeti
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]