gsignal: Add a new GSignalFlag to mark the first run of an accumulator function

Also add a test for signal accumulators. There was none before, and this
one now also covers the new flag.

Fixes https://gitlab.gnome.org/GNOME/glib/issues/514
This commit is contained in:
Sebastian Dröge
2012-02-16 10:09:27 +01:00
committed by Philip Withnall
parent 2008cb58a4
commit 9d1455444c
3 changed files with 121 additions and 7 deletions

View File

@@ -1717,6 +1717,7 @@ g_signal_newv (const gchar *signal_name,
g_return_val_if_fail (accumulator == NULL, 0);
if (!accumulator)
g_return_val_if_fail (accu_data == NULL, 0);
g_return_val_if_fail ((signal_flags & G_SIGNAL_ACCUMULATOR_FIRST_RUN) == 0, 0);
if (!is_canonical (signal_name))
{
@@ -3241,6 +3242,8 @@ accumulate (GSignalInvocationHint *ihint,
continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
g_value_reset (handler_return);
ihint->run_type &= ~G_SIGNAL_ACCUMULATOR_FIRST_RUN;
return continue_emission;
}
@@ -3380,7 +3383,7 @@ g_signal_emit_valist (gpointer instance,
emission.instance = instance;
emission.ihint.signal_id = signal_id;
emission.ihint.detail = detail;
emission.ihint.run_type = run_type;
emission.ihint.run_type = run_type | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
emission.state = EMISSION_RUN;
emission.chain_type = instance_type;
emission_push (&emission);
@@ -3658,7 +3661,7 @@ signal_emit_unlocked_R (SignalNode *node,
if (handler_list)
handler_ref (handler_list);
emission.ihint.run_type = G_SIGNAL_RUN_FIRST;
emission.ihint.run_type = G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
{
@@ -3766,7 +3769,8 @@ signal_emit_unlocked_R (SignalNode *node,
goto EMIT_RESTART;
}
emission.ihint.run_type = G_SIGNAL_RUN_LAST;
emission.ihint.run_type &= ~G_SIGNAL_RUN_FIRST;
emission.ihint.run_type |= G_SIGNAL_RUN_LAST;
if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
{
@@ -3837,7 +3841,8 @@ signal_emit_unlocked_R (SignalNode *node,
EMIT_CLEANUP:
emission.ihint.run_type = G_SIGNAL_RUN_CLEANUP;
emission.ihint.run_type &= ~G_SIGNAL_RUN_LAST;
emission.ihint.run_type |= G_SIGNAL_RUN_CLEANUP;
if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
{