diff --git a/src/scripts/node/create-item.lua b/src/scripts/node/create-item.lua index 259ebc83..f77e0dc2 100644 --- a/src/scripts/node/create-item.lua +++ b/src/scripts/node/create-item.lua @@ -17,6 +17,7 @@ function configProperties (node) local properties = node.properties local media_class = properties ["media.class"] or "" local factory_name = properties ["factory.name"] or "" + local collection = CollectionManager.get_global_collection (node) -- ensure a media.type is set if not properties ["media.type"] then @@ -44,6 +45,7 @@ function configProperties (node) (factory_name == "api.alsa.pcm.sink" or factory_name == "api.bluez5.a2dp.sink") and Settings.get_boolean ("node.features.audio.mono") properties ["node.id"] = node ["bound-id"] + properties ["collection.name"] = collection and collection:get_name () or nil -- set the default media.role, if configured -- avoid Settings.get_string(), as it will parse the default "null" value @@ -61,69 +63,76 @@ AsyncEventHook { name = "node/create-item", interests = { EventInterest { - Constraint { "event.type", "=", "node-added" }, + Constraint { "event.type", "c", "node-added", "node-collected", "node-dropped" }, Constraint { "media.class", "#", "Stream/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "node-added" }, + Constraint { "event.type", "c", "node-added", "node-collected", "node-dropped" }, Constraint { "media.class", "#", "Video/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "node-added" }, + Constraint { "event.type", "c", "node-added", "node-collected", "node-dropped" }, Constraint { "media.class", "#", "Audio/*", type = "pw-global" }, Constraint { "wireplumber.is-virtual", "-", type = "pw" }, }, }, steps = { start = { - next = "register", + next = "none", execute = function (event, transition) local node = event:get_subject () local id = node.id - local item - local item_type - local media_class = node.properties ['media.class'] + local node_name = node.properties ['node.name'] + local collection = CollectionManager.get_global_collection (node) + local collection_name = collection and collection:get_name () or nil + + -- Just return if the item already exists with the same collection name + if items [id] and + items [id]:get_property ("collection.name") == collection_name then + transition:advance () + return + end + + -- Destroy the old item if any + if items [id] then + log:info (items [id], "destroying item for node " .. tostring (id)) + items [id]:remove () + items [id] = nil + end + + -- get the item type + local item_type = nil if string.find (media_class, "Audio") then item_type = "si-audio-adapter" else item_type = "si-node" end - log:info (node, "creating item for node -> " .. item_type) - -- create item - item = SessionItem (item_type) + local item = SessionItem (item_type) items [id] = item + log:info (item, "created item for node " .. tostring (id) .. ": " .. node_name) -- configure item if not item:configure (configProperties (node)) then - transition:return_error ("failed to configure item for node " - .. tostring (id)) + transition:return_error ("failed to configure item for node " .. tostring (id)) return end -- activate item item:activate (Features.ALL, function (_, e) if e then - transition:return_error ("failed to activate item: " - .. tostring (e)); - else - transition:advance () + transition:return_error ("failed to activate item for node " .. tostring (id) .. + ": " .. tostring (e)); + return end - end) - end, - }, - register = { - next = "none", - execute = function (event, transition) - local node = event:get_subject () - local bound_id = node ["bound-id"] - local item = items [node.id] - log:info (item, "activated item for node " .. tostring (bound_id)) - item:register () - transition:advance () + -- register item + log:info (item, "activated item for node " .. tostring (id) .. ": " .. node_name) + item:register () + transition:advance () + end) end, }, },