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 <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> The universe is always one step beyond logic _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list