builder: Use a GPtrArray when parsing signals

This commit is contained in:
Timm Bäder 2021-01-06 19:23:02 +01:00
parent aec2fb939f
commit de6cd4f0d2
3 changed files with 33 additions and 21 deletions

View File

@ -260,7 +260,7 @@ typedef struct
char *domain; char *domain;
GHashTable *objects; GHashTable *objects;
GSList *delayed_properties; GSList *delayed_properties;
GSList *signals; GPtrArray *signals;
GSList *bindings; GSList *bindings;
char *filename; char *filename;
char *resource_prefix; char *resource_prefix;
@ -375,8 +375,8 @@ gtk_builder_finalize (GObject *object)
#endif #endif
g_hash_table_destroy (priv->objects); g_hash_table_destroy (priv->objects);
if (priv->signals)
g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info); g_ptr_array_free (priv->signals, TRUE);
G_OBJECT_CLASS (gtk_builder_parent_class)->finalize (object); G_OBJECT_CLASS (gtk_builder_parent_class)->finalize (object);
} }
@ -1020,12 +1020,14 @@ _gtk_builder_add (GtkBuilder *builder,
void void
_gtk_builder_add_signals (GtkBuilder *builder, _gtk_builder_add_signals (GtkBuilder *builder,
GSList *signals) GPtrArray *signals)
{ {
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder); GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
priv->signals = g_slist_concat (priv->signals, if (G_UNLIKELY (!priv->signals))
g_slist_copy (signals)); priv->signals = g_ptr_array_new_with_free_func ((GDestroyNotify)_free_signal_info);
g_ptr_array_extend_and_steal (priv->signals, signals);
} }
static gboolean static gboolean
@ -1853,18 +1855,17 @@ gtk_builder_connect_signals (GtkBuilder *builder,
GError **error) GError **error)
{ {
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder); GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
GSList *l;
GObject *object; GObject *object;
GObject *connect_object; GObject *connect_object;
gboolean result = FALSE; gboolean result = TRUE;
if (!priv->signals) if (!priv->signals ||
priv->signals->len == 0)
return TRUE; return TRUE;
priv->signals = g_slist_reverse (priv->signals); for (guint i = 0; i < priv->signals->len; i++)
for (l = priv->signals; l; l = l->next)
{ {
SignalInfo *signal = (SignalInfo*)l->data; SignalInfo *signal = g_ptr_array_index (priv->signals, i);
GClosure *closure; GClosure *closure;
g_assert (signal != NULL); g_assert (signal != NULL);
@ -1897,7 +1898,10 @@ gtk_builder_connect_signals (GtkBuilder *builder,
error); error);
if (closure == NULL) if (closure == NULL)
break; {
result = false;
break;
}
g_signal_connect_closure_by_id (object, g_signal_connect_closure_by_id (object,
signal->id, signal->id,
@ -1905,10 +1909,8 @@ gtk_builder_connect_signals (GtkBuilder *builder,
closure, closure,
signal->flags & G_CONNECT_AFTER ? TRUE : FALSE); signal->flags & G_CONNECT_AFTER ? TRUE : FALSE);
} }
if (l == NULL)
result = TRUE;
g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info); g_ptr_array_free (priv->signals, TRUE);
priv->signals = NULL; priv->signals = NULL;
return result; return result;

View File

@ -797,7 +797,8 @@ free_object_info (ObjectInfo *info)
{ {
/* Do not free the signal items, which GtkBuilder takes ownership of */ /* Do not free the signal items, which GtkBuilder takes ownership of */
g_type_class_unref (info->oclass); g_type_class_unref (info->oclass);
g_slist_free (info->signals); if (info->signals)
g_ptr_array_free (info->signals, TRUE);
if (info->properties) if (info->properties)
g_ptr_array_free (info->properties, TRUE); g_ptr_array_free (info->properties, TRUE);
g_free (info->constructor); g_free (info->constructor);
@ -1955,7 +1956,12 @@ end_element (GtkBuildableParseContext *context,
if (GTK_IS_BUILDABLE (object_info->object) && if (GTK_IS_BUILDABLE (object_info->object) &&
GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished) GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished)
data->finalizers = g_slist_prepend (data->finalizers, object_info->object); data->finalizers = g_slist_prepend (data->finalizers, object_info->object);
_gtk_builder_add_signals (data->builder, object_info->signals);
if (object_info->signals)
{
_gtk_builder_add_signals (data->builder, object_info->signals);
object_info->signals = NULL;
}
free_object_info (object_info); free_object_info (object_info);
} }
@ -1973,7 +1979,11 @@ end_element (GtkBuildableParseContext *context,
ObjectInfo *object_info = (ObjectInfo*)state_peek_info (data, CommonInfo); ObjectInfo *object_info = (ObjectInfo*)state_peek_info (data, CommonInfo);
g_assert (object_info != NULL); g_assert (object_info != NULL);
signal_info->object_name = g_strdup (object_info->id); signal_info->object_name = g_strdup (object_info->id);
object_info->signals = g_slist_prepend (object_info->signals, signal_info);
if (G_UNLIKELY (!object_info->signals))
object_info->signals = g_ptr_array_new ();
g_ptr_array_add (object_info->signals, signal_info);
} }
else if (strcmp (element_name, "constant") == 0 || else if (strcmp (element_name, "constant") == 0 ||
strcmp (element_name, "closure") == 0 || strcmp (element_name, "closure") == 0 ||

View File

@ -48,7 +48,7 @@ typedef struct {
char *constructor; char *constructor;
GPtrArray *properties; GPtrArray *properties;
GSList *signals; GPtrArray *signals;
GSList *bindings; GSList *bindings;
GObject *object; GObject *object;
@ -220,7 +220,7 @@ void _gtk_builder_add_object (GtkBuilder *builder,
void _gtk_builder_add (GtkBuilder *builder, void _gtk_builder_add (GtkBuilder *builder,
ChildInfo *child_info); ChildInfo *child_info);
void _gtk_builder_add_signals (GtkBuilder *builder, void _gtk_builder_add_signals (GtkBuilder *builder,
GSList *signals); GPtrArray *signals);
gboolean _gtk_builder_finish (GtkBuilder *builder, gboolean _gtk_builder_finish (GtkBuilder *builder,
GError **error); GError **error);
void _free_signal_info (SignalInfo *info, void _free_signal_info (SignalInfo *info,