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 };
|
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 *
|
static GObject *
|
||||||
gst_child_proxy_default_get_child_by_name (GstChildProxy * parent,
|
gst_child_proxy_default_get_child_by_name (GstChildProxy * parent,
|
||||||
const gchar * name)
|
const gchar * name)
|
||||||
|
@ -194,55 +257,54 @@ gboolean
|
||||||
gst_child_proxy_lookup (GstChildProxy * object, const gchar * name,
|
gst_child_proxy_lookup (GstChildProxy * object, const gchar * name,
|
||||||
GObject ** target, GParamSpec ** pspec)
|
GObject ** target, GParamSpec ** pspec)
|
||||||
{
|
{
|
||||||
GObject *obj;
|
|
||||||
gboolean res = FALSE;
|
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 (GST_IS_CHILD_PROXY (object), FALSE);
|
||||||
g_return_val_if_fail (name != NULL, 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);
|
/* Extract "child1::child2" from "child1::child2::prop" */
|
||||||
/* find the owner of the property */
|
children = g_strndup (name, prop - name - 2);
|
||||||
while (current[1]) {
|
GST_INFO ("Looking for property %s in %s", prop, children);
|
||||||
GObject *next;
|
|
||||||
|
|
||||||
if (!GST_IS_CHILD_PROXY (obj)) {
|
child = gst_child_proxy_get_child_by_name_recurse (object, children);
|
||||||
GST_INFO
|
g_free (children);
|
||||||
("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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* look for psec */
|
if (!child) {
|
||||||
if (current[1] == NULL) {
|
GST_INFO ("Child not found");
|
||||||
GParamSpec *spec =
|
goto out;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,10 @@ GType gst_child_proxy_get_type (void);
|
||||||
GST_API
|
GST_API
|
||||||
GObject * gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name);
|
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
|
GST_API
|
||||||
guint gst_child_proxy_get_children_count (GstChildProxy * parent);
|
guint gst_child_proxy_get_children_count (GstChildProxy * parent);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue