Module: Syskit::DataFlow::Extension

Defined in:
lib/syskit/data_flow.rb

Overview

Methods that are mixed-in Syskit::Component to help with connection management

Defined Under Namespace

Classes: NotComposition, NotInputPort, NotOutputPort

Instance Method Summary collapse

Instance Method Details

#all_inputs_connected?(only_static: false) ⇒ Boolean

Returns true if all the declared connections to the inputs of task have been applied. A given module won't be started until it is the case.

If the only_static flag is set to true, only ports that require static connections will be considered

Returns:

  • (Boolean)


439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'lib/syskit/data_flow.rb', line 439

def all_inputs_connected?(only_static: false)
    logger = Runtime::ConnectionManagement
    each_concrete_input_connection do |source_task, source_port, sink_port, policy|
        # Our source may not be initialized at all
        if !source_task.orocos_task
            logger.debug do
                logger.debug "missing input connection because the source task is not ready on port #{sink_port} of"
                logger.log_pp :debug, self
                logger.log_nest(2) do
                    logger.debug "connection expected to port #{source_port} of"
                    logger.log_pp :debug, source_task
                end
                break
            end
            return false
        end
        if only_static && !concrete_model.find_input_port(sink_port)
            next
        end

        is_connected =
            ActualDataFlow.has_edge?(source_task.orocos_task, orocos_task) &&
            ActualDataFlow.edge_info(source_task.orocos_task, orocos_task).
                has_key?([source_port, sink_port])

        if !is_connected
            logger.debug do
                logger.debug "missing input connection on port #{sink_port} of"
                logger.log_pp :debug, self
                logger.log_nest(2) do
                    logger.debug "  connection expected to port #{source_port} of"
                    logger.log_pp :debug, source_task
                end
                break
            end
            return false
        end
    end
    true
end

#connect_ports(sink_task, mappings) ⇒ Object

Connect a set of ports between self and target_task.

mappings describes the connections. It is a hash of the form

[source_port_name, sink_port_name] => connection_policy

where source_port_name is a port of self and sink_port_name a port of target_task

Raises ArgumentError if one of the ports do not exist.



325
326
327
328
329
330
331
332
333
# File 'lib/syskit/data_flow.rb', line 325

def connect_ports(sink_task, mappings)
    return if mappings.empty?

    mappings.each do |(out_port, in_port), options|
        ensure_has_output_port(out_port)
        sink_task.ensure_has_input_port(in_port)
    end
    add_sink(sink_task, mappings)
end

#connected?(port_name) ⇒ Boolean

Returns true if port_name is connected

Returns:

  • (Boolean)


302
303
304
305
306
# File 'lib/syskit/data_flow.rb', line 302

def connected?(port_name)
    dataflow_graph = relation_graph_for(Flows::DataFlow)
    dataflow_graph.has_out_connections?(self, port_name) ||
        dataflow_graph.has_in_connections?(self, port_name)
end

#connected_to?(port_name, other_task, other_port) ⇒ Boolean

Tests if port_name is connected to other_port on other_task

Returns:

  • (Boolean)


310
311
312
313
# File 'lib/syskit/data_flow.rb', line 310

def connected_to?(port_name, other_task, other_port)
    relation_graph_for(Flows::DataFlow).
        connected?(self, port_name, other_task, other_port)
end

#disconnect_port(port_name) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/syskit/data_flow.rb', line 344

def disconnect_port(port_name)
    if port_name.respond_to?(:name)
        port_name = port_name.name
    end

    each_source do |parent_task|
        current = parent_task[self, Flows::DataFlow]
        current.delete_if { |(from, to), pol| to == port_name }
        parent_task[self, Flows::DataFlow] = current
    end
    each_sink do |child_task|
        current = self[child_task, Flows::DataFlow]
        current.delete_if { |(from, to), pol| from == port_name }
        self[child_task, Flows::DataFlow] = current
    end
end

#disconnect_ports(sink_task, mappings) ⇒ Object



335
336
337
338
339
340
341
342
# File 'lib/syskit/data_flow.rb', line 335

def disconnect_ports(sink_task, mappings)
    mappings.each do |out_port, in_port|
        ensure_has_output_port(out_port)
        sink_task.ensure_has_input_port(in_port)
    end
    relation_graph_for(Flows::DataFlow).
        remove_connections(self, sink_task, mappings)
end

#each_concrete_input_connection(port = nil, &block) ⇒ Object



385
386
387
388
# File 'lib/syskit/data_flow.rb', line 385

def each_concrete_input_connection(port = nil, &block)
    relation_graph_for(Flows::DataFlow).
        each_concrete_in_connection(self, port, &block)
end

#each_concrete_output_connection(port = nil, &block) ⇒ Object



404
405
406
407
# File 'lib/syskit/data_flow.rb', line 404

def each_concrete_output_connection(port = nil, &block)
    relation_graph_for(Flows::DataFlow).
        each_concrete_out_connection(self, port, &block)
end

#each_input_connection(port = nil) {|source_task, source_port, sink_port, policy| ... } ⇒ Object

Yield or enumerates the connections that exist towards the input ports of self.

Parameters:

  • port (#name, String, nil) (defaults to: nil)

    if non-nil, the port for which we want to enumerate the connections (in which case the sink_port yield parameter is guaranteed to be this name). Otherwise, all ports are enumerated.

Yields:

  • each connections

Yield Parameters:

  • source_task (Syskit::TaskContext)

    the source task in the connection

  • source_port (String)

    the source port name on source_task

  • sink_port (String)

    the sink port name on self. If the port argument is non-nil, it is guaranteed to be the same.

  • policy (Hash)

    the connection policy

See Also:



380
381
382
383
# File 'lib/syskit/data_flow.rb', line 380

def each_input_connection(port = nil, &block)
    relation_graph_for(Flows::DataFlow).
        each_in_connection(self, port, &block)
end

#each_output_connection(port = nil) {|source_port, sink_port, sink_task, policy| ... } ⇒ Object

Yield or enumerates the connections that exist from the output ports of self.

Parameters:

  • source_task (Component)

    the task whose connections are being enumerated

  • port (#name, String, nil) (defaults to: nil)

    if non-nil, the port for which we want to enumerate the connections (in which case the source_port yield parameter is guaranteed to be this name). Otherwise, all ports are enumerated.

Yields:

  • each connections

Yield Parameters:

  • source_port (String)

    the source port name on self. If the port argument is non-nil, it is guaranteed to be the same.

  • sink_port (String)

    the sink port name on sink_task.

  • sink_task (Syskit::Component)

    the sink task in the connection

  • policy (Hash)

    the connection policy



429
430
431
432
# File 'lib/syskit/data_flow.rb', line 429

def each_output_connection(port = nil, &block)
    relation_graph_for(Flows::DataFlow).
        each_out_connection(self, port, &block)
end

#ensure_has_input_port(name) ⇒ Object

Makes sure that self has an input port called name. It will instanciate a dynamic port if needed.

Raises ArgumentError if no such port can ever exist on self



266
267
268
269
270
# File 'lib/syskit/data_flow.rb', line 266

def ensure_has_input_port(name)
    if !model.find_input_port(name)
        raise NotInputPort, "#{self} has no input port called #{name}"
    end
end

#ensure_has_output_port(name) ⇒ Object

Makes sure that self has an output port called name. It will instanciate a dynamic port if needed.

Raises ArgumentError if no such port can ever exist on self



256
257
258
259
260
# File 'lib/syskit/data_flow.rb', line 256

def ensure_has_output_port(name)
    if !model.find_output_port(name)
        raise NotOutputPort, "#{self} has no output port called #{name}"
    end
end

#forward_input_ports(task, mappings) ⇒ Object

Forward an input of self to an input port of another task



273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/syskit/data_flow.rb', line 273

def forward_input_ports(task, mappings)
    if !fullfills?(Composition)
        raise NotComposition, "#{self} is not a composition"
    elsif mappings.empty?
        return
    end

    mappings.each do |(from, to), options|
        ensure_has_input_port(from)
        task.ensure_has_input_port(to)
    end
    add_sink(task, mappings)
end

#forward_output_ports(task, mappings) ⇒ Object



287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/syskit/data_flow.rb', line 287

def forward_output_ports(task, mappings)
    if !task.fullfills?(Composition)
        raise NotComposition, "#{self} is not a composition"
    elsif mappings.empty?
        return
    end

    mappings.each do |(from, to), options|
        ensure_has_output_port(from)
        task.ensure_has_output_port(to)
    end
    add_sink(task, mappings)
end

#has_concrete_input_connection?(port) ⇒ Boolean

Tests if an input port or any input ports is connected to an actual task (ignoring composition exports)

Parameters:

  • port (#name, String, nil)

    if non-nil, only connections involving this port will be tested against. Otherwise, the method tests for any inbound connection to self

Returns:

  • (Boolean)

    true if the given port, or the task, is connected to something by an inbound connection



399
400
401
402
# File 'lib/syskit/data_flow.rb', line 399

def has_concrete_input_connection?(port)
    each_concrete_input_connection(port) { return true }
    false
end

#has_concrete_output_connection?(port) ⇒ Boolean

Tests if an output port or any output ports is connected to an actual task (ignoring composition exports)

Parameters:

  • port (#name, String, nil)

    if non-nil, only connections involving this port will be tested against. Otherwise, the method tests for any outbound connection to self

Returns:

  • (Boolean)

    true if the given port, or the task, is connected to something by an outbound connection



418
419
420
421
# File 'lib/syskit/data_flow.rb', line 418

def has_concrete_output_connection?(port)
    each_concrete_output_connection(port) { return true }
    false
end