Class: Syskit::Models::Port

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

Overview

Representation of a component port on a component instance.

The sibling class Syskit::Port represents a port on a component instance. For instance, an object of class Syskit::Models::Port could be used to represent a port on a subclass of TaskContext while Syskit::Port would represent it for an object of that subclass.

Direct Known Subclasses

InputPort, OutputPort

Constant Summary collapse

OROGEN_MODEL_EXCLUDED_FORWARDINGS =
[:task]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component_model, orogen_model, name = orogen_model.name) ⇒ Port

Returns a new instance of Port

Parameters:

  • component_model (#instanciate)

    the component model

  • orogen_model (Orocos::Spec::Port)

    the oroGen port model

  • name (String) (defaults to: orogen_model.name)

    the port name if it is different than the name in 'orogen_model'



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

def initialize(component_model, orogen_model, name = orogen_model.name)
    @component_model, @name, @orogen_model =
        component_model, name, orogen_model

    if orogen_model.type.contains_opaques?
        @type = Orocos.default_loader.intermediate_type_for(orogen_model.type)
    else
        @type = orogen_model.type
    end
    @max_sizes = orogen_model.max_sizes.
        merge(Orocos.max_sizes_for(type))
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object



155
156
157
158
159
160
# File 'lib/syskit/models/port.rb', line 155

def method_missing(m, *args, &block)
    if !OROGEN_MODEL_EXCLUDED_FORWARDINGS.include?(m) && orogen_model.respond_to?(m)
        orogen_model.public_send(m, *args, &block)
    else super
    end
end

Instance Attribute Details

#component_modelComponentModel (readonly)

Returns The component model this port is part of

Returns:

  • (ComponentModel)

    The component model this port is part of



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

def component_model
  @component_model
end

#max_sizesObject (readonly)

Returns the value of attribute max_sizes



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

def max_sizes
  @max_sizes
end

#nameString

Returns The port name on component_model. It can be different from orogen_model.name, as the port could be imported from another component

Returns:

  • (String)

    The port name on component_model. It can be different from orogen_model.name, as the port could be imported from another component



17
18
19
# File 'lib/syskit/models/port.rb', line 17

def name
  @name
end

#orogen_modelOrocos::Spec::Port (readonly)

Returns The port model

Returns:

  • (Orocos::Spec::Port)

    The port model



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

def orogen_model
  @orogen_model
end

#typeModel<Typelib::Type> (readonly)

Returns the typelib type of this port

Returns:

  • (Model<Typelib::Type>)

    the typelib type of this port



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

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object

Whether this port and the argument are the same port



51
52
53
54
55
# File 'lib/syskit/models/port.rb', line 51

def ==(other)
    other.kind_of?(self.class) && other.component_model == component_model &&
    other.orogen_model == orogen_model &&
    other.name == name
end

#attach(model) ⇒ Port

Return a new port attached to another component model

Returns:



60
61
62
63
64
# File 'lib/syskit/models/port.rb', line 60

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

#can_connect_to?(sink_port) ⇒ Boolean

Tests whether this port can be connceted to the provided input port

Returns:

  • (Boolean)


137
138
139
140
141
142
143
144
145
# File 'lib/syskit/models/port.rb', line 137

def can_connect_to?(sink_port)
    source_port = self.try_to_component_port
    if source_port == self
        sink_port  = sink_port.try_to_component_port
        output? && sink_port.input? && type == sink_port.type
    else
        source_port.can_connect_to?(sink_port)
    end
end

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

Connects this port to the other given port, using the given policy



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/syskit/models/port.rb', line 99

def connect_to(in_port, policy = Hash.new)
    out_port = self.to_component_port
    if out_port == self
        if in_port.respond_to?(:to_component_port)
            in_port = in_port.to_component_port
            if !out_port.output?
                raise WrongPortConnectionDirection.new(self, in_port), "cannot connect #{out_port} to #{in_port}: #{out_port} is not an output port"
            elsif !in_port.input?
                raise WrongPortConnectionDirection.new(self, in_port), "cannot connect #{out_port} to #{in_port}: #{in_port} is not an input port"
            elsif out_port.component_model == in_port.component_model
                raise SelfConnection.new(out_port, in_port), "cannot connect #{out_port} to #{in_port}: they are both ports of the same component"
            elsif out_port.type != in_port.type
                raise WrongPortConnectionTypes.new(self, in_port), "cannot connect #{out_port} to #{in_port}: types mismatch"
            end

            component_model.connect_ports(in_port.component_model, [out_port.name, in_port.name] => policy)
        else
            Syskit.connect self, in_port, policy
        end

    else
        out_port.connect_to(in_port, policy)
    end
end

#connected_to?(sink_port) ⇒ Boolean

Tests whether self is connected to the provided port

Returns:

  • (Boolean)


125
126
127
128
129
130
131
132
133
# File 'lib/syskit/models/port.rb', line 125

def connected_to?(sink_port)
    source_port = self.try_to_component_port
    if source_port == self
        sink_port = sink_port.try_to_component_port
        component_model.connected?(source_port, sink_port)
    else
        source_port.connected_to?(sink_port)
    end
end

#input?Boolean

Returns true if this is an input port, false otherwise. The default implementation returns false

Returns:

  • (Boolean)

    true if this is an input port, false otherwise. The default implementation returns false



212
# File 'lib/syskit/models/port.rb', line 212

def input?; false end

#instanciate(plan) ⇒ Object



196
197
198
# File 'lib/syskit/models/port.rb', line 196

def instanciate(plan)
    bind(component_model.instanciate(plan))
end

#max_marshalling_sizeObject



38
39
40
# File 'lib/syskit/models/port.rb', line 38

def max_marshalling_size
    OroGen::Spec::OutputPort.compute_max_marshalling_size(type, max_sizes)
end

#new_sampleObject



192
193
194
# File 'lib/syskit/models/port.rb', line 192

def new_sample
    orogen_model.type.new
end

#output?Boolean

Returns true if this is an output port, false otherwise. The default implementation returns false

Returns:

  • (Boolean)

    true if this is an output port, false otherwise. The default implementation returns false



209
# File 'lib/syskit/models/port.rb', line 209

def output?; false end

#pretty_print(pp) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/syskit/models/port.rb', line 170

def pretty_print(pp)
    pp.text "port '#{name}' of "
    pp.nest(2) do
        pp.breakable
        component_model.pretty_print(pp)
        pp.breakable
        pp.text "Defined with"
        pp.nest(2) do
            pp.breakable
            orogen_model.pretty_print(pp)
        end
    end
end

#resolve_data_source(context) ⇒ Object



200
201
202
203
204
205
# File 'lib/syskit/models/port.rb', line 200

def resolve_data_source(context)
    if context.kind_of?(Roby::Plan)
        context.add(context = component_model.as_plan)
    end
    bind(context).to_data_source
end

#respond_to_missing?(m, include_private) ⇒ Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
# File 'lib/syskit/models/port.rb', line 147

def respond_to_missing?(m, include_private)
    if !OROGEN_MODEL_EXCLUDED_FORWARDINGS.include?(m) && orogen_model.respond_to?(m)
        true
    else super
    end
end

#same_port?(other) ⇒ Boolean

Whether this port and the argument represent the same port

Returns:

  • (Boolean)


45
46
47
48
# File 'lib/syskit/models/port.rb', line 45

def same_port?(other)
    other.kind_of?(Port) && (other.component_model <=> component_model) &&
        other.orogen_model == orogen_model
end

#short_nameObject



162
163
164
# File 'lib/syskit/models/port.rb', line 162

def short_name
    "#{component_model.short_name}.#{name}_port[#{type.name}]"
end

#static?Boolean

Returns:

  • (Boolean)


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

def static?
    orogen_model.static?
end

#to_component_portPort

Returns the Port object corresponding to self, in which #component_model is a “proper” component model (i.e. a subclass of Component and not a data service)

Returns:

Raises:

  • (ArgumentError)

    if self cannot be resolved into a component port



87
88
89
90
91
92
# File 'lib/syskit/models/port.rb', line 87

def to_component_port
    if component_model.respond_to?(:self_port_to_component_port)
        component_model.self_port_to_component_port(self)
    else raise ArgumentError, "cannot resolve a port of #{component_model.short_name} into a component port"
    end
end

#to_orocos_port(component) ⇒ Object



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

def to_orocos_port(component)
    component_model.bind(component).find_port(name)
end

#to_sObject



166
167
168
# File 'lib/syskit/models/port.rb', line 166

def to_s
    "#{component_model.short_name}.#{name}_port[#{type.name}]"
end

#try_to_component_portPort

Try to resolve, if possible, the Port object corresponding to self, in which #component_model is a “proper” component model (i.e. a subclass of Component and not a data service)

If it is not possible, returns self

Returns:



73
74
75
76
77
78
# File 'lib/syskit/models/port.rb', line 73

def try_to_component_port
    if component_model.respond_to?(:self_port_to_component_port)
        component_model.self_port_to_component_port(self)
    else self
    end
end