diff --git a/lib/syskit/dynamic_port_binding.rb b/lib/syskit/dynamic_port_binding.rb index b503a28d9..4c443f6ae 100644 --- a/lib/syskit/dynamic_port_binding.rb +++ b/lib/syskit/dynamic_port_binding.rb @@ -99,6 +99,10 @@ def attach_to_task(task) # the port was updated, and false otherwise. The tuple's second element # is the new resolved port which may be nil if no ports can be found def update + if @resolved_port && @port_resolver&.current_selection_valid?(@resolved_port) + return false, @resolved_port + end + port = @port_resolver&.update return false, @resolved_port if @resolved_port == port @@ -294,6 +298,10 @@ def initialize(plan, matcher) @last_provider_task = nil end + def current_selection_valid?(port) + @matcher === port + end + def update port = @matcher.each_in_plan(@plan).first port&.to_actual_port @@ -319,6 +327,10 @@ def initialize(port) @port = port end + def current_selection_valid?(port) + !!port.component.plan + end + def update @port if @port.component.plan end @@ -337,6 +349,10 @@ def initialize(port) @port = port end + def current_selection_valid?(port) + !!port.component.to_task.plan + end + def update @port if @port.component.to_task.plan end diff --git a/lib/syskit/queries/port_matcher.rb b/lib/syskit/queries/port_matcher.rb index e670fc00b..bce3c7c40 100644 --- a/lib/syskit/queries/port_matcher.rb +++ b/lib/syskit/queries/port_matcher.rb @@ -57,9 +57,9 @@ def with_type(type) def ===(port) return unless port.kind_of?(Port) - (@name_filter === object.name) && - (!@type_filter || @type_filter == object.type) && - (@component_matcher === object.component) + (@name_filter === port.name) && + (!@type_filter || @type_filter == port.type) && + (@component_matcher === port.component) end def each_in_plan(plan, &block) diff --git a/test/queries/test_port_matcher.rb b/test/queries/test_port_matcher.rb index ab22e9221..f34148e07 100644 --- a/test/queries/test_port_matcher.rb +++ b/test/queries/test_port_matcher.rb @@ -30,6 +30,13 @@ module Queries PortMatcher.new(@task_m).with_name("out_d") end + it "can find ports with ===" do + plan.add(task = @task_m.new) + matcher = PortMatcher.new(@task_m).with_name("out_d") + assert matcher === task.out_d_port + refute matcher === task.out_f_port + end + it "optionally allows to filter with a name pattern" do plan.add(task = @task_m.new) assert_matcher_finds [task.out_d_port, task.out_f_port],