Class: Syskit::Models::FacetedAccess

Inherits:
InstanceSelection show all
Includes:
MetaRuby::DSLs::FindThroughMethodMissing
Defined in:
lib/syskit/models/faceted_access.rb

Overview

Proxy class that gives access to a component under the cover of a certain number of models (e.g. services, …) to make it “look like” one of these components

It can be used on component instances and component models

One rarely creates an instance of this object directly, but uses the #as() acessor on component models

Instance Attribute Summary collapse

Attributes inherited from InstanceSelection

#component, #required, #selected, #service_selection

Instance Method Summary collapse

Methods inherited from InstanceSelection

#autoselect_service_if_needed, #bind, #component_model, compute_service_selection, #each_fullfilled_model, #fullfills?, #initialize_copy, #instanciate, #pretty_print, #selected_model

Constructor Details

#initialize(object, required, mappings = Hash.new) ⇒ FacetedAccess

Returns a new instance of FacetedAccess



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

def initialize(object, required, mappings = Hash.new)
    super(nil, object.to_instance_requirements, required.to_instance_requirements, mappings)
    @object = object
    @ports_on_required = Hash.new
    @port_mappings = Hash.new
end

Instance Attribute Details

#objectObject (readonly)

The object to which we are giving a faceted access



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

def object
  @object
end

#port_mappings{String=>Port} (readonly)

Returns mapping of ports in InstanceSelection#required to ports in #object

Returns:



19
20
21
# File 'lib/syskit/models/faceted_access.rb', line 19

def port_mappings
  @port_mappings
end

#ports_on_required{String=>[Port]} (readonly)

Returns the ports on InstanceSelection#required that provide the named port

Returns:



16
17
18
# File 'lib/syskit/models/faceted_access.rb', line 16

def ports_on_required
  @ports_on_required
end

Instance Method Details

#connect_to(sink, policy = Hash.new) ⇒ Object



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

def connect_to(sink, policy = Hash.new)
    Syskit.connect(self, sink, policy)
end

#each_input_portObject



108
109
110
111
112
113
# File 'lib/syskit/models/faceted_access.rb', line 108

def each_input_port
    return enum_for(:each_input_port) if !block_given?
    each_port_helper :each_input_port do |p|
        yield(p)
    end
end

#each_output_portObject



115
116
117
118
119
120
# File 'lib/syskit/models/faceted_access.rb', line 115

def each_output_port
    return enum_for(:each_output_port) if !block_given?
    each_port_helper :each_output_port do |p|
        yield(p)
    end
end

#each_portObject



122
123
124
125
126
# File 'lib/syskit/models/faceted_access.rb', line 122

def each_port
    return enum_for(:each_port) if block_given?
    each_input_port(&proc)
    each_output_port(&proc)
end

#each_port_helper(each_method) ⇒ Object



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

def each_port_helper(each_method)
    required.each_required_model do |m|
        m.send(each_method) do |p|
            port_mappings[p.name] ||= find_all_port_mappings_for(p.name)
            if port_mappings[p.name].size == 1
                yield(p.attach(self))
            end
        end
    end
end

#find_all_port_mappings_for(name) ⇒ Set<Port>

Find all possible port mappings for the given port name to #object

Parameters:

Returns:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/syskit/models/faceted_access.rb', line 58

def find_all_port_mappings_for(name)
    candidates = Set.new
    ports_on_required[name] ||= find_ports_on_required(name)
    ports_on_required[name].each do |p|
        srv = service_selection[p.component_model]
        actual_port_name = srv.port_mappings_for_task[p.name]
        if p = object.find_port(actual_port_name)
            candidates << p
        else
            raise InternalError, "failed to map port from the required facet #{required} to #{object}"
        end
    end
    candidates
end

#find_data_service(name) ⇒ Object



38
39
40
41
42
# File 'lib/syskit/models/faceted_access.rb', line 38

def find_data_service(name)
    # The name of data services cannot change between the facet and the
    # real object, just return the one from the real object
    object.find_data_service(name)
end

#find_data_service_from_type(type) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/syskit/models/faceted_access.rb', line 44

def find_data_service_from_type(type)
    srv = required.find_data_service_from_type(type)
    if !required.each_required_model.to_a.include?(srv.model)
        return find_data_service(srv.name)
    else
        return srv
    end
end

#find_port(name) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/syskit/models/faceted_access.rb', line 77

def find_port(name)
    if !port_mappings[name]
        port_mappings[name] = find_all_port_mappings_for(name)
    end
    candidates = port_mappings[name]
    if candidates.size > 1
        raise AmbiguousPortOnCompositeModel.new(self, required.each_required_model.to_a, name, candidates),
            "#{name} is an ambiguous port on #{self}: it can be mapped to #{candidates.map(&:to_s).join(", ")}"
    end

    ports = ports_on_required[name]
    if !ports.empty?
        ports.first.attach(self)
    end
end

#find_ports_on_required(name) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/syskit/models/faceted_access.rb', line 28

def find_ports_on_required(name)
    result = []
    required.each_required_model do |m|
        if p = m.find_port(name)
            result << p
        end
    end
    result
end

#find_through_method_missing(m, args) ⇒ Object



141
142
143
144
# File 'lib/syskit/models/faceted_access.rb', line 141

def find_through_method_missing(m, args)
    MetaRuby::DSLs.find_through_method_missing(
        self, m, args, "_port".freeze => :find_port) || super
end

#has_port?(name) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/syskit/models/faceted_access.rb', line 73

def has_port?(name)
    !(port_mappings[name] ||= find_all_port_mappings_for(name)).empty?
end

#has_through_method_missing?(m) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/syskit/models/faceted_access.rb', line 136

def has_through_method_missing?(m)
    MetaRuby::DSLs.has_through_method_missing?(
        self, m, "_port".freeze => :has_port?) || super
end

#self_port_to_component_port(port) ⇒ Object



93
94
95
# File 'lib/syskit/models/faceted_access.rb', line 93

def self_port_to_component_port(port)
    port_mappings[port.name].first.to_component_port
end

#to_sObject



132
133
134
# File 'lib/syskit/models/faceted_access.rb', line 132

def to_s
    "#{object.to_s}.as(#{required.each_required_model.map(&:to_s).sort.join(",")})"
end