state-routes.lua: Use the returned iterator from enum_params() to update routes info

This does not really fix anything but it saves some CPU cycles as we don't need
to get the route params from the cache anymore.
This commit is contained in:
Julian Bouzas 2025-10-02 10:22:21 -04:00
parent 4239055454
commit e30c2a7cd9

View file

@ -159,129 +159,125 @@ store_or_restore_routes_hook = AsyncEventHook {
}, },
steps = { steps = {
start = { start = {
next = "evaluate", next = "none",
execute = function (event, transition) execute = function (event, transition)
local source = event:get_source ()
local device = event:get_subject ()
-- Make sure the routes are always updated before evaluating them. -- Make sure the routes are always updated before evaluating them.
-- https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/762 -- https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/762
local device = event:get_subject () device:enum_params ("EnumRoute", function (enum_route_it, e)
device:enum_params ("EnumRoute", function (_, e) local selected_routes = {}
local push_select_routes = false
-- check for error
if e then if e then
transition:return_error ("failed to enum routes: " transition:return_error ("failed to enum routes: "
.. tostring (e)); .. tostring (e));
else return
end
-- Make sure the device is still valid
if (device:get_active_features() & Feature.Proxy.BOUND) == 0 then
transition:advance () transition:advance ()
end return
end)
end
},
evaluate = {
next = "none",
execute = function (event, transition)
local device = event:get_subject ()
local source = event:get_source ()
local selected_routes = {}
local push_select_routes = false
-- Make sure the device is still valid
if (device:get_active_features() & Feature.Proxy.BOUND) == 0 then
transition:advance ()
return
end
local dev_info = devinfo:get_device_info (device)
if not dev_info then
transition:advance ()
return
end
local new_route_infos = {}
-- look at all the routes and update/reset cached information
for p in device:iterate_params ("EnumRoute") do
-- parse pod
local route = cutils.parseParam (p, "EnumRoute")
if not route then
goto skip_enum_route
end end
-- find cached route information local dev_info = devinfo:get_device_info (device)
local route_info = devinfo.find_route_info (dev_info, route, true) if not dev_info then
if not route_info then transition:advance ()
goto skip_enum_route return
end end
-- update properties local new_route_infos = {}
route_info.prev_active = route_info.active
route_info.active = false
route_info.save = false
-- store -- look at all the routes and update/reset cached information
new_route_infos [route.index] = route_info for p in enum_route_it:iterate() do
-- parse pod
local route = cutils.parseParam (p, "EnumRoute")
if not route then
goto skip_enum_route
end
::skip_enum_route:: -- find cached route information
end local route_info = devinfo.find_route_info (dev_info, route, true)
if not route_info then
goto skip_enum_route
end
-- update route_infos with new prev_active, active and save changes -- update properties
dev_info.route_infos = new_route_infos route_info.prev_active = route_info.active
new_route_infos = nil route_info.active = false
route_info.save = false
-- check for changes in the active routes -- store
for p in device:iterate_params ("Route") do new_route_infos [route.index] = route_info
local route = cutils.parseParam (p, "Route")
if not route then ::skip_enum_route::
goto skip_route
end end
-- get cached route info and at the same time -- update route_infos with new prev_active, active and save changes
-- ensure that the route is also in EnumRoute dev_info.route_infos = new_route_infos
local route_info = devinfo.find_route_info (dev_info, route, false) new_route_infos = nil
if not route_info then
goto skip_route
end
-- update route_info state -- check for changes in the active routes
route_info.active = true for p in device:iterate_params ("Route") do
route_info.save = route.save local route = cutils.parseParam (p, "Route")
if not route then
goto skip_route
end
if not route_info.prev_active then -- get cached route info and at the same time
-- a new route is now active, restore the volume and -- ensure that the route is also in EnumRoute
-- make sure we save this as a preferred route local route_info = devinfo.find_route_info (dev_info, route, false)
log:info (device, if not route_info then
string.format ("new active route(%s) found of device(%s)", goto skip_route
route.name, dev_info.name)) end
route_info.prev_active = true
-- update route_info state
route_info.active = true route_info.active = true
route_info.save = route.save
selected_routes [tostring (route.device)] = if not route_info.prev_active then
Json.Object { index = route_info.index }:to_string () -- a new route is now active, restore the volume and
push_select_routes = true -- make sure we save this as a preferred route
log:info (device,
string.format ("new active route(%s) found of device(%s)",
route.name, dev_info.name))
route_info.prev_active = true
route_info.active = true
elseif route.available ~= "no" and route.save and route.props then selected_routes [tostring (route.device)] =
-- just save route properties Json.Object { index = route_info.index }:to_string ()
log:info (device, push_select_routes = true
string.format ("storing route(%s) props of device(%s)",
route.name, dev_info.name))
saveRouteProps (dev_info, route) elseif route.available ~= "no" and route.save and route.props then
-- just save route properties
log:info (device,
string.format ("storing route(%s) props of device(%s)",
route.name, dev_info.name))
saveRouteProps (dev_info, route)
end
::skip_route::
end end
::skip_route:: -- save selected routes for the active profile
end for p in device:iterate_params ("Profile") do
local profile = cutils.parseParam (p, "Profile")
saveProfileRoutes (dev_info, profile.name)
end
-- save selected routes for the active profile -- push a select-routes event to re-apply the routes with new properties
for p in device:iterate_params ("Profile") do if push_select_routes then
local profile = cutils.parseParam (p, "Profile") local e = source:call ("create-event", "select-routes", device, nil)
saveProfileRoutes (dev_info, profile.name) e:set_data ("selected-routes", selected_routes)
end EventDispatcher.push_event (e)
end
-- push a select-routes event to re-apply the routes with new properties transition:advance ()
if push_select_routes then end)
local e = source:call ("create-event", "select-routes", device, nil)
e:set_data ("selected-routes", selected_routes)
EventDispatcher.push_event (e)
end
transition:advance ()
end end
} }
} }