Class: Syskit::Models::DynamicDataService

Inherits:
Object
  • Object
show all
Defined in:
lib/syskit/models/dynamic_data_service.rb

Overview

Representation of a dynamic service registered with Component#dynamic_service

Defined Under Namespace

Classes: InstantiationContext

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component_model, name, service_model, block, addition_requires_reconfiguration: true, remove_when_unused: false) ⇒ DynamicDataService

Returns a new instance of DynamicDataService



20
21
22
23
24
25
# File 'lib/syskit/models/dynamic_data_service.rb', line 20

def initialize(component_model, name, service_model, block, addition_requires_reconfiguration: true, remove_when_unused: false)
    @component_model, @name, @service_model, @block = component_model, name, service_model, block
    @addition_requires_reconfiguration = addition_requires_reconfiguration
    @remove_when_unused = remove_when_unused
    @demoted = self
end

Instance Attribute Details

#blockObject (readonly)

The service definition block



13
14
15
# File 'lib/syskit/models/dynamic_data_service.rb', line 13

def block
  @block
end

#component_modelObject (readonly)

The component model we are bound to



7
8
9
# File 'lib/syskit/models/dynamic_data_service.rb', line 7

def component_model
  @component_model
end

#demotedObject (readonly)

The actual dynamic data service model we've been promoted from

See BoundDataService documentation for a discussion on promotion



50
51
52
# File 'lib/syskit/models/dynamic_data_service.rb', line 50

def demoted
  @demoted
end

#nameObject (readonly)

The dynamic service name



9
10
11
# File 'lib/syskit/models/dynamic_data_service.rb', line 9

def name
  @name
end

#service_modelObject (readonly)

The service model



11
12
13
# File 'lib/syskit/models/dynamic_data_service.rb', line 11

def service_model
  @service_model
end

Class Method Details

.directional_port_mapping(component_model, direction, port, expected_name) ⇒ Object

Validates the setup for a single data service port, and computes the port mapping for it. It validates the port creation rule that a mapping must be given for a port to be created.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/syskit/models/dynamic_data_service.rb', line 160

def self.directional_port_mapping(component_model, direction, port, expected_name)
    # Filter out the ports that already exist on the component
    if expected_name
        if component_model.send("find_#{direction}_port", expected_name)
            return expected_name
        end
    else
        expected_name = component_model.find_directional_port_mapping(direction, port, nil)
        if !expected_name
            raise InvalidPortMapping, "no explicit mapping has been given for the service port #{port.name} and no port on #{component_model.short_name} matches. You must give an explicit mapping of the form 'service_port_name' => 'task_port_name' if you expect the port to be dynamically created."
        end
        return expected_name
    end

    # Now verify that the rest can be instanciated
    if !component_model.send("has_dynamic_#{direction}_port?", expected_name, port.type)
        raise InvalidPortMapping, "there are no dynamic #{direction} ports declared in #{component_model.short_name} that match #{expected_name}:#{port.type_name}"
    end
    return expected_name
end

.update_component_model_interface(component_model, service_model, user_port_mappings) ⇒ Hash{String=>String}

Updates the component_model's oroGen interface description to include the ports needed for the given dynamic service model

Returns:

  • (Hash{String=>String})

    the updated port mappings



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/syskit/models/dynamic_data_service.rb', line 136

def self.update_component_model_interface(component_model, service_model, user_port_mappings)
    user_port_mappings = user_port_mappings.dup
    port_mappings = Hash.new
    service_model.each_output_port do |service_port|
        port_mappings[service_port.name] = directional_port_mapping(component_model, 'output', service_port, user_port_mappings.delete(service_port.name))
    end
    service_model.each_input_port do |service_port|
        port_mappings[service_port.name] = directional_port_mapping(component_model, 'input', service_port, user_port_mappings.delete(service_port.name))
    end

    if !user_port_mappings.empty?
        raise Syskit::InvalidPortMapping, "port mappings #{user_port_mappings} do not match either the ports of #{service_model} or the ports of #{component_model}"
    end

    # Unlike #data_service, we need to add the service's interface
    # to our own
    component_model.merge_service_model(service_model, port_mappings)
    port_mappings
end

Instance Method Details

#==(other) ⇒ Object



36
37
38
# File 'lib/syskit/models/dynamic_data_service.rb', line 36

def ==(other)
    eql?(other)
end

#addition_requires_reconfiguration?Boolean

Whether this service can be dynamically added to a configured/running task

Returns:

  • (Boolean)


16
# File 'lib/syskit/models/dynamic_data_service.rb', line 16

attr_predicate :addition_requires_reconfiguration?

#attach(component_model) ⇒ Object



40
41
42
43
44
# File 'lib/syskit/models/dynamic_data_service.rb', line 40

def attach(component_model)
    result = dup
    result.instance_variable_set(:@component_model, component_model)
    result
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
30
# File 'lib/syskit/models/dynamic_data_service.rb', line 27

def eql?(other)
    component_model == other.component_model &&
        name == other.name
end

#hashObject



32
33
34
# File 'lib/syskit/models/dynamic_data_service.rb', line 32

def hash
    [component_model, name].hash
end

#instanciate(name, **options) ⇒ BoundDynamicDataService

Instanciates a new bound dynamic service on the underlying component

Parameters:

  • the (String)

    name of the bound service

  • options

    options that should be given to #block. These options are available to the block as an 'options' local variable

Returns:



123
124
125
126
127
128
129
130
# File 'lib/syskit/models/dynamic_data_service.rb', line 123

def instanciate(name, **options)
    instantiator = component_model.create_dynamic_instantiation_context(name, self, **options)
    instantiator.instance_eval(&block)
    if !instantiator.service
        raise InvalidDynamicServiceBlock.new(self), "the block #{block} used to instantiate the dynamic service #{name} on #{component_model.short_name} with options #{options} did not provide any service"
    end
    instantiator.service
end

#remove_when_unused?Boolean

Whether this service should be removed if unused

Returns:

  • (Boolean)


18
# File 'lib/syskit/models/dynamic_data_service.rb', line 18

attr_predicate :remove_when_unused?