summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@gnome.org>2015-09-24 13:21:15 +0200
committerThibault Saunier <tsaunier@gnome.org>2015-09-24 13:27:16 +0200
commit822e0a7b09b4da360736d1c1e727584f2a9eca53 (patch)
treebdcff8dea43cb1b5ee2a5600073bdfc79d7e8da0
parentbd1d03202bdd278df7db3558e9df49082ade485d (diff)
ges: Avoid emitting 'child-added/removed' when signal emission stops addition
In the GESTimeline, TrackElement addition to a clip might get cancelled (and thus the element gets removed), we need to make sure users do not get wrong signals. Also document the fact that user should connect to container::child-added with g_signal_connect_after.
-rw-r--r--ges/ges-container.c18
-rw-r--r--ges/ges-timeline.c13
2 files changed, 24 insertions, 7 deletions
diff --git a/ges/ges-container.c b/ges/ges-container.c
index 016b6dda..1543d09b 100644
--- a/ges/ges-container.c
+++ b/ges/ges-container.c
@@ -77,6 +77,10 @@ struct _GESContainerPrivate
*/
GHashTable *mappings;
guint nb_effects;
+
+ /* List of GESTimelineElement being in the "child-added" signal
+ * emission stage */
+ GList *adding_children;
};
enum
@@ -380,6 +384,9 @@ ges_container_class_init (GESContainerClass * klass)
* @element: the #GESTimelineElement that was added.
*
* Will be emitted after a child was added to @container.
+ * Usually you should connect with #g_signal_connect_after
+ * as in the first emission stage, the signal emission might
+ * get stopped internally.
*/
ges_container_signals[CHILD_ADDED_SIGNAL] =
g_signal_new ("child-added", G_TYPE_FROM_CLASS (klass),
@@ -687,8 +694,10 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
_ges_container_add_child_properties (container, child);
+ priv->adding_children = g_list_prepend (priv->adding_children, child);
g_signal_emit (container, ges_container_signals[CHILD_ADDED_SIGNAL], 0,
child);
+ priv->adding_children = g_list_remove (priv->adding_children, child);
return TRUE;
}
@@ -733,8 +742,13 @@ ges_container_remove (GESContainer * container, GESTimelineElement * child)
_ges_container_remove_child_properties (container, child);
- g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0,
- child);
+ if (!g_list_find (container->priv->adding_children, child)) {
+ g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0,
+ child);
+ } else {
+ GST_INFO_OBJECT (container, "Not emitting 'child-removed' signal as child"
+ " removal happend during 'child-added' signal emission");
+ }
gst_object_unref (child);
return TRUE;
diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c
index e45106ce..8eabdbd3 100644
--- a/ges/ges-timeline.c
+++ b/ges/ges-timeline.c
@@ -2276,13 +2276,14 @@ clip_track_element_added_cb (GESClip * clip,
if (!tracks || tracks->len == 0) {
GST_WARNING_OBJECT (timeline, "Got no Track to add %p (type %s), removing"
- " from clip",
+ " from clip (stopping 'child-added' signal emission).",
track_element, ges_track_type_name (ges_track_element_get_track_type
(track_element)));
if (tracks)
g_ptr_array_unref (tracks);
+ g_signal_stop_emission_by_name (clip, "child-added");
ges_container_remove (GES_CONTAINER (clip),
GES_TIMELINE_ELEMENT (track_element));
@@ -2306,8 +2307,9 @@ clip_track_element_added_cb (GESClip * clip,
}
} else {
GST_INFO_OBJECT (clip, "Already had a Source Element in %" GST_PTR_FORMAT
- " of type %s, removing new one.", track,
- G_OBJECT_TYPE_NAME (track_element));
+ " of type %s, removing new one. (stopping 'child-added' emission)",
+ track, G_OBJECT_TYPE_NAME (track_element));
+ g_signal_stop_emission_by_name (clip, "child-added");
ges_container_remove (GES_CONTAINER (clip),
GES_TIMELINE_ELEMENT (track_element));
}
@@ -2331,8 +2333,9 @@ clip_track_element_added_cb (GESClip * clip,
continue;
} else {
GST_INFO_OBJECT (clip, "Already had a Source Element in %" GST_PTR_FORMAT
- " of type %s, removing new one.", track,
- G_OBJECT_TYPE_NAME (track_element));
+ " of type %s, removing new one. (stopping 'child-added' emission)",
+ track, G_OBJECT_TYPE_NAME (track_element));
+ g_signal_stop_emission_by_name (clip, "child-added");
ges_container_remove (GES_CONTAINER (clip),
GES_TIMELINE_ELEMENT (track_element));
}