mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-14 19:55:12 +01:00
Merge branch 'signal-group-connect-object' into 'main'
gobject: Add g_signal_group_connect_closure See merge request GNOME/glib!2521
This commit is contained in:
commit
59751e86fd
@ -1034,6 +1034,7 @@ g_signal_group_connect_after
|
||||
g_signal_group_connect_data
|
||||
g_signal_group_connect_object
|
||||
g_signal_group_connect_swapped
|
||||
g_signal_group_connect_closure
|
||||
g_signal_group_dup_target
|
||||
g_signal_group_get_type
|
||||
g_signal_group_new
|
||||
|
@ -705,18 +705,28 @@ g_signal_group_new (GType target_type)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
g_signal_group_connect_full (GSignalGroup *self,
|
||||
const gchar *detailed_signal,
|
||||
GCallback c_handler,
|
||||
gpointer data,
|
||||
GClosureNotify notify,
|
||||
GConnectFlags flags,
|
||||
gboolean is_object)
|
||||
/**
|
||||
* g_signal_group_connect_closure:
|
||||
* @self: a #GSignalGroup
|
||||
* @detailed_signal: a string of the form `signal-name` with optional `::signal-detail`
|
||||
* @closure: (not nullable): the closure to connect.
|
||||
* @after: whether the handler should be called before or after the
|
||||
* default handler of the signal.
|
||||
*
|
||||
* Connects @closure to the signal @detailed_signal on #GSignalGroup:target.
|
||||
*
|
||||
* You cannot connect a signal handler after #GSignalGroup:target has been set.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_signal_group_connect_closure (GSignalGroup *self,
|
||||
const gchar *detailed_signal,
|
||||
GClosure *closure,
|
||||
gboolean after)
|
||||
{
|
||||
GObject *target;
|
||||
SignalHandler *handler;
|
||||
GClosure *closure;
|
||||
guint signal_id;
|
||||
GQuark signal_detail;
|
||||
|
||||
@ -724,8 +734,7 @@ g_signal_group_connect_full (GSignalGroup *self,
|
||||
g_return_if_fail (detailed_signal != NULL);
|
||||
g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
|
||||
&signal_id, &signal_detail, TRUE) != 0);
|
||||
g_return_if_fail (c_handler != NULL);
|
||||
g_return_if_fail (!is_object || G_IS_OBJECT (data));
|
||||
g_return_if_fail (closure != NULL);
|
||||
|
||||
g_rec_mutex_lock (&self->mutex);
|
||||
|
||||
@ -736,29 +745,15 @@ g_signal_group_connect_full (GSignalGroup *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & G_CONNECT_SWAPPED) != 0)
|
||||
closure = g_cclosure_new_swap (c_handler, data, notify);
|
||||
else
|
||||
closure = g_cclosure_new (c_handler, data, notify);
|
||||
|
||||
handler = g_slice_new0 (SignalHandler);
|
||||
handler->group = self;
|
||||
handler->signal_id = signal_id;
|
||||
handler->signal_detail = signal_detail;
|
||||
handler->closure = g_closure_ref (closure);
|
||||
handler->connect_after = ((flags & G_CONNECT_AFTER) != 0);
|
||||
handler->connect_after = after;
|
||||
|
||||
g_closure_sink (closure);
|
||||
|
||||
if (is_object)
|
||||
{
|
||||
/* Set closure->is_invalid when data is disposed. We only track this to avoid
|
||||
* reconnecting in the future. However, we do a round of cleanup when ever we
|
||||
* connect a new object or the target changes to GC the old handlers.
|
||||
*/
|
||||
g_object_watch_closure (data, closure);
|
||||
}
|
||||
|
||||
g_ptr_array_add (self->handlers, handler);
|
||||
|
||||
target = g_weak_ref_get (&self->target_ref);
|
||||
@ -775,6 +770,40 @@ g_signal_group_connect_full (GSignalGroup *self,
|
||||
g_rec_mutex_unlock (&self->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
g_signal_group_connect_full (GSignalGroup *self,
|
||||
const gchar *detailed_signal,
|
||||
GCallback c_handler,
|
||||
gpointer data,
|
||||
GClosureNotify notify,
|
||||
GConnectFlags flags,
|
||||
gboolean is_object)
|
||||
{
|
||||
GClosure *closure;
|
||||
|
||||
g_return_if_fail (c_handler != NULL);
|
||||
g_return_if_fail (!is_object || G_IS_OBJECT (data));
|
||||
|
||||
if ((flags & G_CONNECT_SWAPPED) != 0)
|
||||
closure = g_cclosure_new_swap (c_handler, data, notify);
|
||||
else
|
||||
closure = g_cclosure_new (c_handler, data, notify);
|
||||
|
||||
if (is_object)
|
||||
{
|
||||
/* Set closure->is_invalid when data is disposed. We only track this to avoid
|
||||
* reconnecting in the future. However, we do a round of cleanup when ever we
|
||||
* connect a new object or the target changes to GC the old handlers.
|
||||
*/
|
||||
g_object_watch_closure (data, closure);
|
||||
}
|
||||
|
||||
g_signal_group_connect_closure (self,
|
||||
detailed_signal,
|
||||
closure,
|
||||
(flags & G_CONNECT_AFTER) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_signal_group_connect_object: (skip)
|
||||
* @self: a #GSignalGroup
|
||||
|
@ -59,6 +59,11 @@ GLIB_AVAILABLE_IN_2_72
|
||||
void g_signal_group_block (GSignalGroup *self);
|
||||
GLIB_AVAILABLE_IN_2_72
|
||||
void g_signal_group_unblock (GSignalGroup *self);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_signal_group_connect_closure (GSignalGroup *self,
|
||||
const gchar *detailed_signal,
|
||||
GClosure *closure,
|
||||
gboolean after);
|
||||
GLIB_AVAILABLE_IN_2_72
|
||||
void g_signal_group_connect_object (GSignalGroup *self,
|
||||
const gchar *detailed_signal,
|
||||
|
@ -107,7 +107,7 @@ connect_after_cb (SignalTarget *target,
|
||||
g_assert_true (readback == target);
|
||||
g_object_unref (readback);
|
||||
|
||||
g_assert_cmpint (*signal_calls, ==, 4);
|
||||
g_assert_cmpint (*signal_calls, ==, 5);
|
||||
*signal_calls += 1;
|
||||
}
|
||||
|
||||
@ -194,7 +194,8 @@ connect_data_weak_notify_cb (gboolean *weak_notify_called,
|
||||
static void
|
||||
connect_all_signals (GSignalGroup *group)
|
||||
{
|
||||
GObject *object;
|
||||
GObject *object;
|
||||
GClosure *closure;
|
||||
|
||||
/* Check that these are called in the right order */
|
||||
g_signal_group_connect (group,
|
||||
@ -245,6 +246,20 @@ connect_all_signals (GSignalGroup *group)
|
||||
g_object_weak_ref (G_OBJECT (group),
|
||||
(GWeakNotify)connect_data_weak_notify_cb,
|
||||
&global_weak_notify_called);
|
||||
|
||||
|
||||
/* Check that this can be called as a GClosure */
|
||||
closure = g_cclosure_new (G_CALLBACK (connect_before_cb),
|
||||
&global_signal_calls,
|
||||
NULL);
|
||||
g_signal_group_connect_closure (group, "the-signal", closure, FALSE);
|
||||
|
||||
/* Check that invalidated GClosures don't get called */
|
||||
closure = g_cclosure_new (G_CALLBACK (connect_before_cb),
|
||||
&global_signal_calls,
|
||||
NULL);
|
||||
g_closure_invalidate (closure);
|
||||
g_signal_group_connect_closure (group, "the-signal", closure, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -258,7 +273,7 @@ assert_signals (SignalTarget *target,
|
||||
global_signal_calls = 0;
|
||||
g_signal_emit (target, signals[THE_SIGNAL],
|
||||
signal_detail_quark (), group);
|
||||
g_assert_cmpint (global_signal_calls, ==, success ? 5 : 0);
|
||||
g_assert_cmpint (global_signal_calls, ==, success ? 6 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
x
Reference in New Issue
Block a user