Re: [Language Binders] Re: Chaining Class Closures



Tim Janik wrote:

On Tue, 30 Oct 2001, James Henstridge wrote:

 class PythonWidget(gtk.Widget):
     def do_show(self, invocation_hint):
         print "show!"
         return invocation_hint()  # or possibly pass the self arg as well?
 gobject.type_register(PythonWidget)
 gobject.override_class_closure(PythonWidget, 'show')

I might make this simpler in the future by making gobject.type_register search for signals to override (list all signals of the parent class, check for equivalent methods on the new class). However, this would require initialising the class structure of every type that gets overriden on startup. I don't yet know if that is acceptable.

One thing which isn't completely clear is whether g_signal_chain_from_overridden chains up to the direct parent, or to the class above where the class where the signal closure was overriden. I would prefer that it goes up to the previous class closure, so that overriding an already overriden signal in python is a bit easier:
 class PythonWidget2(PythonWidget):
     def show(self, invocation_hint):
         print "chaining up to PythonWidget"
         return PythonWidget.show(self, invocation_hint)
 gobject.type_register(PythonWidget2)

Of course, this should be PythonWidget2.do_show and PythonWidget.do_show :(



If g_signal_chain_from_overriden chained up to the next class, the procedure would go:
 PythonWidget2.show called by signal class closure marshal
 PythonWidget.show called by PythonWidget2.show
 invocation_hint() executed, calling class closure for PythonWidget class
 PythonWidget2.show called by signal class closure marshal
 PythonWidget.show called by PythonWidget2.show
 invocation_hint() executed, calling class closure for GtkWidget class
 gtk_widget_real_show() called


erm, i can't make too much sense of this, why would PythonWidget2.show
be called twice?

The current closure marshal I am using in pygtk gets the wrapper for the object the signal is being emitted for (note that the same wrapper is used every time that particular GObject is used in python). Emitting the "show" signal on a PythonWidget2 instance the second time will still pick up the PythonWidget2.do_show() implementation rather than the PythonWidget.do_show one.

The idea is that python subclasses would only need to override the class closure once, and use normal python method chaining between python classes.



in any case, i think i can make things clearer by telling how the signal system
should handle this, suppose you derive:
A<-B<-C<-D<-E<-F
and install closures (through signal_new() or g_signal_override_class_closure(),
internally, that's the same):
add_closure (A, Aclosure);
add_closure (C, Cclosure);
add_closure (E, Eclosure);

with Eclosure doing { chain (invocation_hint); }
and Cclosure doing { chain (invocation_hint); }

then things should work as follows:

emitting signal on object of type F:
 type = F; closure = NULL;
 while (!closure) {
   closure = fetch_closure (type);
   type = parent_type (type);
 }
 invocation_hint->type = type;
 /* this ends up with:
  * closure == Eclosure and
  * invocation_hint->type == D, since
  * there was no closure added to F, and because
  * D is parent type of E
  */
 closure(invocation_hint);

chaining from Eclosure:
 type = invocation_hint->type; /* D */
 closure = NULL;
 while (!closure) {
   closure = fetch_closure (type);
   type = parent_type (type);
 }
 invocation_hint->type = type;
 /* this ends up with:
  * closure == Cclosure;
  * invocation_hint->type == B
  */

and finally chaining from Cclosure:
 type = invocation_hint->type; /* B */
 closure = NULL;
 while (!closure) {
   closure = fetch_closure (type);
   type = parent_type (type);
 }
 invocation_hint->type = type;
 /* this ends up with:
  * closure == Aclosure;
  * invocation_hint->type == 0
  */

If g_signal_chain_from_overriden immediately chains to GtkWidget's implementation, everything should work fine.


when calling a function implemented by a certain type,
g_signal_chain_from_overriden() will chain up to the nextmost parent type
which provides a closure. so as long as you override every gtk-created
signal only once, the nextmost parent type providing a closure should always
be a gtk implemented widget.

Cool.  That sounds like it should work well for my python bindings then.

James.

--
Email: james daa com au
WWW:   http://www.daa.com.au/~james/







[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]