Class: Syskit::Models::CompositionChild
- Inherits:
-
InstanceRequirements
- Object
- InstanceRequirements
- Syskit::Models::CompositionChild
- Defined in:
- lib/syskit/models/composition_child.rb
Overview
Used by Composition to define its children. Values returned by Syskit::Models::Composition#find_child are instances of that class.
Instance Attribute Summary collapse
-
#child_name ⇒ Object
readonly
- String
-
the name of this child on #composition_model.
-
#composition_model ⇒ Object
readonly
- Models::Composition
-
the model of the composition this child is part of.
-
#dependency_options ⇒ Object
The set of models that this child should fullfill.
-
#parent_model ⇒ CompositionChild?
The composition child model from which this model has been overloaded.
Attributes inherited from InstanceRequirements
#arguments, #base_model, #deployment_group, #deployment_hints, #dynamics, #model, #name, #required_host, #specialization_hints, #template
Instance Method Summary collapse
-
#==(other) ⇒ Object
:nodoc:.
- #attach(composition_model) ⇒ Object
-
#bind(component) ⇒ Syskit::Component, Syskit::BoundDataService
Binds this child model to the component.
- #connect_ports(other_component, connections) ⇒ Object
-
#connect_to(sink, policy = Hash.new) ⇒ Array<Port>
Automatically computes the connections between the output ports of self to the given port or component interface.
-
#connected?(source_port, sink_port) ⇒ Boolean
private
Tests whether two ports are connected.
- #eql?(other) ⇒ Boolean
- #freeze ⇒ Object
-
#initialize(composition_model, child_name, models = Set.new, dependency_options = Hash.new, parent_model = nil) ⇒ CompositionChild
constructor
A new instance of CompositionChild.
- #initialize_copy(old) ⇒ Object
- #optional ⇒ Object
-
#optional? ⇒ Boolean
If set to true, the child is going to be removed automatically if no selection exists for it.
-
#overload_info ⇒ Object
- InstanceSelection
-
information needed to update the composition's parent models about the child (mainly port mappings).
-
#port_mappings ⇒ Object
The port mappings from this child's parent model to this model.
- #pretty_print(pp) ⇒ Object
-
#resolve_and_bind_child(task) ⇒ Roby::Task
Resolves the task instance that corresponds to self, using
task
as the root composition. -
#resolve_and_bind_child_recursive(root) ⇒ Object
Resolves the task that corresponds to self starting the resolution at the given root.
-
#resolve_child(task) ⇒ Object
deprecated
Deprecated.
use #resolve_and_bind_child instead
-
#self_port?(port) ⇒ Boolean
Test whether the given port object is a port of self.
- #short_name ⇒ Object
- #state ⇒ Object
- #to_instance_requirements ⇒ Object
- #to_s ⇒ Object
-
#try_resolve_and_bind_child(composition) ⇒ nil, Object
Resolves the instance that matches self in the given composition.
-
#try_resolve_and_bind_child_recursive(root) ⇒ nil, Object
Tries to resolve the task that corresponds to self starting the resolution at the given root.
-
#try_resolve_child(task) ⇒ Object
deprecated
Deprecated.
use #try_resolve_and_bind_child instead
-
#try_resolve_child_recursive(root) ⇒ Object
deprecated
Deprecated.
use #try_resolve_and_bind_child_recursive instead
Methods inherited from InstanceRequirements
#abstract, #abstract?, #add_models, #add_port_period, #as, #as_plan, #as_real_model, #as_real_model!, #can_use_template=, #can_use_template?, #component_model, #component_model?, #composition_model?, #compute_template, #create_proxy_task, #do_copy, #each_child, #each_fullfilled_model, #each_input_port, #each_output_port, #each_port, #each_required_model, #each_required_service_model, #find_all_data_services_from_type, #find_child, #find_data_service, #find_data_service_from_type, #find_input_port, #find_output_port, #find_port, #find_port_dynamics, #find_through_method_missing, from_object, #fullfilled_model, #fullfills?, #has_child?, #has_data_service?, #has_port?, #has_template?, #has_through_method_missing?, #hash, #if_already_present, #instanciate, #instanciate_from_template, #invalidate_dependency_injection, #invalidate_template, #map_use_selections!, #merge, #narrow_model, #not_abstract, #on_server, #period, #placeholder_model, #plain?, #port_by_name, #post_instanciation_setup, #prefer_deployed_tasks, #prefer_specializations, #push_dependency_injection, #push_selections, #reset_deployment_selection, #resolve, #resolved_dependency_injection, #select_service, #selected_for, #self_port_to_component_port, #service, #simplest_model_representation, #specialize, #to_action, #to_action_model, #to_component_model, #to_coordination_task, #try_bind, #try_resolve, #unselect_service, #use, #use_conf, #use_configured_deployment, #use_deployment, #use_deployment_group, #with_arguments, #with_conf, #with_no_arguments
Constructor Details
#initialize(composition_model, child_name, models = Set.new, dependency_options = Hash.new, parent_model = nil) ⇒ CompositionChild
Returns a new instance of CompositionChild
28 29 30 31 32 33 34 |
# File 'lib/syskit/models/composition_child.rb', line 28 def initialize(composition_model, child_name, models = Set.new, = Hash.new, parent_model = nil) @composition_model, @child_name = composition_model, child_name super(models) @dependency_options = Roby::TaskStructure::Dependency.() @parent_model = parent_model end |
Instance Attribute Details
#child_name ⇒ Object (readonly)
- String
-
the name of this child on #composition_model
10 11 12 |
# File 'lib/syskit/models/composition_child.rb', line 10 def child_name @child_name end |
#composition_model ⇒ Object (readonly)
- Models::Composition
-
the model of the composition this child is
part of
8 9 10 |
# File 'lib/syskit/models/composition_child.rb', line 8 def composition_model @composition_model end |
#dependency_options ⇒ Object
The set of models that this child should fullfill. It is a Set which contains at most one Component model and any number of data service models
14 15 16 |
# File 'lib/syskit/models/composition_child.rb', line 14 def @dependency_options end |
#parent_model ⇒ CompositionChild?
Returns the composition child model from which this model has been overloaded
22 23 24 |
# File 'lib/syskit/models/composition_child.rb', line 22 def parent_model @parent_model end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
240 241 242 243 244 |
# File 'lib/syskit/models/composition_child.rb', line 240 def ==(other) # :nodoc: other.class == self.class && other.composition_model == composition_model && other.child_name == child_name end |
#attach(composition_model) ⇒ Object
272 273 274 275 276 |
# File 'lib/syskit/models/composition_child.rb', line 272 def attach(composition_model) result = dup result.instance_variable_set :@composition_model, composition_model result end |
#bind(component) ⇒ Syskit::Component, Syskit::BoundDataService
Binds this child model to the component
Within Syskit, binding a model to an instance means returning a 'view' of the instance that is described by the model. For instance, if the child is defined by a service, the returned object will be a BoundDataService instance, which then allows to for instance resolve ports “as if” they were from the service itself.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/syskit/models/composition_child.rb', line 162 def bind(component) compositions = component.each_parent_task. find_all { |t| t.fullfills?(composition_model) } parent = compositions. find { |t| component == t.find_child_from_role(child_name) } unless parent if compositions.empty? raise ArgumentError, "cannot bind #{self} to #{component}: "\ "it is not the child of any #{composition_model} composition" else raise ArgumentError, "cannot bind #{self} to #{component}: "\ "it is the child of one or more #{composition_model} compositions, "\ "but not with the role '#{child_name}'" end end resolve_and_bind_child(composition_model.bind(parent)) end |
#connect_ports(other_component, connections) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/syskit/models/composition_child.rb', line 228 def connect_ports(other_component, connections) if !other_component.respond_to?(:composition_model) raise ArgumentError, "cannot connect ports of #{self} to ports of #{other_component}: #{other_component} is not a composition child" elsif other_component.composition_model != composition_model raise ArgumentError, "cannot connect ports of #{self} to ports of #{other_component}: they are children of different composition models" end cmp_connections = composition_model.explicit_connections[[child_name, other_component.child_name]] connections.each do |port_pair, policy| cmp_connections[port_pair] = policy end end |
#connect_to(sink, policy = Hash.new) ⇒ Array<Port>
Automatically computes the connections between the output ports of self to the given port or component interface
198 199 200 |
# File 'lib/syskit/models/composition_child.rb', line 198 def connect_to(sink, policy = Hash.new) Syskit.connect(self, sink, policy) end |
#connected?(source_port, sink_port) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Tests whether two ports are connected
This is a delegated call from Port#connected_to?. Always use the former unless you know what you are doing
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/syskit/models/composition_child.rb', line 215 def connected?(source_port, sink_port) if !self_port?(source_port) raise ArgumentError, "source port #{source_port} in connected? is not a port of #{self}" elsif !composition_model.child_port?(sink_port) return false end cmp_connections = composition_model. explicit_connections[[child_name, sink_port.component_model.child_name]] cmp_connections.has_key?([source_port.name,sink_port.name]) end |
#eql?(other) ⇒ Boolean
48 49 50 51 |
# File 'lib/syskit/models/composition_child.rb', line 48 def eql?(other) other.respond_to?(:child_name) && other.child_name == child_name && super end |
#freeze ⇒ Object
42 43 44 45 46 |
# File 'lib/syskit/models/composition_child.rb', line 42 def freeze # Precompute memoized values, or we'll get a frozen error overload_info super end |
#initialize_copy(old) ⇒ Object
36 37 38 39 40 |
# File 'lib/syskit/models/composition_child.rb', line 36 def initialize_copy(old) super @dependency_options = old..dup @overload_info = nil end |
#optional ⇒ Object
187 188 189 |
# File 'lib/syskit/models/composition_child.rb', line 187 def optional @optional = true end |
#optional? ⇒ Boolean
If set to true, the child is going to be removed automatically if no selection exists for it
26 |
# File 'lib/syskit/models/composition_child.rb', line 26 attr_predicate :optional? |
#overload_info ⇒ Object
- InstanceSelection
-
information needed to update the composition's
parent models about the child (mainly port mappings)
17 18 19 |
# File 'lib/syskit/models/composition_child.rb', line 17 def overload_info @overload_info ||= InstanceSelection.new(nil, self, @parent_model || InstanceRequirements.new) end |
#port_mappings ⇒ Object
The port mappings from this child's parent model to this model
183 184 185 |
# File 'lib/syskit/models/composition_child.rb', line 183 def port_mappings overload_info.port_mappings end |
#pretty_print(pp) ⇒ Object
260 261 262 263 264 265 |
# File 'lib/syskit/models/composition_child.rb', line 260 def pretty_print(pp) pp.text "child #{child_name} of type " super pp.breakable pp.text "of #{composition_model}" end |
#resolve_and_bind_child(task) ⇒ Roby::Task
Resolves the task instance that corresponds to self, using
task
as the root composition. The returned instance is bound
to self.
140 141 142 143 144 145 146 |
# File 'lib/syskit/models/composition_child.rb', line 140 def resolve_and_bind_child(task) if resolved_task = try_resolve_and_bind_child(task) resolved_task else raise ArgumentError, "cannot find #{self} from #{task}" end end |
#resolve_and_bind_child_recursive(root) ⇒ Object
Resolves the task that corresponds to self starting the resolution at the given root
If #composition_model is not itself a CompositionChild, this is equivalent to #resolve_and_bind_child. Otherwise, it resolves the children one by one starting at the given root.
104 105 106 107 108 109 110 |
# File 'lib/syskit/models/composition_child.rb', line 104 def resolve_and_bind_child_recursive(root) if bound = try_resolve_and_bind_child_recursive(root) bound else raise ArgumentError, "cannot resolve #{self} from #{root}" end end |
#resolve_child(task) ⇒ Object
use #resolve_and_bind_child instead
68 69 70 71 72 |
# File 'lib/syskit/models/composition_child.rb', line 68 def resolve_child(task) Roby.warn_deprecated "#{__method__} is deprecated, "\ "use #resolve_and_bind_child instead" resolve_and_bind_child(task) end |
#self_port?(port) ⇒ Boolean
Test whether the given port object is a port of self
205 206 207 |
# File 'lib/syskit/models/composition_child.rb', line 205 def self_port?(port) port.component_model == self end |
#short_name ⇒ Object
268 269 270 |
# File 'lib/syskit/models/composition_child.rb', line 268 def short_name "#{composition_model.short_name}.#{child_name}_child[#{model.short_name}]" end |
#state ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/syskit/models/composition_child.rb', line 246 def state if @state return @state elsif component_model = models.find { |c| c <= Component } @state = Roby::StateFieldModel.new(component_model.state) @state.__object = self return @state else raise ArgumentError, "cannot create a state model on elements that are only data services" end end |
#to_instance_requirements ⇒ Object
278 279 280 281 282 |
# File 'lib/syskit/models/composition_child.rb', line 278 def to_instance_requirements ir = InstanceRequirements.new ir.do_copy(self) ir end |
#to_s ⇒ Object
258 |
# File 'lib/syskit/models/composition_child.rb', line 258 def to_s; "#{composition_model}.#{child_name}_child[#{super}]" end |
#try_resolve_and_bind_child(composition) ⇒ nil, Object
Resolves the instance that matches self in the given composition
The method binds the instance to self with #bind. This means that the returned value offers the interface that InstanceRequirements#model expects, and not necessarily the one of the actual instance.
For instance, if self represents a data service, it will return the corresponding BoundDataService
125 126 127 128 129 130 |
# File 'lib/syskit/models/composition_child.rb', line 125 def try_resolve_and_bind_child(composition) if bound = composition_model.try_bind(composition) bound.find_required_composition_child_from_role( child_name, composition_model) end end |
#try_resolve_and_bind_child_recursive(root) ⇒ nil, Object
Tries to resolve the task that corresponds to self starting the resolution at the given root
If #composition_model is not itself a CompositionChild, this is equivalent to #try_resolve_and_bind_child. Otherwise, it resolves the children one by one starting at the given root.
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/syskit/models/composition_child.rb', line 82 def try_resolve_and_bind_child_recursive(root) # Handle a composition child of a composition child if composition_model.respond_to?(:try_resolve_and_bind_child_recursive) resolved_parent = composition_model. try_resolve_and_bind_child_recursive(root) try_resolve_and_bind_child(resolved_parent) if resolved_parent else try_resolve_and_bind_child(root) end end |
#try_resolve_child(task) ⇒ Object
use #try_resolve_and_bind_child instead
54 55 56 57 58 |
# File 'lib/syskit/models/composition_child.rb', line 54 def try_resolve_child(task) Roby.warn_deprecated "#{__method__} is deprecated, use "\ "CompositionChild#try_resolve_and_bind_child instead" try_resolve_and_bind_child(task) end |
#try_resolve_child_recursive(root) ⇒ Object
use #try_resolve_and_bind_child_recursive instead
61 62 63 64 65 |
# File 'lib/syskit/models/composition_child.rb', line 61 def try_resolve_child_recursive(root) Roby.warn_deprecated "#{__method__} is deprecated, use "\ "CompositionChild#try_resolve_and_bind_child_recursive instead" try_resolve_and_bind_child_recursive(root) end |