Re: [Language Binders] Re: Chaining Class Closures



Tim Janik wrote:

On Fri, 19 Oct 2001, Tim Janik wrote:

a long outstanding issue in the signal system is chaining from
class signal handlers to parent class signal handlers in language
bindings where custom closures are being used.
to enable that facility, i propose the addition of two new functions,
and like to discuss the public API here.


[...]

comments, especially from LB authors, are apprechiated.


hm, i whished for at least one or two comments from LB authors on whether
they think this will suit their needs.

or maybe just "i didn't understand your proposal, could you elaborate
on <foo>?" ;)

so any comments are aprechiated, even if it's just "this is fine, go
for it", for reference, the original mail is at:

http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00308.html

Sorry for not replying earlier. Here is how class closures are handled in pygtk for new signals at the moment:

I always use the same closure object for all signals created from python. This closure looks up the wrapper for the first object passed as the first argument. It then checks to see if the instance has a do_signalname (where signalname is the name of the signal, as given in the invocation hint) method. If found, it calls the method with the rest of the parameters. Chaining between python classes is just done by calling the do_signalname() method of the parent class.

What you have suggested sounds like it will work fine for pygtk. I will probably pass an opaque python object as an extra argument to the signal class closure that holds the signal invocation hint (that is the easiest way to keep track of things). Probably make the invocation hint wrapper object callable as a way of chaining to the parent handler would make sense. So the python object that overrides a non python signal might look something like this:

 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)

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

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

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]