clone a GParamSpec for composite objects
Submitted by Stefan Sauer (gstreamer, gtkdoc dev)
Link to original bug (#744011)
Description
Imagine a case where you implement a GObject built from smaller gobjects. You want the top-level one forward some properties. Right now you would create the same property that you want to forward on the top-level and forwards from set/get. Some of the issues here:
- one duplicated the param spec definition
- a notify on the child would not trigger a notify on the parent
Using a g_param_spec_override()
sounds like a plan, but it does not work due to expectations in g_object_class_list_properties()
. And that is the same issue as in bug #688014. On the application level it is not easy to work-around this as the pspec pool is internal.
So what I wonder is why does g_object_class_list_properties()
traverses the parent types even. Can't it just collect params for this type and handle the redirects (g_param_spec_get_redirect_target
)?
#if 0
/* we repeat the param spec details from the component */
properties[PROP_RESONANCE] = g_param_spec_double ("resonance", "Resonance",
"Audio filter resonance", 0.7, 25.0, 0.8,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS);
#else
/* the problem is that g_object_class_list_properties() will remove the
* g_param_spec_override() - see pspec_list_remove_overridden_and_redirected()
* as it also goes up the hierarchy in order to try to supply the redirect
* target instead. Here the filter_klass is not a parent, nor an interface
* and thus the property is missing.
*/
GObjectClass * filter_klass = g_type_class_ref (GSTBT_TYPE_FILTER_SVF);
GParamSpec *target = g_object_class_find_property (filter_klass, "resonance");
g_assert (target);
#if 1
properties[PROP_RESONANCE] = g_param_spec_override ("resonance", target);
#else
/* the GParamSpec is not reusable, we need a g_param_spec_clone() - but that
* is impossible without knowing the types
*/
GParamSpec *target_dup = g_memdup (target, sizeof (GParamSpec));
target_dup->owner_type = 0;
target_dup->qdata = NULL;
target_dup->ref_count = 0;
target_dup->param_id = 0;
properties[PROP_RESONANCE] = target_dup;
#endif
g_type_class_unref (filter_klass);
#endif