From 5a930aa642837e4732bfa7b7a83339dea30712c0 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Wed, 5 Nov 2014 11:50:47 +0100 Subject: [PATCH] gstobject: Add gst_object_has_parent() Adds gst_object_has_parent, which works like gst_object_has_ancestor but does not ascend further. API: gst_object_has_parent() --- docs/gst/gstreamer-sections.txt | 1 + gst/gstobject.c | 28 +++++++++++++ gst/gstobject.h | 1 + tests/check/gst/gstobject.c | 70 ++++++++++++++++++++++++++++----- win32/common/libgstreamer.def | 1 + 5 files changed, 91 insertions(+), 10 deletions(-) diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 818c0d18a7..37e852fe20 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1697,6 +1697,7 @@ gst_object_set_name gst_object_get_name gst_object_set_parent gst_object_get_parent +gst_object_has_parent gst_object_unparent gst_object_default_deep_notify gst_object_default_error diff --git a/gst/gstobject.c b/gst/gstobject.c index 5691bec27e..198a7dbd3f 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -778,6 +778,34 @@ gst_object_unparent (GstObject * object) } } +/** + * gst_object_has_parent: + * @object: a #GstObject to check + * @parent: a #GstObject to check as parent + * + * Check if @parent is the parent of @object. + * E.g. a #GstElement can check if it owns a given #GstPad. + * + * Returns: %FALSE if either @object or @parent is %NULL. %TRUE if @parent is + * the parent of @object. Otherwise %FALSE. + * + * MT safe. Grabs and releases @object's locks. + * Since: 1.6 + */ +gboolean +gst_object_has_parent (GstObject * object, GstObject * parent) +{ + gboolean result = FALSE; + + if (G_LIKELY (GST_IS_OBJECT (object) && GST_IS_OBJECT (parent))) { + GST_OBJECT_LOCK (object); + result = GST_OBJECT_PARENT (object) == parent; + GST_OBJECT_UNLOCK (object); + } + + return result; +} + /** * gst_object_has_ancestor: * @object: a #GstObject to check diff --git a/gst/gstobject.h b/gst/gstobject.h index 86c5715422..b9e6661ecc 100644 --- a/gst/gstobject.h +++ b/gst/gstobject.h @@ -212,6 +212,7 @@ gchar* gst_object_get_name (GstObject *object); gboolean gst_object_set_parent (GstObject *object, GstObject *parent); GstObject* gst_object_get_parent (GstObject *object); void gst_object_unparent (GstObject *object); +gboolean gst_object_has_parent (GstObject *object, GstObject *parent); gboolean gst_object_has_ancestor (GstObject *object, GstObject *ancestor); void gst_object_default_deep_notify (GObject *object, GstObject *orig, diff --git a/tests/check/gst/gstobject.c b/tests/check/gst/gstobject.c index 96f6bcf740..cba79e9758 100644 --- a/tests/check/gst/gstobject.c +++ b/tests/check/gst/gstobject.c @@ -360,6 +360,11 @@ GST_START_TEST (test_fake_object_parentage) ASSERT_CRITICAL (result = gst_object_set_parent (object1, object1)); fail_if (result == TRUE, "GstFakeObject accepted itself as parent"); + /* _has_parent always returns FALSE if there is no parent */ + fail_if (gst_object_has_parent (object1, NULL)); + fail_if (gst_object_has_parent (NULL, object1)); + fail_if (gst_object_has_parent (object1, object1)); + /* should still be floating */ fail_unless (g_object_is_floating (object1), "GstFakeObject instance is not floating"); @@ -373,6 +378,9 @@ GST_START_TEST (test_fake_object_parentage) fail_unless (g_object_is_floating (object1), "GstFakeObject instance is not floating"); + result = gst_object_has_parent (object1, object2); + fail_if (result == TRUE, "GstFakeObject has a parent"); + /* try to set other object as parent */ result = gst_object_set_parent (object1, object2); fail_if (result == FALSE, @@ -386,9 +394,17 @@ GST_START_TEST (test_fake_object_parentage) "GstFakeObject instance is not floating"); /* check the parent */ - parent = gst_object_get_parent (object1); - fail_if (parent != object2, "GstFakeObject has wrong parent"); - gst_object_unref (parent); + fail_unless (gst_object_has_parent (object1, object2)); + + /* any other combination is invalid */ + fail_if (gst_object_has_parent (object2, object1)); + fail_if (gst_object_has_parent (object1, NULL)); + fail_if (gst_object_has_parent (object2, NULL)); + fail_if (gst_object_has_parent (NULL, object1)); + fail_if (gst_object_has_parent (NULL, object2)); + fail_if (gst_object_has_parent (object1, object1)); + fail_if (gst_object_has_parent (object2, object2)); + /* try to set other object as parent again */ result = gst_object_set_parent (object1, object2); fail_if (result == TRUE, "GstFakeObject could set parent twice"); @@ -470,16 +486,50 @@ GST_START_TEST (test_fake_object_has_ancestor) fail_if (result == FALSE, "GstFakeObject could not accept other object as parent"); + /* Hierarchy: + * object4 + * `- object3 + * |- object2 + * `- object1 + */ + + /* An object isn't its own parent, but it is its own ancestor */ + fail_if (gst_object_has_parent (object1, object1)); fail_unless (gst_object_has_ancestor (object1, object1)); - fail_if (gst_object_has_ancestor (object1, object2)); - fail_unless (gst_object_has_ancestor (object1, object3)); - fail_unless (gst_object_has_ancestor (object1, object4)); - fail_if (gst_object_has_ancestor (object3, object1)); - fail_if (gst_object_has_ancestor (object4, object1)); - fail_unless (gst_object_has_ancestor (object3, object4)); - fail_if (gst_object_has_ancestor (object4, object3)); + + fail_if (gst_object_has_parent (object4, object4)); fail_unless (gst_object_has_ancestor (object4, object4)); + /* direct parents */ + fail_unless (gst_object_has_parent (object1, object3)); + fail_unless (gst_object_has_ancestor (object1, object3)); + + fail_unless (gst_object_has_parent (object2, object3)); + fail_unless (gst_object_has_ancestor (object2, object3)); + + fail_unless (gst_object_has_parent (object3, object4)); + fail_unless (gst_object_has_ancestor (object3, object4)); + + /* grandparents */ + fail_if (gst_object_has_parent (object1, object4)); + fail_unless (gst_object_has_ancestor (object1, object4)); + + fail_if (gst_object_has_parent (object2, object4)); + fail_unless (gst_object_has_ancestor (object2, object4)); + + /* not ancestors */ + fail_if (gst_object_has_parent (object1, object2)); + fail_if (gst_object_has_ancestor (object1, object2)); + + fail_if (gst_object_has_parent (object3, object1)); + fail_if (gst_object_has_ancestor (object3, object1)); + + fail_if (gst_object_has_parent (object4, object1)); + fail_if (gst_object_has_ancestor (object4, object1)); + + fail_if (gst_object_has_parent (object4, object3)); + fail_if (gst_object_has_ancestor (object4, object3)); + /* unparent everything */ gst_object_unparent (object3); gst_object_unparent (object2); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 99a15682b1..4c18bf18cf 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -770,6 +770,7 @@ EXPORTS gst_object_get_value_array gst_object_has_active_control_bindings gst_object_has_ancestor + gst_object_has_parent gst_object_ref gst_object_ref_sink gst_object_remove_control_binding