From 1450d539d44ea4648e5ee82c0dd027d3d36cdc9a Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 20 Dec 2010 12:01:04 +0100 Subject: [PATCH] GESTimelineObject: Subclass from GInitiallyUnowned The floating reference will be owned by the Layer --- ges/ges-timeline-layer.c | 28 +++++++++++++++++++--------- ges/ges-timeline-object.c | 3 ++- ges/ges-timeline-object.h | 4 ++-- tests/check/ges/basic.c | 4 ++++ tests/check/ges/layer.c | 2 ++ 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ges/ges-timeline-layer.c b/ges/ges-timeline-layer.c index ce8249a8e7..05e58e1a8a 100644 --- a/ges/ges-timeline-layer.c +++ b/ges/ges-timeline-layer.c @@ -212,13 +212,15 @@ objects_start_compare (GESTimelineObject * a, GESTimelineObject * b) /** * ges_timeline_layer_add_object: * @layer: a #GESTimelineLayer - * @object: the #GESTimelineObject to add. + * @object: (transfer full): the #GESTimelineObject to add. * - * Adds the object to the layer. The layer will steal a reference to the - * provided object. + * Adds the given object to the layer. Sets the object's parent, and thus + * takes ownership of the object. + * + * An object can only be added to one layer. * * Returns: TRUE if the object was properly added to the layer, or FALSE - * if the @layer refused to add the object. + * if the @layer refuses to add the object. */ gboolean @@ -230,12 +232,15 @@ ges_timeline_layer_add_object (GESTimelineLayer * layer, GST_DEBUG ("layer:%p, object:%p", layer, object); tl_obj_layer = ges_timeline_object_get_layer (object); + if (G_UNLIKELY (tl_obj_layer)) { GST_WARNING ("TimelineObject %p already belongs to another layer"); g_object_unref (tl_obj_layer); return FALSE; } + g_object_ref_sink (object); + /* Take a reference to the object and store it stored by start/priority */ layer->priv->objects_start = g_slist_insert_sorted (layer->priv->objects_start, object, @@ -268,18 +273,23 @@ ges_timeline_layer_add_object (GESTimelineLayer * layer, * @layer: a #GESTimelineLayer * @object: the #GESTimelineObject to remove * - * Removes the given @object from the @layer. The reference stolen by the @layer - * when the object was added will be removed. If you wish to use the object after - * this function, make sure you take an extra reference to the object before - * calling this function. + * Removes the given @object from the @layer and unparents it. + * Unparenting it means the reference owned by @layer on the @object will be + * removed. If you wish to use the @object after this function, make sure you + * call g_object_ref() before removing it from the @layer. * - * Returns: TRUE if the object was properly remove, else FALSE. + * Returns: TRUE if the object could be removed, FALSE if the layer does + * not want to remove the object. */ gboolean ges_timeline_layer_remove_object (GESTimelineLayer * layer, GESTimelineObject * object) { GESTimelineLayer *tl_obj_layer; + + g_return_val_if_fail (GES_IS_TIMELINE_LAYER (layer), FALSE); + g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE); + GST_DEBUG ("layer:%p, object:%p", layer, object); tl_obj_layer = ges_timeline_object_get_layer (object); diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index 4646954f4c..9283eb4ba4 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -54,7 +54,8 @@ static void track_object_priority_changed_cb (GESTrackObject * child, GParamSpec * arg G_GNUC_UNUSED, GESTimelineObject * object); -G_DEFINE_ABSTRACT_TYPE (GESTimelineObject, ges_timeline_object, G_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE (GESTimelineObject, ges_timeline_object, + G_TYPE_INITIALLY_UNOWNED); /* Mapping of relationship between a TimelineObject and the TrackObjects * it controls diff --git a/ges/ges-timeline-object.h b/ges/ges-timeline-object.h index a82f65713c..b76c4fded4 100644 --- a/ges/ges-timeline-object.h +++ b/ges/ges-timeline-object.h @@ -156,7 +156,7 @@ typedef gboolean (*GESCreateTrackObjectsFunc) (GESTimelineObject * object, */ struct _GESTimelineObject { /*< private >*/ - GObject parent; + GInitiallyUnowned parent; GESTimelineObjectPrivate *priv; @@ -186,7 +186,7 @@ struct _GESTimelineObject { */ struct _GESTimelineObjectClass { /*< private >*/ - GObjectClass parent_class; + GInitiallyUnownedClass parent_class; /*< public >*/ GESCreateTrackObjectFunc create_track_object; diff --git a/tests/check/ges/basic.c b/tests/check/ges/basic.c index b0f53b850c..0c72f1987c 100644 --- a/tests/check/ges/basic.c +++ b/tests/check/ges/basic.c @@ -93,11 +93,15 @@ GST_START_TEST (test_ges_scenario) source = ges_custom_timeline_source_new (my_fill_track_func, NULL); fail_unless (source != NULL); + /* The source will be floating before added to the layer... */ + fail_unless (g_object_is_floating (source)); GST_DEBUG ("Adding the source to the timeline layer"); fail_unless (ges_timeline_layer_add_object (layer, GES_TIMELINE_OBJECT (source))); + fail_if (g_object_is_floating (source)); tmp_layer = ges_timeline_object_get_layer (GES_TIMELINE_OBJECT (source)); fail_unless (tmp_layer == layer); + /* The timeline stole our reference */ ASSERT_OBJECT_REFCOUNT (source, "source", 1); g_object_unref (tmp_layer); ASSERT_OBJECT_REFCOUNT (layer, "layer", 1); diff --git a/tests/check/ges/layer.c b/tests/check/ges/layer.c index 7fbcb7549f..5e3ec09d81 100644 --- a/tests/check/ges/layer.c +++ b/tests/check/ges/layer.c @@ -97,8 +97,10 @@ GST_START_TEST (test_layer_properties) assert_equals_uint64 (GES_TIMELINE_OBJECT_PRIORITY (object), 0); /* Add the object to the timeline */ + fail_unless (g_object_is_floating (object)); fail_unless (ges_timeline_layer_add_object (layer, GES_TIMELINE_OBJECT (object))); + fail_if (g_object_is_floating (object)); trackobject = ges_timeline_object_find_track_object (object, track, G_TYPE_NONE); fail_unless (trackobject != NULL);