diff options
Diffstat (limited to 'gobject')
-rw-r--r-- | gobject/ChangeLog | 15 | ||||
-rw-r--r-- | gobject/gsignal.c | 82 | ||||
-rw-r--r-- | gobject/gsignal.h | 2 | ||||
-rw-r--r-- | gobject/testoverride.c | 15 |
4 files changed, 77 insertions, 37 deletions
diff --git a/gobject/ChangeLog b/gobject/ChangeLog index 40cd87468..ccdc94072 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,18 @@ +Tue Dec 18 21:39:57 2001 Tim Janik <timj@gtk.org> + + * testoverride.c: added some assertions to test + g_signal_get_invocation_hint(). + + * gsignal.[hc]: remove signal_id argument from + g_signal_chain_from_overridden(), the parameters are assumed to match + the innermost signal currently in emission for this instance. + added g_signal_get_invocation_hint() to figure the invocation hint + of the innermost signal emission of an instance. + + * gsignal.c (g_signal_list_ids): fix G_BSEARCH_ARRAY_NODES() to + access a bsearch array and not a pointer to it (discovered by + Sven Neumann). + 2001-12-17 Anders Carlsson <andersca@gnu.org> * gtype.h (G_TYPE_FLAG_RESERVED_ID_BIT): Set the reserved bit diff --git a/gobject/gsignal.c b/gobject/gsignal.c index 40780dca3..20c826e4c 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -657,15 +657,28 @@ emission_find (Emission *emission_list, } static inline Emission* -emission_find_innermost (Emission *emission_list, - gpointer instance) +emission_find_innermost (gpointer instance) { - Emission *emission; + Emission *emission, *s = NULL, *c = NULL; - for (emission = emission_list; emission; emission = emission->next) + for (emission = g_restart_emissions; emission; emission = emission->next) if (emission->instance == instance) - return emission; - return NULL; + { + s = emission; + break; + } + for (emission = g_recursive_emissions; emission; emission = emission->next) + if (emission->instance == instance) + { + c = emission; + break; + } + if (!s) + return c; + else if (!c) + return s; + else + return G_HAVE_GROWING_STACK ? MAX (c, s) : MIN (c, s); } static gint @@ -1008,7 +1021,7 @@ g_signal_list_ids (GType itype, g_return_val_if_fail (n_ids != NULL, NULL); SIGNAL_LOCK (); - keys = G_BSEARCH_ARRAY_NODES (&g_signal_key_bsa); + keys = G_BSEARCH_ARRAY_NODES (g_signal_key_bsa); n_nodes = g_signal_key_bsa->n_nodes; result = g_array_new (FALSE, FALSE, sizeof (guint)); @@ -1389,10 +1402,10 @@ g_signal_override_class_closure (guint signal_id, GClosure *class_closure) { SignalNode *node; - + g_return_if_fail (signal_id > 0); g_return_if_fail (class_closure != NULL); - + SIGNAL_LOCK (); node = LOOKUP_SIGNAL_NODE (signal_id); if (!g_type_is_a (instance_type, node->itype)) @@ -1400,7 +1413,7 @@ g_signal_override_class_closure (guint signal_id, else { ClassClosure *cc = signal_find_class_closure (node, instance_type); - + if (cc && cc->instance_type == instance_type) g_warning ("%s: type `%s' is already overridden for signal id `%u'", G_STRLOC, g_type_name (instance_type), signal_id); else @@ -1411,42 +1424,35 @@ g_signal_override_class_closure (guint signal_id, void g_signal_chain_from_overridden (const GValue *instance_and_params, - guint signal_id, GValue *return_value) { GType chain_type = 0, restore_type = 0; Emission *emission = NULL; GClosure *closure = NULL; + guint n_params = 0; gpointer instance; - SignalNode *node; g_return_if_fail (instance_and_params != NULL); instance = g_value_peek_pointer (instance_and_params); g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); - g_return_if_fail (signal_id > 0); SIGNAL_LOCK (); - node = LOOKUP_SIGNAL_NODE (signal_id); - if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) + emission = emission_find_innermost (instance); + if (emission) { - Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; - - emission = emission_find_innermost (emission_list, instance); - - /* what we don't catch here is the scenario: - * 1) signal1 being in class_closure, emitting signal2 - * 2) signal2 being in class closure, trying to chain signal1 - * 3) signal1&G_SIGNAL_NO_RECURSE != signal2&G_SIGNAL_NO_RECURSE. - * - * also, it'd be a good idea to perform the same checks on parameters - * as g_signal_emitv() here. + SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); + + g_assert (node != NULL); /* paranoid */ + + /* we should probably do the same parameter checks as g_signal_emit() here. */ - if (emission && emission->ihint.signal_id == signal_id && emission->chain_type != G_TYPE_NONE) + if (emission->chain_type != G_TYPE_NONE) { ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); - + g_assert (cc != NULL); /* closure currently in call stack */ + n_params = node->n_params; restore_type = cc->instance_type; cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); if (cc && cc->instance_type != restore_type) @@ -1456,17 +1462,17 @@ g_signal_chain_from_overridden (const GValue *instance_and_params, } } else - g_warning ("%s: signal id `%u' is not innermost class closure emission for instance `%p'", G_STRLOC, signal_id, instance); + g_warning ("%s: signal id `%u' cannot be chained from current emission stage for instance `%p'", G_STRLOC, node->signal_id, instance); } else - g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); + g_warning ("%s: no signal is currently being emitted for instance `%p'", G_STRLOC, instance); if (closure) { emission->chain_type = chain_type; SIGNAL_UNLOCK (); g_closure_invoke (closure, return_value, - node->n_params + 1, + n_params + 1, instance_and_params, &emission->ihint); SIGNAL_LOCK (); @@ -1475,6 +1481,20 @@ g_signal_chain_from_overridden (const GValue *instance_and_params, SIGNAL_UNLOCK (); } +GSignalInvocationHint* +g_signal_get_invocation_hint (gpointer instance) +{ + Emission *emission = NULL; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL); + + SIGNAL_LOCK (); + emission = emission_find_innermost (instance); + SIGNAL_UNLOCK (); + + return emission ? &emission->ihint : NULL; +} + gulong g_signal_connect_closure_by_id (gpointer instance, guint signal_id, diff --git a/gobject/gsignal.h b/gobject/gsignal.h index 6b9628581..9e3de1065 100644 --- a/gobject/gsignal.h +++ b/gobject/gsignal.h @@ -152,6 +152,7 @@ gboolean g_signal_parse_name (const gchar *detailed_signal, guint *signal_id_p, GQuark *detail_p, gboolean force_detail_quark); +GSignalInvocationHint* g_signal_get_invocation_hint (gpointer instance); /* --- signal emissions --- */ @@ -232,7 +233,6 @@ 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); diff --git a/gobject/testoverride.c b/gobject/testoverride.c index d8bbb1efc..2ac34e9f2 100644 --- a/gobject/testoverride.c +++ b/gobject/testoverride.c @@ -100,7 +100,8 @@ test_a_foo (TestI *self) g_value_init (&args[0], TEST_TYPE_A); g_value_set_object (&args[0], self); - g_signal_chain_from_overridden (args, foo_signal_id, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); g_value_unset (&args[0]); } @@ -193,7 +194,8 @@ test_b_foo (TestA *self) g_value_init (&args[0], TEST_TYPE_A); g_value_set_object (&args[0], self); - g_signal_chain_from_overridden (args, foo_signal_id, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); g_value_unset (&args[0]); } @@ -208,7 +210,8 @@ test_b_bar (TestI *self) g_value_init (&args[0], TEST_TYPE_A); g_value_set_object (&args[0], self); - g_signal_chain_from_overridden (args, bar_signal_id, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); g_value_unset (&args[0]); } @@ -279,7 +282,8 @@ test_c_foo (TestA *self) g_value_init (&args[0], TEST_TYPE_A); g_value_set_object (&args[0], self); - g_signal_chain_from_overridden (args, foo_signal_id, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); g_value_unset (&args[0]); } @@ -294,7 +298,8 @@ test_c_bar (TestI *self) g_value_init (&args[0], TEST_TYPE_A); g_value_set_object (&args[0], self); - g_signal_chain_from_overridden (args, bar_signal_id, NULL); + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); g_value_unset (&args[0]); } |