Re: [Language Binders] Re: Chaining Class Closures
- From: James Henstridge <james daa com au>
- To: Tim Janik <timj gtk org>
- Cc: Gtk+ Developers <gtk-devel-list gnome org>
- Subject: Re: [Language Binders] Re: Chaining Class Closures
- Date: Tue, 30 Oct 2001 10:26:25 +1100
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]