[glib: 1/2] gsignal: Allow return types for RUN_FIRST-only signals too
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] gsignal: Allow return types for RUN_FIRST-only signals too
- Date: Mon, 21 Dec 2020 17:40:29 +0000 (UTC)
commit 3581eda9a2ed8d7731ce80d16bb03d84ad251e92
Author: Sebastian Dröge <sebastian centricular com>
Date: Thu Feb 16 09:57:48 2012 +0100
gsignal: Allow return types for RUN_FIRST-only signals too
Also adds a test that checks that the G_SIGNAL_RUN flags are handled
correctly and the class signal handler is called at the right times.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/513
gobject/gsignal.c | 9 ----
gobject/tests/signals.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+), 9 deletions(-)
---
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index c3b453de7..d8a4cd9d9 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -1771,15 +1771,6 @@ g_signal_newv (const gchar *signal_name,
SIGNAL_UNLOCK ();
return 0;
}
- if (return_type != G_TYPE_NONE &&
- (signal_flags & (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP)) == G_SIGNAL_RUN_FIRST)
- {
- g_warning (G_STRLOC ": signal \"%s::%s\" has return type '%s' and is only G_SIGNAL_RUN_FIRST",
- type_debug_name (itype), name, type_debug_name (return_type));
- g_free (signal_name_copy);
- SIGNAL_UNLOCK ();
- return 0;
- }
/* setup permanent portion of signal node */
if (!node)
diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c
index 37d06a237..ea9a778bf 100644
--- a/gobject/tests/signals.c
+++ b/gobject/tests/signals.c
@@ -186,6 +186,8 @@ 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);
+static gboolean accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue
*handler_return, gpointer data);
+static gchar * accumulator_class (Test *test);
struct _TestClass
{
@@ -194,6 +196,7 @@ struct _TestClass
void (* variant_changed) (Test *, GVariant *);
void (* all_types) (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);
void (* all_types_null) (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);
+ gchar * (*accumulator_class) (Test *test);
};
static GType test_get_type (void);
@@ -213,6 +216,7 @@ test_class_init (TestClass *klass)
flags_type = g_flags_register_static ("MyFlag", my_flag_values);
klass->all_types = all_types_handler;
+ klass->accumulator_class = accumulator_class;
simple_id = g_signal_new ("simple",
G_TYPE_FROM_CLASS (klass),
@@ -247,6 +251,54 @@ test_class_init (TestClass *klass)
NULL,
G_TYPE_INT,
0);
+ g_signal_new ("accumulator-class-first",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
+ g_signal_new ("accumulator-class-last",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
+ g_signal_new ("accumulator-class-cleanup",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_CLEANUP,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
+ g_signal_new ("accumulator-class-first-last",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
+ g_signal_new ("accumulator-class-first-last-cleanup",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
+ g_signal_new ("accumulator-class-last-cleanup",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
+ G_STRUCT_OFFSET (TestClass, accumulator_class),
+ accumulator_concat_string, NULL,
+ NULL,
+ G_TYPE_STRING,
+ 0);
g_signal_new ("generic-marshaller-1",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
@@ -1227,6 +1279,76 @@ test_accumulator (void)
g_object_unref (test);
}
+static gboolean
+accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return,
gpointer data)
+{
+ const gchar *acc = g_value_get_string (return_accu);
+ const gchar *ret = g_value_get_string (handler_return);
+
+ g_assert_nonnull (ret);
+
+ if (acc == NULL)
+ g_value_set_string (return_accu, ret);
+ else
+ g_value_take_string (return_accu, g_strconcat (acc, ret, NULL));
+
+ return TRUE;
+}
+
+static gchar *
+accumulator_class_before_cb (gpointer instance, gpointer data)
+{
+ return g_strdup ("before");
+}
+
+static gchar *
+accumulator_class_after_cb (gpointer instance, gpointer data)
+{
+ return g_strdup ("after");
+}
+
+static gchar *
+accumulator_class (Test *test)
+{
+ return g_strdup ("class");
+}
+
+static void
+test_accumulator_class (void)
+{
+ const struct {
+ const gchar *signal_name;
+ const gchar *return_string;
+ } tests[] = {
+ {"accumulator-class-first", "classbeforeafter"},
+ {"accumulator-class-last", "beforeclassafter"},
+ {"accumulator-class-cleanup", "beforeafterclass"},
+ {"accumulator-class-first-last", "classbeforeclassafter"},
+ {"accumulator-class-first-last-cleanup", "classbeforeclassafterclass"},
+ {"accumulator-class-last-cleanup", "beforeclassafterclass"},
+ };
+ gsize i;
+
+ for (i = 0; i < G_N_ELEMENTS (tests); i++)
+ {
+ GObject *test;
+ gchar *ret = NULL;
+
+ g_test_message ("Signal: %s", tests[i].signal_name);
+
+ test = g_object_new (test_get_type (), NULL);
+
+ g_signal_connect (test, tests[i].signal_name, G_CALLBACK (accumulator_class_before_cb), NULL);
+ g_signal_connect_after (test, tests[i].signal_name, G_CALLBACK (accumulator_class_after_cb), NULL);
+ g_signal_emit_by_name (test, tests[i].signal_name, &ret);
+
+ g_assert_cmpstr (ret, ==, tests[i].return_string);
+ g_free (ret);
+
+ g_object_unref (test);
+ }
+}
+
static gboolean
in_set (const gchar *s,
const gchar *set[])
@@ -1254,6 +1376,12 @@ test_introspection (void)
"simple-detailed",
"simple-2",
"simple-accumulator",
+ "accumulator-class-first",
+ "accumulator-class-last",
+ "accumulator-class-cleanup",
+ "accumulator-class-first-last",
+ "accumulator-class-first-last-cleanup",
+ "accumulator-class-last-cleanup",
"generic-marshaller-1",
"generic-marshaller-2",
"generic-marshaller-enum-return-signed",
@@ -1680,6 +1808,7 @@ main (int argc,
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/accumulator-class", test_accumulator_class);
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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]