From 3fbf1286e692c0047da8e4553b91f4a0156a68ea Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Mon, 4 Mar 2024 16:27:37 +0200 Subject: [PATCH] lua: change the Conf API to have methods for getting sections as specific types In some cases we need to get a section as JSON, so that we can pass it down to the rules parser, while in other cases we neeed to get it as a table to use it natively, and in that case we even need to differentiate between it being an object, an array or an object with WpProperties. Make it also possible to optionally pass tables with default values to the functions so that we can get rid of cutils.get_config_section() as well. --- modules/module-lua-scripting/api/api.c | 106 ++++++++++++++---- src/scripts/client/access-default.lua | 2 +- src/scripts/lib/common-utils.lua | 24 +--- src/scripts/linking/find-virtual-target.lua | 6 +- src/scripts/linking/rescan-virtual-links.lua | 7 +- src/scripts/monitors/alsa-midi.lua | 32 +++--- src/scripts/monitors/alsa.lua | 2 +- src/scripts/monitors/bluez-midi.lua | 4 +- src/scripts/monitors/bluez.lua | 2 +- .../monitors/libcamera/enumerate-device.lua | 2 +- .../monitors/v4l2/enumerate-device.lua | 2 +- src/scripts/node/create-virtual-item.lua | 6 +- 12 files changed, 113 insertions(+), 82 deletions(-) diff --git a/modules/module-lua-scripting/api/api.c b/modules/module-lua-scripting/api/api.c index f7741176..7a58ed1e 100644 --- a/modules/module-lua-scripting/api/api.c +++ b/modules/module-lua-scripting/api/api.c @@ -1619,37 +1619,103 @@ impl_module_new (lua_State *L) /* WpConf */ static int -conf_get_section (lua_State *L) +conf_get_section_as_properties (lua_State *L) { + const char *section = luaL_checkstring (L, 1); + g_autoptr (WpConf) conf = wp_core_get_conf (get_wp_core (L)); + g_autoptr (WpSpaJson) s = NULL; + g_autoptr (WpProperties) props = NULL; + + if (lua_istable (L, 2)) + props = wplua_table_to_properties (L, 2); + else + props = wp_properties_new_empty (); + + if (conf) { + s = wp_conf_get_section (conf, section); + if (s && wp_spa_json_is_object (s)) + wp_properties_update_from_json (props, s); + } + wplua_properties_to_table (L, props); + return 1; +} + +static int +conf_get_section_as_object (lua_State *L) +{ + const char *section = luaL_checkstring (L, 1); g_autoptr (WpConf) conf = wp_core_get_conf (get_wp_core (L)); - const char *section; - g_autoptr (WpSpaJson) fb = NULL; g_autoptr (WpSpaJson) s = NULL; - if (!conf) { - lua_pushnil (L); - return 1; + if (conf) { + s = wp_conf_get_section (conf, section); + if (s && wp_spa_json_is_object (s)) { + push_luajson (L, s, INT_MAX); + return 1; + } } - section = luaL_checkstring (L, 1); - if (lua_isuserdata (L, 2)) { - WpSpaJson *v = wplua_checkboxed (L, 2, WP_TYPE_SPA_JSON); - if (v) - fb = wp_spa_json_ref (v); - } - - s = wp_conf_get_section (conf, section); - if (s) - wplua_pushboxed (L, WP_TYPE_SPA_JSON, g_steal_pointer (&s)); - else if (fb) - wplua_pushboxed (L, WP_TYPE_SPA_JSON, g_steal_pointer (&fb)); + if (lua_istable (L, 2)) + lua_pushvalue (L, 2); else - lua_pushnil (L); + lua_newtable (L); + return 1; +} + +static int +conf_get_section_as_array (lua_State *L) +{ + const char *section = luaL_checkstring (L, 1); + g_autoptr (WpConf) conf = wp_core_get_conf (get_wp_core (L)); + g_autoptr (WpSpaJson) s = NULL; + + if (conf) { + s = wp_conf_get_section (conf, section); + if (s && wp_spa_json_is_array (s)) { + push_luajson (L, s, INT_MAX); + return 1; + } + } + + if (lua_istable (L, 2)) + lua_pushvalue (L, 2); + else + lua_newtable (L); + return 1; +} + +static int +conf_get_section_as_json (lua_State *L) +{ + const char *section = luaL_checkstring (L, 1); + g_autoptr (WpConf) conf = NULL; + g_autoptr (WpSpaJson) s = NULL; + WpSpaJson *fb = NULL; + + if (lua_isuserdata (L, 2)) + fb = wplua_checkboxed (L, 2, WP_TYPE_SPA_JSON); + + conf = wp_core_get_conf (get_wp_core (L)); + if (conf) { + s = wp_conf_get_section (conf, section); + if (!s && fb) + s = wp_spa_json_ref (fb); + if (s) { + wplua_pushboxed (L, WP_TYPE_SPA_JSON, + wp_spa_json_ensure_unique_owner (g_steal_pointer (&s))); + return 1; + } + } + + lua_pushnil (L); return 1; } static const luaL_Reg conf_methods[] = { - { "get_section", conf_get_section }, + { "get_section_as_properties", conf_get_section_as_properties }, + { "get_section_as_object", conf_get_section_as_object }, + { "get_section_as_array", conf_get_section_as_array }, + { "get_section_as_json", conf_get_section_as_json }, { NULL, NULL } }; diff --git a/src/scripts/client/access-default.lua b/src/scripts/client/access-default.lua index 308bc1aa..a00f16e9 100644 --- a/src/scripts/client/access-default.lua +++ b/src/scripts/client/access-default.lua @@ -43,7 +43,7 @@ function getDefaultPermissions (properties) end function getPermissions (properties) - local section = Conf.get_section ("access.rules") + local section = Conf.get_section_as_json ("access.rules") if section then local matched, mprops = JsonUtils.match_rules_update_properties ( section, properties) diff --git a/src/scripts/lib/common-utils.lua b/src/scripts/lib/common-utils.lua index a3ee1ab6..e302426a 100644 --- a/src/scripts/lib/common-utils.lua +++ b/src/scripts/lib/common-utils.lua @@ -84,7 +84,7 @@ function cutils.get_default_metadata_object () end function cutils.evaluateRulesApplyProperties (properties, name) - local section = Conf.get_section (name) + local section = Conf.get_section_as_json (name) if not section then return end @@ -112,26 +112,4 @@ function cutils.get_application_name () return Core.get_properties()["application.name"] or "WirePlumber" end -function cutils.get_config_section (name, defaults) - local section = Conf.get_section (name) - if not section then - section = defaults or {} - else - section = section:parse () - if defaults then - for k, v in pairs (defaults) do - if section [k] == nil then - section [k] = v - end - end - for k, v in ipairs (defaults) do - if section [k] == nil then - section [k] = v - end - end - end - end - return section -end - return cutils diff --git a/src/scripts/linking/find-virtual-target.lua b/src/scripts/linking/find-virtual-target.lua index 4e81c780..14783d80 100644 --- a/src/scripts/linking/find-virtual-target.lua +++ b/src/scripts/linking/find-virtual-target.lua @@ -9,12 +9,8 @@ lutils = require ("linking-utils") log = Log.open_topic ("s-linking") -defaults = {} -defaults.roles = Json.Object {} - config = {} -config.roles = Conf.get_section ( - "virtual-item-roles", defaults.roles):parse () +config.roles = Conf.get_section_as_object ("virtual-item-roles") function findRole(role, tmc) if role and not config.roles[role] then diff --git a/src/scripts/linking/rescan-virtual-links.lua b/src/scripts/linking/rescan-virtual-links.lua index 89f806d3..bc96c31d 100644 --- a/src/scripts/linking/rescan-virtual-links.lua +++ b/src/scripts/linking/rescan-virtual-links.lua @@ -10,13 +10,10 @@ log = Log.open_topic ("s-linking") defaults = {} defaults.duck_level = 0.3 -defaults.roles = Json.Object {} config = {} -config.duck_level = Conf.get_value_float ("wireplumber.settings", - "linking.default.duck-level", defaults.duck_level) -config.roles = Conf.get_section ( - "virtual-item-roles", defaults.roles):parse () +config.duck_level = default.duck_level -- FIXME +config.roles = Conf.get_section_as_object ("virtual-item-roles") -- enable ducking if mixer-api is loaded mixer_api = Plugin.find("mixer-api") diff --git a/src/scripts/monitors/alsa-midi.lua b/src/scripts/monitors/alsa-midi.lua index 7b60d4f7..120b118e 100644 --- a/src/scripts/monitors/alsa-midi.lua +++ b/src/scripts/monitors/alsa-midi.lua @@ -8,9 +8,22 @@ cutils = require ("common-utils") log = Log.open_topic ("s-monitors") +defaults = {} +defaults.node_properties = { -- Midi bridge node properties + ["factory.name"] = "api.alsa.seq.bridge", + + -- Name set for the node with ALSA MIDI ports + ["node.name"] = "Midi-Bridge", + + -- Set priorities so that it can be used as a fallback driver (see pipewire#3562) + ["priority.session"] = "100", + ["priority.driver"] = "1", +} + config = {} config.monitoring = Core.test_feature ("monitor.alsa-midi.monitoring") -config.node_properties = cutils.get_config_section ("monitor.alsa-midi.properties") +config.node_properties = Conf.get_section_as_properties ( + "monitor.alsa-midi.properties", defaults.node_properties) SND_PATH = "/dev/snd" SEQ_NAME = "seq" @@ -20,23 +33,8 @@ midi_node = nil fm_plugin = nil function CreateMidiNode () - -- Midi properties - local props = { - ["factory.name"] = "api.alsa.seq.bridge", - - -- Name set for the node with ALSA MIDI ports - ["node.name"] = "Midi-Bridge", - - -- Set priorities so that it can be used as a fallback driver (see pipewire#3562) - ["priority.session"] = "100", - ["priority.driver"] = "1", - } - for k, v in pairs(config.node_properties) do - props[k] = v - end - -- create the midi node - local node = Node("spa-node-factory", props) + local node = Node("spa-node-factory", config.node_properties) node:activate(Feature.Proxy.BOUND, function (n) log:info ("activated Midi bridge") end) diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua index ca746ec5..4ba43675 100644 --- a/src/scripts/monitors/alsa.lua +++ b/src/scripts/monitors/alsa.lua @@ -10,7 +10,7 @@ log = Log.open_topic ("s-monitors") config = {} config.reserve_device = Core.test_feature ("monitor.alsa.reserve-device") -config.properties = cutils.get_config_section ("monitor.alsa.properties") +config.properties = Conf.get_section_as_properties ("monitor.alsa.properties") -- unique device/node name tables device_names_table = nil diff --git a/src/scripts/monitors/bluez-midi.lua b/src/scripts/monitors/bluez-midi.lua index 1d0beb57..a33cca45 100644 --- a/src/scripts/monitors/bluez-midi.lua +++ b/src/scripts/monitors/bluez-midi.lua @@ -13,8 +13,8 @@ defaults.servers = { "bluez_midi.server" } config = {} config.seat_monitoring = Core.test_feature ("monitor.bluez.seat-monitoring") -config.properties = cutils.get_config_section ("monitor.bluez-midi.properties") -config.servers = cutils.get_config_section ("monitor.bluez-midi.servers", defaults.servers) +config.properties = Conf.get_section_as_properties ("monitor.bluez-midi.properties") +config.servers = Conf.get_section_as_array ("monitor.bluez-midi.servers", defaults.servers) -- unique device/node name tables node_names_table = nil diff --git a/src/scripts/monitors/bluez.lua b/src/scripts/monitors/bluez.lua index 930410b0..319b5310 100644 --- a/src/scripts/monitors/bluez.lua +++ b/src/scripts/monitors/bluez.lua @@ -14,7 +14,7 @@ log = Log.open_topic ("s-monitors") config = {} config.seat_monitoring = Core.test_feature ("monitor.bluez.seat-monitoring") -config.properties = cutils.get_config_section ("monitor.bluez.properties") +config.properties = Conf.get_section_as_properties ("monitor.bluez.properties") -- This is not a setting, it must always be enabled config.properties["api.bluez5.connection-info"] = true diff --git a/src/scripts/monitors/libcamera/enumerate-device.lua b/src/scripts/monitors/libcamera/enumerate-device.lua index 9e716234..e6e8361d 100644 --- a/src/scripts/monitors/libcamera/enumerate-device.lua +++ b/src/scripts/monitors/libcamera/enumerate-device.lua @@ -9,7 +9,7 @@ cutils = require ("common-utils") log = Log.open_topic ("s-monitors-libcamera") config = {} -config.properties = cutils.get_config_section ("monitor.libcamera.properties") +config.properties = Conf.get_section_as_properties ("monitor.libcamera.properties") function createCamDevice (parent, id, type, factory, properties) source = source or Plugin.find ("standard-event-source") diff --git a/src/scripts/monitors/v4l2/enumerate-device.lua b/src/scripts/monitors/v4l2/enumerate-device.lua index 0b2daa31..87564d1c 100644 --- a/src/scripts/monitors/v4l2/enumerate-device.lua +++ b/src/scripts/monitors/v4l2/enumerate-device.lua @@ -9,7 +9,7 @@ cutils = require ("common-utils") log = Log.open_topic ("s-monitors-v4l2") config = {} -config.properties = cutils.get_config_section ("monitor.v4l2.properties") +config.properties = Conf.get_section_as_properties ("monitor.v4l2.properties") function createCamDevice (parent, id, type, factory, properties) source = source or Plugin.find ("standard-event-source") diff --git a/src/scripts/node/create-virtual-item.lua b/src/scripts/node/create-virtual-item.lua index 1c857c69..67008b09 100644 --- a/src/scripts/node/create-virtual-item.lua +++ b/src/scripts/node/create-virtual-item.lua @@ -11,12 +11,8 @@ log = Log.open_topic ("s-node") -defaults = {} -defaults.virtual_items = Json.Object {} - config = {} -config.virtual_items = Conf.get_section ( - "virtual-items", defaults.virtual_items):parse () +config.virtual_items = Conf.get_section_as_object ("virtual-items") function createVirtualItem (factory_name, properties) -- create virtual item