Class: Syskit::InstanceSelection

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

Overview

A representation of a selection matching a given requirement

Direct Known Subclasses

Models::FacetedAccess

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component = nil, selected = InstanceRequirements.new([Component]), required = InstanceRequirements.new, mappings = Hash.new) ⇒ InstanceSelection

Returns a new instance of InstanceSelection



20
21
22
23
24
25
26
27
# File 'lib/syskit/instance_selection.rb', line 20

def initialize(component = nil, selected = InstanceRequirements.new([Component]), required = InstanceRequirements.new, mappings = Hash.new)
    @component = component

    selected = @selected = autoselect_service_if_needed(selected, required, mappings)
    required = @required = required.dup
    @service_selection =
        InstanceSelection.compute_service_selection(selected, required, mappings)
end

Instance Attribute Details

#componentSyskit::Component (readonly)

The selected task, if one is specified explicitly

Returns:



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

def component
  @component
end

#requiredObject (readonly)

InstanceRequirements

the required instance



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

def required
  @required
end

#selectedObject (readonly)

InstanceRequirements

the selected instance. It can only refer to

a single component model. This model is available with #component_model

See Also:



15
16
17
# File 'lib/syskit/instance_selection.rb', line 15

def selected
  @selected
end

#service_selectionObject (readonly)

=> Models::BoundDataService

a mapping from

the services in #required to the services of #component_model.



18
19
20
# File 'lib/syskit/instance_selection.rb', line 18

def service_selection
  @service_selection
end

Class Method Details

.compute_service_selection(selected, required, mappings) ⇒ {Model<DataService>=>Models::BoundDataService}

Computes the service selection that will allow to replace a placeholder representing the required models by the given component model. The additional mappings are only used as hints.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    if a service in mappings is either not a service of component_model, or does not fullfill the data service it is selected for

  • AmbiguousServiceSelection if multiple services exist with that type



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/syskit/instance_selection.rb', line 99

def self.compute_service_selection(selected, required, mappings)
    mappings = mappings.dup
    if selected.service
        # Save this selection explicitly
        mappings[selected.service.model] = selected.service
    end

    selected_component_model = selected.model.to_component_model
    required_component_model, required_service_models =
        required.component_model || Syskit::Component,
        required.each_required_service_model.to_a

    mappings[required_component_model] =
        selected_component_model

    required_service_models.each do |required_m|
        if selected_m = mappings[required_m]
            # Verify that it is of the right type
            if !selected_component_model.fullfills?(selected_m.component_model)
                raise ArgumentError, "#{selected_m} was explicitly selected for #{required_m}, but is not a service of the selected component model #{selected_component_model}"
            elsif !selected_m.fullfills?(required_m)
                raise ArgumentError, "#{selected_m} was explicitly selected for #{required_m}, but does not provide it"
            end
            mappings[required_m] = selected_m.attach(selected_component_model)
        else
            selected_m = selected_component_model.find_data_service_from_type(required_m)
            if !selected_m
                raise ArgumentError, "selected model #{selected} does not provide required service #{required_m.short_name}"
            end
        end

        mappings[required_m] = selected_m
    end
    mappings
end

Instance Method Details

#autoselect_service_if_needed(selected, required, mappings) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/syskit/instance_selection.rb', line 46

def autoselect_service_if_needed(selected, required, mappings)
    return selected.dup if selected.service

    if required_srv = required.service
        if srv = selected.find_data_service(required_srv.name)
            srv
        elsif m = mappings[required.service.model]
            selected = selected.dup
            selected.select_service(m)
        else
            selected.find_data_service_from_type(required_srv.model)
        end

    elsif !required.component_model
        required_services = required.each_required_service_model.to_a
        if required_services.size == 1
            required_srv = required_services.first
            if m = mappings[required_srv]
                selected = selected.dup
                selected.select_service(m)
            else
                selected.find_data_service_from_type(required_srv)
            end
        else selected.dup
        end

    else selected.dup
    end
end

#bind(task) ⇒ Object



176
177
178
# File 'lib/syskit/instance_selection.rb', line 176

def bind(task)
    selected.bind(task)
end

#component_modelObject

Returns the selected component model



77
78
79
# File 'lib/syskit/instance_selection.rb', line 77

def component_model
    selected.base_model
end

#each_fullfilled_model(&block) ⇒ Object



180
181
182
# File 'lib/syskit/instance_selection.rb', line 180

def each_fullfilled_model(&block)
    required.each_fullfilled_model(&block)
end

#fullfills?(set) ⇒ Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/syskit/instance_selection.rb', line 184

def fullfills?(set)
    selected.fullfills?(set)
end

#initialize_copy(old) ⇒ Object



29
30
31
32
33
34
# File 'lib/syskit/instance_selection.rb', line 29

def initialize_copy(old)
    @component = old.component
    @selected = old.selected.dup
    @required = old.required.dup
    @service_selection = service_selection.dup
end

#instanciate(plan, context = Syskit::DependencyInjectionContext.new, options = Hash.new) ⇒ Object

If this selection does not yet have an associated task, instanciate one



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/syskit/instance_selection.rb', line 162

def instanciate(plan, context = Syskit::DependencyInjectionContext.new, options = Hash.new)
    if component
        # We have an explicitly selected component. We just need to
        # bind the bound data service if there is one
        component = plan[self.component]
        if selected_service = selected.service
            selected_service.bind(component)
        else component
        end
    else
        selected.instanciate(plan, context, options)
    end
end

#port_mappingsObject

Compute the combined port mappings given the service selection in #service_selection.

Raises:



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/syskit/instance_selection.rb', line 140

def port_mappings
    if @port_mappings then return @port_mappings end

    mappings = Hash.new
    service_selection.each do |req_m, sel_m|
        mappings.merge!(sel_m.port_mappings_for(req_m)) do |req_name, sel_name1, sel_name2|
            if sel_name1 != sel_name2
                # need to find who has the same port ...
                service_selection.each_key do |other_m|
                    if req_m.has_port?(req_name)
                        raise AmbiguousPortMappings.new(other_m, req_m, req_name)
                    end
                end
            else sel_name1
            end
        end
    end
    @port_mappings = mappings
end

#pretty_print(pp) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/syskit/instance_selection.rb', line 192

def pretty_print(pp)
    pp.text "Instance selection for "
    pp.nest(2) do
        pp.breakable
        pp.text "Component"
        if component
            pp.nest(2) do
                pp.breakable
                component.pretty_print(pp)
            end
        end
        pp.breakable
        pp.text "Required"
        pp.nest(2) do
            pp.breakable
            required.pretty_print(pp)
        end
        pp.breakable
        pp.text "Selected"
        pp.nest(2) do
            pp.breakable
            selected.pretty_print(pp)
        end
        pp.breakable
        pp.text "Services"
        if !service_selection.empty?
            pp.nest(2) do
                pp.breakable
                pp.seplist(service_selection) do |sel|
                    pp.text "#{sel[0].short_name} => #{sel[1].short_name}"
                end
            end
        end
    end
end

#selected_modelBoundDataService, ...

Returns the simplest model representation for #selected

It mostly either returns #selected or #selected.model if Syskit::InstanceRequirements#plain? returns resp. false or true



42
43
44
# File 'lib/syskit/instance_selection.rb', line 42

def selected_model
    selected.simplest_model_representation
end

#to_sObject



188
189
190
# File 'lib/syskit/instance_selection.rb', line 188

def to_s
    "#<#{self.class}: #{required} selected=#{selected} service_selection=#{service_selection}>"
end