mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-01-08 10:10:14 +01:00
scripts/lib: add a new settings manager lua library
This intends to reduce the amount of code needed to maintain tables of settings values across different scripts
This commit is contained in:
parent
73870c528b
commit
57d4a8cb07
1 changed files with 124 additions and 0 deletions
124
src/scripts/lib/settings-manager.lua
Normal file
124
src/scripts/lib/settings-manager.lua
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
-- WirePlumber
|
||||
--
|
||||
-- Copyright © 2022 Collabora Ltd.
|
||||
--
|
||||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- Settings manager helper
|
||||
--
|
||||
-- This sets up a lua table that will automatically populate itself with
|
||||
-- values from the settings, falling back to the default values specified.
|
||||
-- Any changes in the settings will automatically change the values of this
|
||||
-- table.
|
||||
--
|
||||
-- Usage:
|
||||
--
|
||||
-- local settings_manager = require ("settings-manager")
|
||||
-- local defaults = {
|
||||
-- ["foo"] = true,
|
||||
-- ["foo-bar"] = 3,
|
||||
-- }
|
||||
-- local settings = settings_manager.new ("example.prefix.", defaults)
|
||||
--
|
||||
-- The above "settings" table should now look like this internally:
|
||||
-- {
|
||||
-- foo = true, -- or the value specified in the Settings
|
||||
-- foo_bar = 3, -- or the value specified in the Settings
|
||||
-- }
|
||||
--
|
||||
-- Additionally, a "subscribe" method is present in the "settings" table, which
|
||||
-- allows subscribing to changes of the values:
|
||||
--
|
||||
-- settings:subscribe ("foo-bar", function (new_value)
|
||||
-- Log.info ("foo-bar value changed to " .. new_value)
|
||||
-- end)
|
||||
--
|
||||
|
||||
local settings_manager = {}
|
||||
local private_api = {}
|
||||
|
||||
function private_api.subscribe (self, key, closure)
|
||||
if not self.subscribers[key] then
|
||||
self.subscribers[key] = {}
|
||||
end
|
||||
table.insert (self.subscribers, closure)
|
||||
end
|
||||
|
||||
function private_api.call_subscribers (self, key, new_value)
|
||||
if self.subscribers[key] then
|
||||
for i, closure in ipairs (self.subscribers[key]) do
|
||||
closure (new_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function private_api.update_value (self, key, json_value, default)
|
||||
local new_value = json_value and json_value:parse () or default
|
||||
|
||||
-- only accept values that have the same type as the default value
|
||||
if type (new_value) ~= type (default) then
|
||||
new_value = default
|
||||
end
|
||||
|
||||
-- store only if the new value is not equal to the default
|
||||
self.values[key] = (new_value ~= default) and new_value or nil
|
||||
|
||||
return new_value
|
||||
end
|
||||
|
||||
function settings_manager.new (_prefix, _defaults)
|
||||
-- private storage table
|
||||
local private = {
|
||||
prefix = _prefix,
|
||||
prefix_len = string.len (_prefix),
|
||||
defaults = _defaults,
|
||||
values = {},
|
||||
subscribers = {},
|
||||
}
|
||||
setmetatable (private, { __index = private_api })
|
||||
|
||||
-- initialize with the values found in Settings
|
||||
for key, default in pairs (private.defaults) do
|
||||
local json_value = Settings.get (private.prefix .. key)
|
||||
private:update_value (key, json_value, default)
|
||||
end
|
||||
|
||||
-- subscribe for changes in Settings
|
||||
Settings.subscribe (private.prefix .. "*", function (_, setting, json_value)
|
||||
local key = string.sub (setting, private.prefix_len, -1)
|
||||
local default = private.defaults[key]
|
||||
|
||||
-- unknown key, ignore it
|
||||
if default == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local new_value = private:update_value (key, json_value, default)
|
||||
private:call_subscribers (key, new_value)
|
||||
end)
|
||||
|
||||
-- return an empty table with a metatable that will resolve
|
||||
-- keys to the values stored in `private` or their default values
|
||||
return setmetatable ({}, {
|
||||
__private = private,
|
||||
__index = function (self, key)
|
||||
if key == "subscribe" then
|
||||
-- special case, "subscribe" is a method
|
||||
return function (self, key, closure)
|
||||
local private = getmetatable (self) ["__private"]
|
||||
private:subscribe (key, closure)
|
||||
end
|
||||
else
|
||||
local private = getmetatable (self) ["__private"]
|
||||
key = string.gsub (key, "_", "-") -- foo_bar_baz -> foo-bar-baz
|
||||
local value = private.values[key]
|
||||
return (value ~= nil) and value or private.defaults[key]
|
||||
end
|
||||
end,
|
||||
__newindex = function(_, key, _)
|
||||
error ('Not allowed to modify configuration value')
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
return settings_manager
|
||||
Loading…
Add table
Reference in a new issue