static guint signals[LAST_SIGNAL] = { 0 };
+/**
+ * gst_child_proxy_get_child_by_name_recurse:
+ * @parent: the parent object to get the child from
+ * @name: the full-path child's name
+ *
+ * Looks up a child element by the given full-path name.
+ *
+ * Similar to gst_child_proxy_get_child_by_name(), this method
+ * searches and returns a child given a name. The difference is that
+ * this method allows a hierarchical path in the form of
+ * child1::child2::child3. In the later example this method would
+ * return a reference to child3, if found. The name should be made of
+ * element names only and should not contain any property names.
+ *
+ * Returns: (transfer full) (nullable): the child object or %NULL if
+ * not found.
+ *
+ * Since: 1.22
+ */
+GObject *
+gst_child_proxy_get_child_by_name_recurse (GstChildProxy * child_proxy,
+ const gchar * name)
+{
+ gchar **names = NULL, **current = NULL;
+ GObject *obj = NULL, *next = NULL;
+
+ g_return_val_if_fail (child_proxy != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ current = names = g_strsplit (name, "::", -1);
+ if (current[0]) {
+ obj = G_OBJECT (g_object_ref (child_proxy));
+ }
+
+ /* walk through the children hierarchy until the requested one is found */
+ while (current[0]) {
+
+ /* Cannot ask for the child of a non-childproxy */
+ if (!GST_IS_CHILD_PROXY (obj)) {
+ gst_object_unref (obj);
+ next = NULL;
+ break;
+ }
+
+ next = gst_child_proxy_get_child_by_name (GST_CHILD_PROXY (obj),
+ current[0]);
+ gst_object_unref (obj);
+
+ /* The child does not exist */
+ if (!next) {
+ GST_INFO ("Unable to find child %s", current[0]);
+ break;
+ }
+
+ obj = next;
+ current++;
+ }
+
+ g_strfreev (names);
+
+ return next;
+}
+
static GObject *
gst_child_proxy_default_get_child_by_name (GstChildProxy * parent,
const gchar * name)
gst_child_proxy_lookup (GstChildProxy * object, const gchar * name,
GObject ** target, GParamSpec ** pspec)
{
- GObject *obj;
gboolean res = FALSE;
- gchar **names, **current;
+ gchar *children = NULL;
+ const gchar *prop = NULL;
+ GObject *child = NULL;
+ static const gchar *separator = "::";
g_return_val_if_fail (GST_IS_CHILD_PROXY (object), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
- obj = G_OBJECT (g_object_ref (object));
-
- current = names = g_strsplit (name, "::", -1);
- /* find the owner of the property */
- while (current[1]) {
- GObject *next;
-
- if (!GST_IS_CHILD_PROXY (obj)) {
- GST_INFO
- ("object %s is not a parent, so you cannot request a child by name %s",
- (GST_IS_OBJECT (obj) ? GST_OBJECT_NAME (obj) : ""), current[0]);
- break;
+ /* If the requested name does not include a "::" then it is not a
+ child proxy path, but the property name directly */
+ prop = g_strrstr (name, separator);
+ if (!prop) {
+ child = gst_object_ref (G_OBJECT (object));
+ prop = name;
+ } else {
+ /* Skip "::" */
+ prop += 2;
+
+ /* Extract "child1::child2" from "child1::child2::prop" */
+ children = g_strndup (name, prop - name - 2);
+ GST_INFO ("Looking for property %s in %s", prop, children);
+
+ child = gst_child_proxy_get_child_by_name_recurse (object, children);
+ g_free (children);
+
+ if (!child) {
+ GST_INFO ("Child not found");
+ goto out;
}
- next = gst_child_proxy_get_child_by_name (GST_CHILD_PROXY (obj),
- current[0]);
- if (!next) {
- GST_INFO ("no such object %s", current[0]);
- break;
- }
- gst_object_unref (obj);
- obj = next;
- current++;
}
- /* look for psec */
- if (current[1] == NULL) {
- GParamSpec *spec =
- g_object_class_find_property (G_OBJECT_GET_CLASS (obj), current[0]);
- if (spec == NULL) {
- GST_INFO ("no param spec named %s", current[0]);
- } else {
- if (pspec)
- *pspec = spec;
- if (target) {
- g_object_ref (obj);
- *target = obj;
- }
- res = TRUE;
+ GParamSpec *spec =
+ g_object_class_find_property (G_OBJECT_GET_CLASS (child), prop);
+ if (spec == NULL) {
+ GST_INFO ("no param spec named %s", prop);
+ } else {
+ if (pspec)
+ *pspec = spec;
+ if (target) {
+ g_object_ref (child);
+ *target = child;
}
+ res = TRUE;
}
- gst_object_unref (obj);
- g_strfreev (names);
+ gst_object_unref (child);
+
+out:
return res;
}