comp-loader: add support for wireplumber.components.rules
This is a new rules section that allows defining rules to modify component definitions. This is useful to add repetitive dependencies, for example, as in the case of "type = script/lua" that always requires the "support.lua-scripting" feature. This can also be useful to modify other component properties, such as the arguments, in overriding configuration files, without needing to redefine the whole components section.
This commit is contained in:
@@ -83,12 +83,83 @@ get_feature_state (WpProperties * dict, const gchar * feature)
|
||||
}
|
||||
}
|
||||
|
||||
static ComponentData *
|
||||
component_data_new_from_json (WpSpaJson * json, WpProperties * features,
|
||||
static gboolean
|
||||
component_rule_match_cb (gpointer data, const gchar * action, WpSpaJson * value,
|
||||
GError ** error)
|
||||
{
|
||||
WpProperties *props = data;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
gboolean merge;
|
||||
|
||||
if (!wp_spa_json_is_object (value)) {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"expected JSON object instead of: %.*s", (int) wp_spa_json_get_size (value),
|
||||
wp_spa_json_get_data (value));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_str_equal (action, "merge")) {
|
||||
merge = TRUE;
|
||||
} else if (g_str_equal (action, "override")) {
|
||||
merge = FALSE;
|
||||
} else {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"invalid action '%s' in component rules", action);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
it = wp_spa_json_new_iterator (value);
|
||||
|
||||
do {
|
||||
g_autofree gchar *key = NULL;
|
||||
g_autofree gchar *val = NULL;
|
||||
const gchar *old_val = NULL;
|
||||
|
||||
/* extract key */
|
||||
if (!wp_iterator_next (it, &item))
|
||||
break;
|
||||
key = wp_spa_json_to_string (g_value_get_boxed (&item));
|
||||
g_value_unset (&item);
|
||||
|
||||
/* extract value */
|
||||
if (!wp_iterator_next (it, &item)) {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"expected value for key '%s' in component rules", key);
|
||||
return FALSE;
|
||||
}
|
||||
val = wp_spa_json_to_string (g_value_get_boxed (&item));
|
||||
g_value_unset (&item);
|
||||
|
||||
old_val = wp_properties_get (props, key);
|
||||
|
||||
/* override if not merging or if the value is not a container */
|
||||
if (!merge || !old_val || (*old_val != '[' && *old_val != '{')) {
|
||||
wp_properties_set (props, key, val);
|
||||
}
|
||||
else {
|
||||
g_autoptr (WpSpaJson) old_json = NULL;
|
||||
g_autoptr (WpSpaJson) new_json = NULL;
|
||||
g_autoptr (WpSpaJson) merged_json = NULL;
|
||||
|
||||
old_json = wp_spa_json_new_wrap_string (old_val);
|
||||
new_json = wp_spa_json_new_wrap_string (val);
|
||||
merged_json = wp_json_utils_merge_containers (old_json, new_json);
|
||||
wp_properties_set (props, key,
|
||||
merged_json ? wp_spa_json_get_data (merged_json) : val);
|
||||
}
|
||||
} while (TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ComponentData *
|
||||
component_data_new_from_json (WpSpaJson * json, WpProperties * features,
|
||||
WpSpaJson * rules, GError ** error)
|
||||
{
|
||||
g_autoptr (ComponentData) comp = NULL;
|
||||
g_autoptr (WpSpaJson) comp_reqs = NULL, comp_wants = NULL;
|
||||
g_autoptr (WpProperties) props = NULL;
|
||||
const gchar *str;
|
||||
|
||||
if (!wp_spa_json_is_object (json)) {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
@@ -102,17 +173,24 @@ component_data_new_from_json (WpSpaJson * json, WpProperties * features,
|
||||
comp->requires = g_ptr_array_new_with_free_func (g_free);
|
||||
comp->wants = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
if (!wp_spa_json_object_get (json, "type", "s", &comp->type, NULL)) {
|
||||
props = wp_properties_new_json (json);
|
||||
if (rules && !wp_json_utils_match_rules (rules, props, component_rule_match_cb,
|
||||
props, error))
|
||||
return NULL;
|
||||
|
||||
if (!(comp->type = g_strdup (wp_properties_get (props, "type")))) {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"component 'type' is required at: %.*s", (int) wp_spa_json_get_size (json),
|
||||
wp_spa_json_get_data (json));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wp_spa_json_object_get (json, "name", "s", &comp->name, NULL);
|
||||
wp_spa_json_object_get (json, "arguments", "J", &comp->arguments, NULL);
|
||||
comp->name = g_strdup (wp_properties_get (props, "name"));
|
||||
str = wp_properties_get (props, "arguments");
|
||||
comp->arguments = str ? wp_spa_json_new_from_string (str) : NULL;
|
||||
|
||||
if (wp_spa_json_object_get (json, "provides", "s", &comp->provides, NULL)) {
|
||||
if ((str = wp_properties_get (props, "provides"))) {
|
||||
comp->provides = g_strdup (str);
|
||||
comp->state = get_feature_state (features, comp->provides);
|
||||
if (comp->name) {
|
||||
comp->printable_id =
|
||||
@@ -126,7 +204,8 @@ component_data_new_from_json (WpSpaJson * json, WpProperties * features,
|
||||
comp->printable_id = g_strdup_printf ("[%s: %s]", comp->type, comp->name);
|
||||
}
|
||||
|
||||
if (wp_spa_json_object_get (json, "requires", "J", &comp_reqs, NULL)) {
|
||||
if ((str = wp_properties_get (props, "requires"))) {
|
||||
g_autoptr (WpSpaJson) comp_reqs = wp_spa_json_new_wrap_string (str);
|
||||
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (comp_reqs);
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
|
||||
@@ -136,7 +215,8 @@ component_data_new_from_json (WpSpaJson * json, WpProperties * features,
|
||||
}
|
||||
}
|
||||
|
||||
if (wp_spa_json_object_get (json, "wants", "J", &comp_wants, NULL)) {
|
||||
if ((str = wp_properties_get (props, "wants"))) {
|
||||
g_autoptr (WpSpaJson) comp_wants = wp_spa_json_new_wrap_string (str);
|
||||
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (comp_wants);
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
|
||||
@@ -171,6 +251,8 @@ struct _WpComponentArrayLoadTask
|
||||
WpSpaJson *json;
|
||||
/* the features profile */
|
||||
WpProperties *profile;
|
||||
/* the rules to apply on each component description */
|
||||
WpSpaJson *rules;
|
||||
/* all components that provide a feature; key: comp->provides, value: comp */
|
||||
GHashTable *feat_components;
|
||||
/* the final sorted list of components to load */
|
||||
@@ -317,7 +399,7 @@ parse_components (WpComponentArrayLoadTask * self, GError ** error)
|
||||
GError *e = NULL;
|
||||
g_autoptr (ComponentData) comp = NULL;
|
||||
|
||||
if (!(comp = component_data_new_from_json (cjson, self->profile, &e))) {
|
||||
if (!(comp = component_data_new_from_json (cjson, self->profile, self->rules, &e))) {
|
||||
g_propagate_error (error, e);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -459,6 +541,7 @@ wp_component_array_load_task_finalize (GObject * object)
|
||||
g_clear_pointer (&self->feat_components, g_hash_table_unref);
|
||||
g_clear_pointer (&self->components, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->profile, wp_properties_unref);
|
||||
g_clear_pointer (&self->rules, wp_spa_json_unref);
|
||||
g_clear_pointer (&self->json, wp_spa_json_unref);
|
||||
|
||||
G_OBJECT_CLASS (wp_component_array_load_task_parent_class)->finalize (object);
|
||||
@@ -478,7 +561,7 @@ wp_component_array_load_task_class_init (WpComponentArrayLoadTaskClass * klass)
|
||||
|
||||
static WpTransition *
|
||||
wp_component_array_load_task_new (WpSpaJson * json, WpProperties * profile,
|
||||
gpointer source_object, GCancellable * cancellable,
|
||||
WpSpaJson * rules, gpointer source_object, GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback, gpointer callback_data)
|
||||
{
|
||||
WpTransition *t = wp_transition_new (wp_component_array_load_task_get_type (),
|
||||
@@ -486,6 +569,7 @@ wp_component_array_load_task_new (WpSpaJson * json, WpProperties * profile,
|
||||
WpComponentArrayLoadTask *task = WP_COMPONENT_ARRAY_LOAD_TASK (t);
|
||||
task->json = wp_spa_json_ref (json);
|
||||
task->profile = wp_properties_ref (profile);
|
||||
task->rules = rules ? wp_spa_json_ref (rules) : NULL;
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -641,23 +725,30 @@ wp_internal_comp_loader_load (WpComponentLoader * self, WpCore * core,
|
||||
if (g_str_equal (type, "profile") || g_str_equal (type, "array")) {
|
||||
WpTransition *task = NULL;
|
||||
g_autoptr (WpSpaJson) components = NULL;
|
||||
g_autoptr (WpSpaJson) rules = NULL;
|
||||
g_autoptr (WpProperties) profile = wp_properties_new_empty ();
|
||||
|
||||
if (g_str_equal (type, "profile")) {
|
||||
/* component name is the profile name;
|
||||
component list and profile features are loaded from config */
|
||||
g_autoptr (WpConf) conf = wp_conf_get_instance (core);
|
||||
g_autoptr (WpSpaJson) profile_json =
|
||||
g_autoptr (WpSpaJson) profile_json = NULL;
|
||||
|
||||
profile_json =
|
||||
wp_conf_get_value (conf, "wireplumber.profiles", component, NULL);
|
||||
if (profile_json)
|
||||
wp_properties_update_from_json (profile, profile_json);
|
||||
|
||||
components = wp_conf_get_section (conf, "wireplumber.components", NULL);
|
||||
} else {
|
||||
|
||||
rules = wp_conf_get_section (conf, "wireplumber.components.rules", NULL);
|
||||
}
|
||||
else {
|
||||
/* component list is retrieved from args; profile features are empty */
|
||||
components = wp_spa_json_ref (args);
|
||||
}
|
||||
|
||||
task = wp_component_array_load_task_new (components, profile, self,
|
||||
task = wp_component_array_load_task_new (components, profile, rules, self,
|
||||
cancellable, callback, data);
|
||||
wp_transition_set_data (task, g_object_ref (core), g_object_unref);
|
||||
wp_transition_set_source_tag (task, wp_internal_comp_loader_load);
|
||||
|
@@ -214,7 +214,6 @@ wireplumber.components = [
|
||||
name = metadata.lua, type = script/lua
|
||||
arguments = { metadata.name = default }
|
||||
provides = metadata.default
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
|
||||
## Provide the "filters" pw_metadata
|
||||
@@ -222,7 +221,6 @@ wireplumber.components = [
|
||||
name = metadata.lua, type = script/lua
|
||||
arguments = { metadata.name = filters }
|
||||
provides = metadata.filters
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
|
||||
## Device monitors' optional features
|
||||
@@ -243,54 +241,49 @@ wireplumber.components = [
|
||||
{
|
||||
name = monitors/alsa.lua, type = script/lua
|
||||
provides = monitor.alsa
|
||||
requires = [ support.lua-scripting, support.export-core ]
|
||||
requires = [ support.export-core ]
|
||||
wants = [ monitor.alsa.reserve-device ]
|
||||
}
|
||||
{
|
||||
name = monitors/bluez.lua, type = script/lua
|
||||
provides = monitor.bluez
|
||||
requires = [ support.lua-scripting, support.export-core ]
|
||||
requires = [ support.export-core ]
|
||||
wants = [ monitor.bluetooth.seat-monitoring ]
|
||||
}
|
||||
{
|
||||
name = monitors/bluez-midi.lua, type = script/lua
|
||||
provides = monitor.bluez-midi
|
||||
requires = [ support.lua-scripting, support.export-core ]
|
||||
requires = [ support.export-core ]
|
||||
wants = [ monitor.bluetooth.seat-monitoring ]
|
||||
}
|
||||
{
|
||||
name = monitors/alsa-midi.lua, type = script/lua
|
||||
provides = monitor.alsa-midi
|
||||
requires = [ support.lua-scripting ]
|
||||
wants = [ monitor.alsa-midi.monitoring ]
|
||||
}
|
||||
## v4l2 monitor hooks
|
||||
{
|
||||
name = monitors/v4l2/name-device.lua, type = script/lua
|
||||
provides = hooks.monitor.v4l2-name-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/v4l2/create-device.lua, type = script/lua
|
||||
provides = hooks.monitor.v4l2-create-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/v4l2/name-node.lua, type = script/lua
|
||||
provides = hooks.monitor.v4l2-name-node
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/v4l2/create-node.lua, type = script/lua
|
||||
provides = hooks.monitor.v4l2-create-node
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
@@ -304,8 +297,7 @@ wireplumber.components = [
|
||||
{
|
||||
name = monitors/v4l2/enumerate-device.lua, type = script/lua
|
||||
provides = hooks.monitor.v4l2-enumerate-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source,
|
||||
monitor.v4l2.hooks ]
|
||||
}
|
||||
@@ -319,29 +311,25 @@ wireplumber.components = [
|
||||
{
|
||||
name = monitors/libcamera/name-device.lua, type = script/lua
|
||||
provides = hooks.monitor.libcamera-name-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/libcamera/create-device.lua, type = script/lua
|
||||
provides = hooks.monitor.libcamera-create-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/libcamera/name-node.lua, type = script/lua
|
||||
provides = hooks.monitor.libcamera-name-node
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
name = monitors/libcamera/create-node.lua, type = script/lua
|
||||
provides = hooks.monitor.libcamera-create-node
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source ]
|
||||
}
|
||||
{
|
||||
@@ -355,8 +343,7 @@ wireplumber.components = [
|
||||
{
|
||||
name = monitors/libcamera/enumerate-device.lua, type = script/lua
|
||||
provides = hooks.monitor.libcamera-enumerate-device
|
||||
requires = [ support.lua-scripting,
|
||||
support.export-core,
|
||||
requires = [ support.export-core,
|
||||
support.standard-event-source,
|
||||
monitor.libcamera.hooks ]
|
||||
}
|
||||
@@ -370,12 +357,11 @@ wireplumber.components = [
|
||||
{
|
||||
name = client/access-default.lua, type = script/lua
|
||||
provides = script.client.access-default
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = client/access-portal.lua, type = script/lua
|
||||
provides = script.client.access-portal
|
||||
requires = [ support.lua-scripting, support.portal-permissionstore ]
|
||||
requires = [ support.portal-permissionstore ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.client.access
|
||||
@@ -387,27 +373,22 @@ wireplumber.components = [
|
||||
{
|
||||
name = device/select-profile.lua, type = script/lua
|
||||
provides = hooks.device.profile.select
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/find-best-profile.lua, type = script/lua
|
||||
provides = hooks.device.profile.find-best
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/state-profile.lua, type = script/lua
|
||||
provides = hooks.device.profile.state
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/apply-profile.lua, type = script/lua
|
||||
provides = hooks.device.profile.apply
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/autoswitch-bluetooth-profile.lua, type = script/lua
|
||||
provides = hooks.device.profile.autoswitch-bluetooth
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.device.profile
|
||||
@@ -422,22 +403,18 @@ wireplumber.components = [
|
||||
{
|
||||
name = device/select-routes.lua, type = script/lua
|
||||
provides = hooks.device.routes.select
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/find-best-routes.lua, type = script/lua
|
||||
provides = hooks.device.routes.find-best
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/state-routes.lua, type = script/lua
|
||||
provides = hooks.device.routes.state
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = device/apply-routes.lua, type = script/lua
|
||||
provides = hooks.device.routes.apply
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.device.routes
|
||||
@@ -451,27 +428,25 @@ wireplumber.components = [
|
||||
{
|
||||
name = default-nodes/rescan.lua, type = script/lua
|
||||
provides = hooks.default-nodes.rescan
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = default-nodes/find-selected-default-node.lua, type = script/lua
|
||||
provides = hooks.default-nodes.find-selected
|
||||
requires = [ support.lua-scripting, metadata.default ]
|
||||
requires = [ metadata.default ]
|
||||
}
|
||||
{
|
||||
name = default-nodes/find-best-default-node.lua, type = script/lua
|
||||
provides = hooks.default-nodes.find-best
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = default-nodes/state-default-nodes.lua, type = script/lua
|
||||
provides = hooks.default-nodes.state
|
||||
requires = [ support.lua-scripting, metadata.default ]
|
||||
requires = [ metadata.default ]
|
||||
}
|
||||
{
|
||||
name = default-nodes/apply-default-node.lua, type = script/lua,
|
||||
provides = hooks.default-nodes.apply
|
||||
requires = [ support.lua-scripting, metadata.default ]
|
||||
requires = [ metadata.default ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.default-nodes
|
||||
@@ -486,74 +461,67 @@ wireplumber.components = [
|
||||
{
|
||||
name = node/create-item.lua, type = script/lua
|
||||
provides = hooks.node.create-session-item
|
||||
requires = [ support.lua-scripting, si.audio-adapter, si.node ]
|
||||
requires = [ si.audio-adapter, si.node ]
|
||||
}
|
||||
{
|
||||
name = node/suspend-node.lua, type = script/lua
|
||||
provides = hooks.node.suspend
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = node/state-stream.lua, type = script/lua
|
||||
provides = hooks.stream.state
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = linking/filter-forward-format.lua, type = script/lua
|
||||
provides = hooks.loopback.forward-format
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = node/create-virtual-item.lua, type = script/lua
|
||||
provides = script.create-role-items
|
||||
requires = [ support.lua-scripting, si.audio-virtual ]
|
||||
requires = [ si.audio-virtual ]
|
||||
}
|
||||
|
||||
## Linking hooks
|
||||
{
|
||||
name = linking/rescan.lua, type = script/lua
|
||||
provides = hooks.linking.rescan
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = linking/move-follow.lua, type = script/lua
|
||||
provides = hooks.linking.move-follow
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = linking/find-defined-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.find-defined
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = linking/find-filter-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.find-filter
|
||||
requires = [ support.lua-scripting, metadata.filters ]
|
||||
requires = [ metadata.filters ]
|
||||
}
|
||||
{
|
||||
name = linking/find-default-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.find-default
|
||||
requires = [ support.lua-scripting, api.default-nodes ]
|
||||
requires = [ api.default-nodes ]
|
||||
}
|
||||
{
|
||||
name = linking/find-best-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.find-best
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
name = linking/get-filter-from-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.get-filter-from
|
||||
requires = [ support.lua-scripting, metadata.filters ]
|
||||
requires = [ metadata.filters ]
|
||||
}
|
||||
{
|
||||
name = linking/prepare-link.lua, type = script/lua
|
||||
provides = hooks.linking.target.prepare-link
|
||||
requires = [ support.lua-scripting, api.default-nodes ]
|
||||
requires = [ api.default-nodes ]
|
||||
}
|
||||
{
|
||||
name = linking/link-target.lua, type = script/lua
|
||||
provides = hooks.linking.target.link
|
||||
requires = [ support.lua-scripting, si.standard-link ]
|
||||
requires = [ si.standard-link ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.linking.standard
|
||||
@@ -572,12 +540,11 @@ wireplumber.components = [
|
||||
{
|
||||
name = linking/rescan-virtual-links.lua, type = script/lua
|
||||
provides = hooks.linking.role-priority-system.links.rescan
|
||||
requires = [ support.lua-scripting, api.mixer ]
|
||||
requires = [ api.mixer ]
|
||||
}
|
||||
{
|
||||
name = linking/find-virtual-target.lua, type = script/lua
|
||||
provides = hooks.linking.role-priority-system.target.find
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.linking.role-priority-system
|
||||
@@ -619,6 +586,38 @@ wireplumber.components = [
|
||||
}
|
||||
]
|
||||
|
||||
wireplumber.components.rules = [
|
||||
## Rules to apply on top of wireplumber.components
|
||||
## Syntax:
|
||||
## {
|
||||
## matches = [
|
||||
## {
|
||||
## [ <key> = <value> ... ]
|
||||
## }
|
||||
## ...
|
||||
## ]
|
||||
## actions = {
|
||||
## <override|merge> = {
|
||||
## [ <key> = <value> ... ]
|
||||
## }
|
||||
## ...
|
||||
## }
|
||||
## }
|
||||
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
type = "script/lua"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
merge = {
|
||||
requires = [ support.lua-scripting ]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
wireplumber.settings = {
|
||||
## This main config file is only supposed to contain the common settings and
|
||||
## rules. rest of the settings and rules are distributed across
|
||||
|
@@ -21,17 +21,17 @@ wireplumber.components = [
|
||||
name = two
|
||||
type = test
|
||||
provides = support.two
|
||||
requires = [ support.one support.six ]
|
||||
requires = [ support.one ]
|
||||
}
|
||||
{
|
||||
type = virtual
|
||||
provides = virtual.four
|
||||
requires = [ support.four ]
|
||||
requires = [ INVALID ]
|
||||
}
|
||||
{
|
||||
name = three
|
||||
type = test
|
||||
provides = support.three
|
||||
provides = INVALID
|
||||
wants = [ support.two ]
|
||||
}
|
||||
{
|
||||
@@ -64,3 +64,46 @@ wireplumber.components = [
|
||||
requires = [ support.four ]
|
||||
}
|
||||
]
|
||||
|
||||
wireplumber.components.rules = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
name = two
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
merge = {
|
||||
# final array should be [ support.one, support.six ]
|
||||
# if this fails, support.six will not be loaded
|
||||
requires = [ support.six ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
name = three
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
merge = {
|
||||
provides = support.three
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
provides = virtual.four
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
override = {
|
||||
requires = [ support.four ]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user