class Syskit::Models::CompositionSpecialization

Representation of a composition specialization

Attributes

compatibilities[R]

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.

composition_model[RW]

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

root_name[RW]

The name of the composition model that is being specialized.

It is only used for display purposes

@return [String]

specialization_blocks[R]

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

Public Instance Methods

add(new_spec, new_blocks) click to toggle source

Add new specializations and blocks to self without checking for compatibility

# 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) click to toggle source

Returns true if spec is compatible with self

See compatibilities for more information on compatible specializations

# File lib/syskit/models/composition_specialization.rb, line 128
def compatible_with?(spec)
    empty? || spec == self || spec.empty? || compatibilities.include?(spec)
end
empty?() click to toggle source

True if this does not specialize on anything

# File lib/syskit/models/composition_specialization.rb, line 114
def empty?
    specialized_children.empty?
end
find_specialization(child_name, model) click to toggle source
# 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) click to toggle source

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

# 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) click to toggle source
# 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) click to toggle source

Merge the specialization specification of other_spec into self

# 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) click to toggle source

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

@param [{String=>Array<Model<Component>,Model<DataService>>}] selection @return [Boolean]

@example

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

@see weak_match?

# 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_s() click to toggle source
# 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) click to toggle source

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

@param [{String=>Array<Model<Component>,Model<DataService>>}] selection @return [Boolean]

@example

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

@see strong_match?

# 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