mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +00:00
childproxy: Implement a new ::get_child_by_name_recurse() API
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2908>
This commit is contained in:
parent
60f7467dfe
commit
ded2fed3b9
2 changed files with 105 additions and 39 deletions
|
@ -55,6 +55,69 @@ enum
|
|||
|
||||
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)
|
||||
|
@ -194,55 +257,54 @@ gboolean
|
|||
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));
|
||||
/* 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;
|
||||
|
||||
current = names = g_strsplit (name, "::", -1);
|
||||
/* find the owner of the property */
|
||||
while (current[1]) {
|
||||
GObject *next;
|
||||
/* Extract "child1::child2" from "child1::child2::prop" */
|
||||
children = g_strndup (name, prop - name - 2);
|
||||
GST_INFO ("Looking for property %s in %s", prop, children);
|
||||
|
||||
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;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
child = gst_child_proxy_get_child_by_name_recurse (object, children);
|
||||
g_free (children);
|
||||
|
||||
/* 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;
|
||||
if (!child) {
|
||||
GST_INFO ("Child not found");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
gst_object_unref (obj);
|
||||
g_strfreev (names);
|
||||
|
||||
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 (child);
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,10 @@ GType gst_child_proxy_get_type (void);
|
|||
GST_API
|
||||
GObject * gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name);
|
||||
|
||||
GST_API
|
||||
GObject * gst_child_proxy_get_child_by_name_recurse (GstChildProxy * child_proxy,
|
||||
const gchar *name);
|
||||
|
||||
GST_API
|
||||
guint gst_child_proxy_get_children_count (GstChildProxy * parent);
|
||||
|
||||
|
|
Loading…
Reference in a new issue