Re: Interface implementation in language bindings
- From: "Gustavo J. A. M. Carneiro" <gjc inescporto pt>
- To: Owen Taylor <otaylor redhat com>
- Cc: gtk-devel-list gnome org
- Subject: Re: Interface implementation in language bindings
- Date: Sat, 26 Feb 2005 17:32:10 +0000
On Fri, 2005-02-25 at 17:21 -0500, Owen Taylor wrote:
>The ideal situation is that someone, using a language binding
>to GTK+ could just do:
>
> class Foo (GtkWidget, GtkCellLayout):
> def start_editing (event):
> [....]
s/start_editing/do_start_editing/ and you have the pygtk 2.5 solution
for GInterface implementation. In pygtk, method 'foo' calls the
implementation method of the interface ("client" part), while do_foo is
defined by the user to provide an implementation ("server" part).
Same thing for virtual methods, which are also recently supported in
pygtk.
>(There is a bit of a problem here in that most languages don't
>allow sufficient customization of class initialization to
>actually allow such a simple syntax, so mentally add whatever
>extra syntax or hacks are necessary)
>
>The problem with the above is that hooking
>
>struct _GtkCellEditableIface
>{
> GTypeInterface g_iface;
>
> [...]
>
> /* virtual table */
> void (* start_editing) (GtkCellEditable *cell_editable,
> GdkEvent *event);
>};
>
>into a language binding is hard because we need to assign something
>to the 'start_editing' vtable pointer. How we fix this once we have
>introspection information inside GTK+?
>
>Here's one scheme.
>
> typedef (*GInterfaceDemarshal) (GInterfaceDesc *interface_desc,
> GMethodDesc *method_desc,
> gpointer instance,
> GArgument *args,
> GArgument *return_value,
> gpointer data);
>
> g_type_add_interface_generic (GType interface_type,
> GType iface_type,
> GInterfaceDemarshal demarshal,
> gpointer data);
>
>The way this works is that
>
> g_type_add_interface_generic (MY_TYPE_FOO, GTK_TYPE_CELL_EDITABLE,
> demarshal, data);
>
>Stores GTK_TYPE_CELL_EDITABLE, demarshal, and data off in qdata
>associated with MY_TYPE_FOO. Then allocates a structure for
>GtkCellEditableIface and fills in start_editing with a pointer
>to:
>
> void
> _g_generic_demarshal_1 (GTypeInstance *instance);
> {
> GenericDemarshalData *data;
> GArgument *arguments;
> GArgument return;
>
> data = lookup_demarshal_data (instance, 1);
> /* libffi magic to demarshal to arguments */
>
> demarshal_data_invoke (data, arguments, &return);
>
> /* libffi magic to marshal the return value */
> }
>
>We have a big pile of these _1, _2, ... so that we can handle
>objects with up to say 256 interface methods that could be
>overridden.
I was kind of following your proposal, in spite of its complexity, but
I was expecting to see, in _g_generic_demarshal_1, a function pointer of
type GInterfaceDemarshal somewhere, and it being actually used.
Otherwise, why bother defining it and registering it in the first place?
>
>You could similarly have a g_type_register_generic() to
>handle virtual method overriding in derivation.
>
>A variant of this is to have GGenericDemarshal as an interface you
>can add to a type with demarshal_interface, demarshal_object as methods,
>and abbreviate g_type_add_interface_generic() to:
>
> g_type_add_interface_generic (GType interface_type,
> GType iface_type);
Hm... not sure about this alternative, seems a bit indirect route to
accomplish the same that is more explicit/clear in the first proposal.
Anyway, this stuff is starting to look good! :-)
Regards.
--
Gustavo J. A. M. Carneiro
<gjc inescporto pt> <gustavo users sourceforge net>
The universe is always one step beyond logic
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]