Class: Syskit::Models::CompositionSpecialization

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

Overview

Representation of a composition specialization

Defined Under Namespace

Modules: Extension

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spec = Hash.new, block = nil) ⇒ CompositionSpecialization

Returns a new instance of CompositionSpecialization



98
99
100
101
102
103
104
105
# File 'lib/syskit/models/composition_specialization.rb', line 98

def initialize(spec = Hash.new, block = nil)
    @specialized_children = spec
    @specialization_blocks = Array.new
    if block
        @specialization_blocks << block
    end
    @compatibilities = Set.new
end

Instance Attribute Details

#compatibilitiesObject (readonly)

Cache of compatibilities: this is a cache of other Specialization objects that can be applied at the same time that this one.

Two compositions are compatible if their specialization sets are either disjoints (they don't specialize on the same children) or if it is possible that a component provides both the required models.



84
85
86
# File 'lib/syskit/models/composition_specialization.rb', line 84

def compatibilities
  @compatibilities
end

#composition_modelObject

The composition model that can be used to instanciate this specialization. This is a subclass of the composition that this specialization specializes.



96
97
98
# File 'lib/syskit/models/composition_specialization.rb', line 96

def composition_model
  @composition_model
end

#root_nameString

The name of the composition model that is being specialized.

It is only used for display purposes

Returns:

  • (String)


91
92
93
# File 'lib/syskit/models/composition_specialization.rb', line 91

def root_name
  @root_name
end

#specialization_blocksObject (readonly)

The set of blocks that have been passed to the corresponding specialize calls. These blocks are going to be evaluated in the task model that will be created (on demand) to create tasks of this specialization



74
75
76
# File 'lib/syskit/models/composition_specialization.rb', line 74

def specialization_blocks
  @specialization_blocks
end

#specialized_children{String=>[Model<Component>,Model<DataService>]} (readonly)

The specialization constraints, as a map from child name to set of models (data services or components)

Returns:



68
69
70
# File 'lib/syskit/models/composition_specialization.rb', line 68

def specialized_children
  @specialized_children
end

Class Method Details

.merge(*specs) ⇒ CompositionSpecialization

Create a new composition specialization object which is the merge of all the given specs



167
168
169
170
171
172
173
# File 'lib/syskit/models/composition_specialization.rb', line 167

def self.merge(*specs)
    composite_spec = CompositionSpecialization.new
    specs.each do |spec|
        composite_spec.merge(spec)
    end
    composite_spec
end

Instance Method Details

#add(new_spec, new_blocks) ⇒ Object

Add new specializations and blocks to self without checking for compatibility



152
153
154
155
156
157
158
159
160
161
# File 'lib/syskit/models/composition_specialization.rb', line 152

def add(new_spec, new_blocks)
    specialized_children.merge!(new_spec) do |child_name, models_a, models_b|
        Models.merge_model_lists(models_a, models_b)
    end
    if new_blocks.respond_to?(:to_ary)
        specialization_blocks.concat(new_blocks)
    elsif new_blocks
        specialization_blocks << new_blocks
    end
end

#compatible_with?(spec) ⇒ Boolean

Returns true if spec is compatible with self

See #compatibilities for more information on compatible specializations

Returns:

  • (Boolean)


128
129
130
# File 'lib/syskit/models/composition_specialization.rb', line 128

def compatible_with?(spec)
    empty? || spec == self || spec.empty? || compatibilities.include?(spec)
end

#empty?Boolean

True if this does not specialize on anything

Returns:

  • (Boolean)


114
115
116
# File 'lib/syskit/models/composition_specialization.rb', line 114

def empty?
    specialized_children.empty?
end

#find_specialization(child_name, model) ⇒ Object



132
133
134
135
136
137
138
139
140
# File 'lib/syskit/models/composition_specialization.rb', line 132

def find_specialization(child_name, model)
    if selected_models = specialized_children[child_name]
        if matches = selected_models.find_all { |m| m.fullfills?(model) }
            if !matches.empty?
                return matches
            end
        end
    end
end

#has_specialization?(child_name, model) ⇒ Boolean

Returns true if self specializes on child_name in a way that is compatible with model

Returns:

  • (Boolean)


144
145
146
147
148
# File 'lib/syskit/models/composition_specialization.rb', line 144

def has_specialization?(child_name, model)
    if selected_models = specialized_children[child_name]
        selected_models.any? { |m| m.fullfills?(model) }
    end
end

#initialize_copy(old) ⇒ Object



107
108
109
110
111
# File 'lib/syskit/models/composition_specialization.rb', line 107

def initialize_copy(old)
    @specialized_children = old.specialized_children.dup
    @specialization_blocks = old.specialization_blocks.dup
    @compatibilities = old.compatibilities.dup
end

#merge(other_spec) ⇒ Object

Merge the specialization specification of other_spec into self



177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/syskit/models/composition_specialization.rb', line 177

def merge(other_spec)
    @compatibilities =
        if empty?
            other_spec.compatibilities.dup
        else
            compatibilities & other_spec.compatibilities.dup
        end
    @compatibilities << other_spec

    add(other_spec.specialized_children, other_spec.specialization_blocks)
    self
end

#strong_match?(selection) ⇒ Boolean

Tests if this specialization could be used for the given selection. All the children in the selection must have a corresponding entry in the specialization for this to return true

Examples:

spec = CompositionSpecialization.new 'srv' => component, 'child' => composition
spec.strong_match?('srv' => component) => false
spec.strong_match?('srv' => component, 'child' => composition) => true
# assuming that 'component' does not provide 'data_service'
spec.strong_match?('srv' => data_service, 'child' => composition) => false

Parameters:

Returns:

  • (Boolean)

See Also:



231
232
233
234
235
236
237
# File 'lib/syskit/models/composition_specialization.rb', line 231

def strong_match?(selection)
    specialized_children.all? do |child_name, child_models|
        if this_selection = selection[child_name]
            this_selection.fullfills?(child_models)
        end
    end
end

#to_sObject



118
119
120
121
122
# File 'lib/syskit/models/composition_specialization.rb', line 118

def to_s
    root_name.to_s + "/" + specialized_children.map do |child_name, child_models|
        "#{child_name}.is_a?(#{child_models.map(&:short_name).join(",")})"
    end.join(",")
end

#weak_match?(selection) ⇒ Boolean

Tests if this specialization could be used for the given selection, ignoring selections that do not have a corresponding entry in the specialization

Examples:

spec = CompositionSpecialization.new 'srv' => component, 'child' => composition
spec.weak_match?('srv' => component) => true
# assuming that 'component' does not provide 'data_service'
spec.weak_match?('srv' => data_service) => false

Parameters:

Returns:

  • (Boolean)

See Also:



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/syskit/models/composition_specialization.rb', line 204

def weak_match?(selection)
    has_match = false
    result = specialized_children.all? do |child_name, child_models|
        if this_selection = selection[child_name]
            has_match = true
            this_selection.fullfills?(child_models)
        else true
        end
    end
    has_match && result
end