Re: Closure chaining



On Fri, 14 Dec 2001, James Henstridge wrote:

> Tim Janik wrote:
> 
> >- g_signal_chain_from_overridden() currently takes a signal_id argument, but
> >  doesn't strictly need it, because it is looking up the innermost emission
> >  anyways. if passing in the signal_id causes extra user-visible hassle for
> >  language bindings (such as having to pass the signal name or id upon
> >  chaining), i'd rather get rid of it.
> >
> Getting rid of the signal_id argument is fine, as long as you provide 
> some other API for getting the id of the innermose emission, so I can 
> correctly parse the arguments to chain() in the language binding.

> >- testcode needs to be written for this, to sufficiently test closure
> >  chaining, the testcode should at least do:
> >  objects: A<-B<-C, interfaces: I
> >  signal_new (A, "bar");
> >  closure_override (B, "bar");
> >  closure_override (C, "bar");
> >  emit (obj, "bar"), chain, and check that all of C's, B's and A's class
> >  closures are called in that order.
> >  signal_new (I, "foo");
> >  iface_add (A, I);
> >  closure_override (A, "foo");
> >  closure_override (B, "foo");
> >  closure_override (C, "foo");
> >  emit (obj, "foo"), chain, and check that all of C's, B's and A's and
> >  I's class closures are called in that order.
> >
> Attached is a program that tests the above.  Everything seems to be 
> working as expected.

great, beutifull test program!
can you put that into CVS?

now to the hard part, we currently have:
void    g_signal_override_class_closure       (guint              signal_id,
                                               GType              instance_type,
                                               GClosure          *class_closure);
void    g_signal_chain_from_overridden        (const GValue      *instance_and_params,
                                               guint              signal_id,
                                               GValue            *return_value);

g_signal_chain_from_overridden() can "mostly" figure the innermost
signal being emitted by walking it's emission lists.
however, since we keep two emission lists, one for normal signals,
and one for non-recurse signals, it may end up having two suitable
candidates for the innermost emission.
now, what i'm pondering is:

void    g_signal_override_class_closure       (guint              signal_id,
                                               GType              instance_type,
                                               GClosure          *class_closure);
void    g_signal_chain_from_overridden        (const GValue      *instance_and_params,
                                               GValue            *return_value);
GSignalInvocationHint* g_signal_get_invocation_hint (gpointer instance);

g_signal_get_invocation_hint() will return the invocation hint of the
innermost signal emission of instance, and choose between the two
candidate emissions by memory location. emissions are stored on the
stack, so with a configure.in check that tells us whether the stack
grows upwards or downwards, we can tell which emission was most
recently allocated.

API wise, this means that we have one source incompatible change, i.e.
getting rid of the GType signal_id in g_signal_chain_from_overridden(),
a function which works for less than 24 hours now, so there shouldn't
be any third party code depending on it. and we have one API addition,
g_signal_get_invocation_hint().

if the gnome-2-0 people want to play freeze-hardliners, we could also
change things towards:

void g_signal_override_class_closure (guint     signal_id,
                                      GType     reserved_arg_pass_as_0,
                                      GClosure *class_closure);
however, i wouldn't recommend that, especially since there's no practical
need to maintain the signature yet.

> 
> James.
> 

---
ciaoTJ




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