mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 07:23:41 +02:00
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:
committed by
Philip Withnall
parent
2008cb58a4
commit
9d1455444c
@@ -185,6 +185,7 @@ struct _Test
|
||||
};
|
||||
|
||||
static void all_types_handler (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64);
|
||||
static gboolean accumulator_sum (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data);
|
||||
|
||||
struct _TestClass
|
||||
{
|
||||
@@ -238,6 +239,14 @@ test_class_init (TestClass *klass)
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
g_signal_new ("simple-accumulator",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
accumulator_sum, NULL,
|
||||
NULL,
|
||||
G_TYPE_INT,
|
||||
0);
|
||||
g_signal_new ("generic-marshaller-1",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
@@ -1127,6 +1136,97 @@ test_invocation_hint (void)
|
||||
g_object_unref (test);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
accumulator_sum (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
{
|
||||
gint acc = g_value_get_int (return_accu);
|
||||
gint ret = g_value_get_int (handler_return);
|
||||
|
||||
g_assert_cmpint (ret, >, 0);
|
||||
|
||||
if (ihint->run_type & G_SIGNAL_ACCUMULATOR_FIRST_RUN)
|
||||
{
|
||||
g_assert_cmpint (acc, ==, 0);
|
||||
g_assert_cmpint (ret, ==, 1);
|
||||
g_assert_true (ihint->run_type & G_SIGNAL_RUN_FIRST);
|
||||
g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST);
|
||||
}
|
||||
else if (ihint->run_type & G_SIGNAL_RUN_FIRST)
|
||||
{
|
||||
/* Only the first signal handler was called so far */
|
||||
g_assert_cmpint (acc, ==, 1);
|
||||
g_assert_cmpint (ret, ==, 2);
|
||||
g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST);
|
||||
}
|
||||
else if (ihint->run_type & G_SIGNAL_RUN_LAST)
|
||||
{
|
||||
/* Only the first two signal handler were called so far */
|
||||
g_assert_cmpint (acc, ==, 3);
|
||||
g_assert_cmpint (ret, ==, 3);
|
||||
g_assert_false (ihint->run_type & G_SIGNAL_RUN_FIRST);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_value_set_int (return_accu, acc + ret);
|
||||
|
||||
/* Continue with the other signal handlers as long as the sum is < 6,
|
||||
* i.e. don't run simple_accumulator_4_cb() */
|
||||
return acc + ret < 6;
|
||||
}
|
||||
|
||||
static gint
|
||||
simple_accumulator_1_cb (gpointer instance, gpointer data)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gint
|
||||
simple_accumulator_2_cb (gpointer instance, gpointer data)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static gint
|
||||
simple_accumulator_3_cb (gpointer instance, gpointer data)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
static gint
|
||||
simple_accumulator_4_cb (gpointer instance, gpointer data)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static void
|
||||
test_accumulator (void)
|
||||
{
|
||||
GObject *test;
|
||||
gint ret = -1;
|
||||
|
||||
test = g_object_new (test_get_type (), NULL);
|
||||
|
||||
/* Connect in reverse order to make sure that LAST signal handlers are
|
||||
* called after FIRST signal handlers but signal handlers in each "group"
|
||||
* are called in the order they were registered */
|
||||
g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_3_cb), NULL);
|
||||
g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_4_cb), NULL);
|
||||
g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_1_cb), NULL);
|
||||
g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_2_cb), NULL);
|
||||
g_signal_emit_by_name (test, "simple-accumulator", &ret);
|
||||
|
||||
/* simple_accumulator_4_cb() is not run because accumulator is 6 */
|
||||
g_assert_cmpint (ret, ==, 6);
|
||||
|
||||
g_object_unref (test);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
in_set (const gchar *s,
|
||||
const gchar *set[])
|
||||
@@ -1153,6 +1253,7 @@ test_introspection (void)
|
||||
"simple",
|
||||
"simple-detailed",
|
||||
"simple-2",
|
||||
"simple-accumulator",
|
||||
"generic-marshaller-1",
|
||||
"generic-marshaller-2",
|
||||
"generic-marshaller-enum-return-signed",
|
||||
@@ -1578,6 +1679,7 @@ main (int argc,
|
||||
g_test_add_func ("/gobject/signals/custom-marshaller", test_custom_marshaller);
|
||||
g_test_add_func ("/gobject/signals/connect", test_connect);
|
||||
g_test_add_func ("/gobject/signals/emission-hook", test_emission_hook);
|
||||
g_test_add_func ("/gobject/signals/accumulator", test_accumulator);
|
||||
g_test_add_func ("/gobject/signals/introspection", test_introspection);
|
||||
g_test_add_func ("/gobject/signals/block-handler", test_block_handler);
|
||||
g_test_add_func ("/gobject/signals/stop-emission", test_stop_emission);
|
||||
|
Reference in New Issue
Block a user