mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-15 04:05:11 +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_data
|
||||||
g_signal_group_connect_object
|
g_signal_group_connect_object
|
||||||
g_signal_group_connect_swapped
|
g_signal_group_connect_swapped
|
||||||
|
g_signal_group_connect_closure
|
||||||
g_signal_group_dup_target
|
g_signal_group_dup_target
|
||||||
g_signal_group_get_type
|
g_signal_group_get_type
|
||||||
g_signal_group_new
|
g_signal_group_new
|
||||||
|
@ -705,18 +705,28 @@ g_signal_group_new (GType target_type)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
g_signal_group_connect_full (GSignalGroup *self,
|
* g_signal_group_connect_closure:
|
||||||
const gchar *detailed_signal,
|
* @self: a #GSignalGroup
|
||||||
GCallback c_handler,
|
* @detailed_signal: a string of the form `signal-name` with optional `::signal-detail`
|
||||||
gpointer data,
|
* @closure: (not nullable): the closure to connect.
|
||||||
GClosureNotify notify,
|
* @after: whether the handler should be called before or after the
|
||||||
GConnectFlags flags,
|
* default handler of the signal.
|
||||||
gboolean is_object)
|
*
|
||||||
|
* 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;
|
GObject *target;
|
||||||
SignalHandler *handler;
|
SignalHandler *handler;
|
||||||
GClosure *closure;
|
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
GQuark signal_detail;
|
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 (detailed_signal != NULL);
|
||||||
g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
|
g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
|
||||||
&signal_id, &signal_detail, TRUE) != 0);
|
&signal_id, &signal_detail, TRUE) != 0);
|
||||||
g_return_if_fail (c_handler != NULL);
|
g_return_if_fail (closure != NULL);
|
||||||
g_return_if_fail (!is_object || G_IS_OBJECT (data));
|
|
||||||
|
|
||||||
g_rec_mutex_lock (&self->mutex);
|
g_rec_mutex_lock (&self->mutex);
|
||||||
|
|
||||||
@ -736,29 +745,15 @@ g_signal_group_connect_full (GSignalGroup *self,
|
|||||||
return;
|
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 = g_slice_new0 (SignalHandler);
|
||||||
handler->group = self;
|
handler->group = self;
|
||||||
handler->signal_id = signal_id;
|
handler->signal_id = signal_id;
|
||||||
handler->signal_detail = signal_detail;
|
handler->signal_detail = signal_detail;
|
||||||
handler->closure = g_closure_ref (closure);
|
handler->closure = g_closure_ref (closure);
|
||||||
handler->connect_after = ((flags & G_CONNECT_AFTER) != 0);
|
handler->connect_after = after;
|
||||||
|
|
||||||
g_closure_sink (closure);
|
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);
|
g_ptr_array_add (self->handlers, handler);
|
||||||
|
|
||||||
target = g_weak_ref_get (&self->target_ref);
|
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);
|
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)
|
* g_signal_group_connect_object: (skip)
|
||||||
* @self: a #GSignalGroup
|
* @self: a #GSignalGroup
|
||||||
|
@ -59,6 +59,11 @@ GLIB_AVAILABLE_IN_2_72
|
|||||||
void g_signal_group_block (GSignalGroup *self);
|
void g_signal_group_block (GSignalGroup *self);
|
||||||
GLIB_AVAILABLE_IN_2_72
|
GLIB_AVAILABLE_IN_2_72
|
||||||
void g_signal_group_unblock (GSignalGroup *self);
|
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
|
GLIB_AVAILABLE_IN_2_72
|
||||||
void g_signal_group_connect_object (GSignalGroup *self,
|
void g_signal_group_connect_object (GSignalGroup *self,
|
||||||
const gchar *detailed_signal,
|
const gchar *detailed_signal,
|
||||||
|
@ -107,7 +107,7 @@ connect_after_cb (SignalTarget *target,
|
|||||||
g_assert_true (readback == target);
|
g_assert_true (readback == target);
|
||||||
g_object_unref (readback);
|
g_object_unref (readback);
|
||||||
|
|
||||||
g_assert_cmpint (*signal_calls, ==, 4);
|
g_assert_cmpint (*signal_calls, ==, 5);
|
||||||
*signal_calls += 1;
|
*signal_calls += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +194,8 @@ connect_data_weak_notify_cb (gboolean *weak_notify_called,
|
|||||||
static void
|
static void
|
||||||
connect_all_signals (GSignalGroup *group)
|
connect_all_signals (GSignalGroup *group)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
|
GClosure *closure;
|
||||||
|
|
||||||
/* Check that these are called in the right order */
|
/* Check that these are called in the right order */
|
||||||
g_signal_group_connect (group,
|
g_signal_group_connect (group,
|
||||||
@ -245,6 +246,20 @@ connect_all_signals (GSignalGroup *group)
|
|||||||
g_object_weak_ref (G_OBJECT (group),
|
g_object_weak_ref (G_OBJECT (group),
|
||||||
(GWeakNotify)connect_data_weak_notify_cb,
|
(GWeakNotify)connect_data_weak_notify_cb,
|
||||||
&global_weak_notify_called);
|
&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
|
static void
|
||||||
@ -258,7 +273,7 @@ assert_signals (SignalTarget *target,
|
|||||||
global_signal_calls = 0;
|
global_signal_calls = 0;
|
||||||
g_signal_emit (target, signals[THE_SIGNAL],
|
g_signal_emit (target, signals[THE_SIGNAL],
|
||||||
signal_detail_quark (), group);
|
signal_detail_quark (), group);
|
||||||
g_assert_cmpint (global_signal_calls, ==, success ? 5 : 0);
|
g_assert_cmpint (global_signal_calls, ==, success ? 6 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user