Class: Syskit::Component
- Extended by:
- Logger::Hierarchy, Models::Component
- Includes:
- Logger::Hierarchy, PortAccess
- Defined in:
- lib/syskit/component.rb
Overview
Base class for models that represent components (TaskContext, Composition)
The model-level methods (a.k.a. singleton methods) are defined on Models::Component). See the documentation of Model for an explanation of this.
Components may be data service providers. Two types of data sources exist:
-
main services are root data services that can be provided independently
-
slave sources are data services that depend on another service. For instance, an ImageProvider source of a StereoCamera task could be slave of the main PointCloudProvider source.
Data services are referred to by name. In the case of a main service, its name is the name used during the declaration. In the case of slave services, it is main_data_service_name.slave_name. I.e. the name of the slave service depends on the selected
Direct Known Subclasses
Defined Under Namespace
Modules: Proxying
Constant Summary
Constants included from Models::Component
Models::Component::PROVIDES_ARGUMENTS
Instance Attribute Summary collapse
-
#dynamics ⇒ NetworkGeneration::PortDynamics
The PortDynamics object that holds the dynamics information computed for this task (not its ports).
-
#required_host ⇒ Object
The name of the process server that should run this component.
-
#requirements ⇒ Object
readonly
The InstanceRequirements object for which this component has been instanciated.
Instance Method Summary collapse
-
#added_dynamic_service(srv) ⇒ void
Hook called on an already-configured task when a new service got added.
-
#added_input_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection has been created to an input port.
-
#added_output_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection has been created to an output port.
-
#adding_input_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection will be created on an input port.
-
#adding_output_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection will be created on an output port.
-
#as(service_model) ⇒ Object
Returns a view of this component as a provider of the given service model.
- #bind(task) ⇒ Object
-
#can_be_deployed_by?(task) ⇒ Boolean
Tests whether a task can be used as-is to deploy this.
-
#can_finalize? ⇒ Boolean
Controls whether the task can be removed from the plan.
-
#can_merge?(task) ⇒ Boolean
Test if the given task could be merged in self.
-
#concrete_model ⇒ Object
Returns the most-derived model that is not a private specialization.
-
#configure ⇒ Object
User-provided part of the component configuration.
-
#connect_to(port_or_component, policy = Hash.new) ⇒ Object
Automatically computes connections from the output ports of self to the given port or to the input ports of the given component.
- #create_fresh_copy ⇒ Object
-
#data_accessor(*args) ⇒ Object
Common implementation of port search for #data_reader and #data_writer.
-
#data_reader(*args) ⇒ Object
call-seq: data_reader 'port_name'[, policy] data_reader 'role_name', 'port_name'[, policy].
-
#data_writer(*args) ⇒ Object
call-seq: data_writer 'port_name'[, policy] data_writer 'role_name', 'port_name'[, policy].
-
#dependency_context ⇒ Object
Returns a description of this task based on the dependency information.
-
#deployment_hints ⇒ Object
Returns a set of hints that should be used to disambiguate the deployment of this task.
- #duplicate_missing_services_from(task) ⇒ Object
-
#each_data_service ⇒ Object
Yields the data services that are defined on this task.
-
#each_dynamic_service(&block) ⇒ Object
deprecated
Deprecated.
has been renamed to #each_required_dynamic_service for consistency with the model-level method
-
#each_fullfilled_model(&block) ⇒ Object
Returns the set of models this task fullfills.
-
#each_required_dynamic_service {|srv| ... } ⇒ void
Yields the data services that have been created through the dynamic data service mechanism.
-
#find_data_service(service_name) ⇒ BoundDataService?
Finds a data service by its name.
-
#find_data_service_from_type(service_type) ⇒ BoundDataService?
Finds a data service by its data service model.
- #find_through_method_missing(m, args) ⇒ Object
- #has_data_service?(service_name) ⇒ Boolean
- #has_through_method_missing?(m) ⇒ Boolean
-
#initialize(**arguments) ⇒ Component
constructor
A new instance of Component.
- #initialize_copy(source) ⇒ Object
- #meets_configurationg_precedence_constraints? ⇒ Boolean
-
#merge(merged_task) ⇒ Object
Updates self so that it is a valid replacement for merged_task.
-
#perform_setup(promise) ⇒ Object
private
The actual setup operations.
-
#placeholder? ⇒ Boolean
Whether this component instance is a placeholder for an abstract combination of a component model and data services.
-
#ready_for_setup? ⇒ Boolean
Returns true if the underlying Orocos task is in a state that allows it to be configured.
-
#removed_input_port_connection(source_task, source_port, sink_port) ⇒ Object
Hook called when a connection has been removed from an input port.
-
#removed_output_port_connection(source_port, sink_task, sink_port) ⇒ Object
Hook called when a connection has been removed from an output port.
-
#removing_input_port_connection(source_task, source_port, sink_port) ⇒ Object
Hook called when a connection will be removed from an input port.
-
#removing_output_port_connection(source_port, sink_task, sink_port) ⇒ Object
Hook called when a connection will be removed from an output port.
-
#require_dynamic_service(dynamic_service_name, as: nil, **dyn_options) ⇒ BoundDataService
Requires a new dynamic service on this task context.
-
#self_port_to_actual_port(port) ⇒ Syskit::Port
It should not be used directly.
-
#self_port_to_component_port(port) ⇒ Syskit::Port
Resolves the given Syskit::Port object into a Port object where #component is guaranteed to be a proper component instance.
-
#setting_up!(promise) ⇒ Object
private
Called once at the beginning of a setup promise.
-
#setting_up? ⇒ Boolean
Whether the task is being set up.
-
#setup ⇒ Promise
Create a Roby::Promise object that configures the component.
-
#setup=(value) ⇒ Object
Returns true if the underlying Orocos task has been properly configured.
-
#setup? ⇒ Boolean
Returns true if the underlying Orocos task has been properly configured.
-
#setup_failed!(exception) ⇒ Object
private
Called when the setup process failed.
-
#setup_successful! ⇒ Object
private
Called once the setup process is finished to mark the task as set up.
-
#should_configure_after(object) ⇒ Object
Declare that this component should not be configured until
event
has been emitted. -
#specialize ⇒ Object
Sets up this task to use its singleton class as model instead of the plain class.
- #specialized_model? ⇒ Boolean
-
#start_only_when_connected? ⇒ Boolean
Whether this task should be started only after all its inputs have been connected.
-
#to_instance_requirements ⇒ Syskit::InstanceRequirements
Generates the InstanceRequirements object that represents
self
best. - #update_requirements(new_requirements, name: nil, keep_abstract: false) ⇒ Object
-
#will_never_setup? ⇒ Boolean
Whether this task context will ever configurable.
Methods included from Models::Component
all_data_service, all_dynamic_service, all_stub_module, apply_missing_dynamic_services_from, as_plan, clear_model, component_model?, compute_port_mappings, concrete_model?, connected?, create_dynamic_instantiation_context, create_private_specialization, create_proxy_task, create_proxy_task_model, data_service, data_services, deregister_placeholder_model, deregister_submodels, driver_for, dynamic_service, dynamic_services, each_com_bus_driver_service, each_input_port, each_master_driver_service, each_output_port, each_port, each_required_model, each_root_data_service, each_slave_data_service, each_stub_module, ensure_model_is_specialized, find_all_data_services_from_type, find_directional_port_mapping, find_input_port, find_matching_service, find_output_port, find_placeholder_model, find_port, fullfills?, if_already_present, implicit_fullfilled_model, instanciate, instanciate_dynamic_input_port, instanciate_dynamic_output_port, merge_service_model, method_missing, needs_stub?, port_mappings_for, port_mappings_for_task, prefer_deployed_tasks, prepare_stub, private_specialization=, private_specialization?, promote_data_service, promote_dynamic_service, provides, provides_dynamic, proxy_task_model, register_placeholder_model, resolve, selected_for, self_port?, specialization_counter, stub, stub_module, supermodel, to_component_model, try_bind, try_resolve, use_conf, use_deployments, with_arguments, with_conf, with_dynamic_service
Methods included from DataService
Methods included from Models::Base
#dependency_injection_names, #pretty_print, #short_name, #to_s
Methods included from PortAccess
#each_input_port, #each_output_port, #each_port, #find_input_port, #find_output_port, #find_port, #has_input_port?, #has_output_port?, #has_port?
Constructor Details
#initialize(**arguments) ⇒ Component
Returns a new instance of Component
50 51 52 53 |
# File 'lib/syskit/component.rb', line 50 def initialize(**arguments) super @requirements = InstanceRequirements.new end |
Instance Attribute Details
#dynamics ⇒ NetworkGeneration::PortDynamics
The PortDynamics object that holds the dynamics information computed for this task (not its ports)
48 49 50 |
# File 'lib/syskit/component.rb', line 48 def dynamics @dynamics end |
#required_host ⇒ Object
The name of the process server that should run this component
On regular task contexts, it is the host on which the task is required to run. On compositions, it affects the composition's children
39 40 41 |
# File 'lib/syskit/component.rb', line 39 def required_host @required_host end |
#requirements ⇒ Object (readonly)
The InstanceRequirements object for which this component has been instanciated.
43 44 45 |
# File 'lib/syskit/component.rb', line 43 def requirements @requirements end |
Instance Method Details
#added_dynamic_service(srv) ⇒ void
This method returns an undefined value.
Hook called on an already-configured task when a new service got added.
Note that it will only happen for services whose 'dynamic' flag is set (not the default)
560 561 562 |
# File 'lib/syskit/component.rb', line 560 def added_dynamic_service(srv) super if defined? super end |
#added_input_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection has been created to an input port
This is called after the connection has been established on the underlying ports
656 657 658 |
# File 'lib/syskit/component.rb', line 656 def added_input_port_connection(source_port, sink_port, policy) super if defined? super end |
#added_output_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection has been created to an output port
This is called after the connection has been established on the underlying ports
680 681 682 |
# File 'lib/syskit/component.rb', line 680 def added_output_port_connection(source_port, sink_port, policy) super if defined? super end |
#adding_input_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection will be created on an input port
This is called before the connection gets established on the underlying ports
644 645 646 |
# File 'lib/syskit/component.rb', line 644 def adding_input_port_connection(source_port, sink_port, policy) super if defined? super end |
#adding_output_port_connection(source_port, sink_port, policy) ⇒ Object
Hook called when a connection will be created on an output port
This is called before the connection gets established on the underlying ports
668 669 670 |
# File 'lib/syskit/component.rb', line 668 def adding_output_port_connection(source_port, sink_port, policy) super if defined? super end |
#as(service_model) ⇒ Object
Returns a view of this component as a provider of the given service model. It can for instance be used to connect ports while transparently applying port mappings
It works only if there is only one service providing the requested type on
self
. Otherwise, one will have to select the service first and
only then call #as on the DataServiceInstance object
The same can be done at the model level with Models::Component#as
483 484 485 |
# File 'lib/syskit/component.rb', line 483 def as(service_model) return model.as(service_model).bind(self) end |
#bind(task) ⇒ Object
519 520 521 522 523 524 |
# File 'lib/syskit/component.rb', line 519 def bind(task) if !task.kind_of?(self) raise TypeError, "cannot bind #{self} to #{task}" end task end |
#can_be_deployed_by?(task) ⇒ Boolean
Tests whether a task can be used as-is to deploy this
It is mostly the same as #can_merge?, while taking into account e.g. that some operations done during merging will require the component to do a reconfiguration cycle
307 308 309 |
# File 'lib/syskit/component.rb', line 307 def can_be_deployed_by?(task) task.can_merge?(self) end |
#can_finalize? ⇒ Boolean
Controls whether the task can be removed from the plan
Task context objects are kept while they're being set up, for the sake of not breaking the setup process in an uncontrollable way.
259 260 261 |
# File 'lib/syskit/component.rb', line 259 def can_finalize? !setting_up? end |
#can_merge?(task) ⇒ Boolean
Test if the given task could be merged in self
This method should only consider intrinsic criteria for the merge, as e.g. compatibility of models or the value abstract? It should never look into the task's neighborhood
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/syskit/component.rb', line 279 def can_merge?(task) if !super NetworkGeneration::MergeSolver.info "rejected: Component#can_merge? super returned false" return end # Cannot merge if we are not reusable if !reusable? NetworkGeneration::MergeSolver.info "rejected: receiver is not reusable" return end # We can not replace a non-abstract task with an # abstract one if !task.abstract? && abstract? NetworkGeneration::MergeSolver.info "rejected: cannot merge a non-abstract task into an abstract one" return end return true end |
#concrete_model ⇒ Object
Returns the most-derived model that is not a private specialization
606 607 608 |
# File 'lib/syskit/component.rb', line 606 def concrete_model self.class.concrete_model end |
#configure ⇒ Object
User-provided part of the component configuration
264 265 266 |
# File 'lib/syskit/component.rb', line 264 def configure super if defined? super end |
#connect_to(port_or_component, policy = Hash.new) ⇒ Object
Automatically computes connections from the output ports of self to the given port or to the input ports of the given component
(see Syskit.connect)
515 516 517 |
# File 'lib/syskit/component.rb', line 515 def connect_to(port_or_component, policy = Hash.new) Syskit.connect(self, port_or_component, policy) end |
#create_fresh_copy ⇒ Object
64 65 66 67 68 |
# File 'lib/syskit/component.rb', line 64 def create_fresh_copy new_task = super new_task.robot = robot new_task end |
#data_accessor(*args) ⇒ Object
Common implementation of port search for #data_reader and #data_writer
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/syskit/component.rb', line 370 def data_accessor(*args) # :nodoc: policy = Hash.new if args.last.respond_to?(:to_hash) policy = args.pop end port_name = args.pop if !args.empty? role_path = args parent = resolve_role_path(role_path[0..-2]) task = parent.child_from_role(role_path.last) if parent.respond_to?(:map_child_port) port_name = parent.map_child_port(role_path.last, port_name) end else task = self end return task, port_name, policy end |
#data_reader(*args) ⇒ Object
call-seq:
data_reader 'port_name'[, policy]
data_reader 'role_name', 'port_name'[, policy]
Returns a data reader that allows to read the specified port
In the first case, the returned reader is applied to a port on
self
. In the second case, it is a port of the specified child.
In both cases, an optional connection policy can be specified as
data_reader('pose', 'pose_samples', :type => :buffer, :size => 1)
A pull policy is taken by default, as to avoid impacting the components.
The reader is automatically disconnected when the task quits
436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/syskit/component.rb', line 436 def data_reader(*args) task, port_name, policy = data_accessor(*args) policy, other_policy = Kernel. policy, :pull => true policy.merge!(other_policy) port = task.find_output_port(port_name) if !port raise ArgumentError, "#{task} has no output port #{port_name}" end result = port.reader(policy) data_readers << result result end |
#data_writer(*args) ⇒ Object
call-seq:
data_writer 'port_name'[, policy]
data_writer 'role_name', 'port_name'[, policy]
Returns a data writer that allows to read the specified port
In the first case, the returned writer is applied to a port on
self
. In the second case, it is a port of the specified child.
In both cases, an optional connection policy can be specified as
data_writer('pose', 'pose_samples', :type => :buffer, :size => 1)
A pull policy is taken by default, as to avoid impacting the components.
The writer is automatically disconnected when the task quits
407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/syskit/component.rb', line 407 def data_writer(*args) task, port_name, policy = data_accessor(*args) port = task.find_input_port(port_name) if !port raise ArgumentError, "#{task} has no input port #{port_name}" end result = port.writer(policy) data_writers << result result end |
#dependency_context ⇒ Object
Returns a description of this task based on the dependency information
627 628 629 630 631 632 633 634 |
# File 'lib/syskit/component.rb', line 627 def dependency_context enum_for(:each_parent_object, Roby::TaskStructure::Dependency). map do |parent_task| = parent_task[self, Roby::TaskStructure::Dependency] [[:roles].to_a.first, parent_task] end end |
#deployment_hints ⇒ Object
Returns a set of hints that should be used to disambiguate the deployment of this task.
It looks for #deployment_hints in the requirements. If there are none, it then looks in the parents.
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/syskit/component.rb', line 83 def deployment_hints hints = requirements.deployment_hints return hints if !hints.empty? result = Set.new each_parent_task do |p| result |= p.deployment_hints end result end |
#duplicate_missing_services_from(task) ⇒ Object
345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/syskit/component.rb', line 345 def duplicate_missing_services_from(task) missing_services = task.model.each_data_service.find_all do |_, srv| !model.find_data_service(srv.full_name) end missing_services.each do |_, srv| if !srv.respond_to?(:dynamic_service) raise InternalError, "attempting to duplicate static service #{srv.name} from #{task} to #{self}" end = Hash[as: srv.name]. merge(srv.) require_dynamic_service srv.dynamic_service.name, ** end end |
#each_data_service ⇒ Object
Yields the data services that are defined on this task
100 101 102 103 104 105 106 |
# File 'lib/syskit/component.rb', line 100 def each_data_service return enum_for(:each_data_service) if !block_given? model.each_data_service do |name, srv| yield(srv.bind(self)) end self end |
#each_dynamic_service(&block) ⇒ Object
has been renamed to #each_required_dynamic_service for consistency with the model-level method
566 567 568 |
# File 'lib/syskit/component.rb', line 566 def each_dynamic_service(&block) each_required_dynamic_service(&block) end |
#each_fullfilled_model(&block) ⇒ Object
Returns the set of models this task fullfills
95 96 97 |
# File 'lib/syskit/component.rb', line 95 def each_fullfilled_model(&block) model.each_fullfilled_model(&block) end |
#each_required_dynamic_service {|srv| ... } ⇒ void
This method returns an undefined value.
Yields the data services that have been created through the dynamic data service mechanism
578 579 580 581 582 583 584 585 |
# File 'lib/syskit/component.rb', line 578 def each_required_dynamic_service return enum_for(:each_dynamic_service) if !block_given? each_data_service do |srv| if srv.model.respond_to?(:dynamic_service) yield(srv) end end end |
#find_data_service(service_name) ⇒ BoundDataService?
Finds a data service by its name
117 118 119 120 121 |
# File 'lib/syskit/component.rb', line 117 def find_data_service(service_name) if service_model = model.find_data_service(service_name) return service_model.bind(self) end end |
#find_data_service_from_type(service_type) ⇒ BoundDataService?
Finds a data service by its data service model
130 131 132 133 134 |
# File 'lib/syskit/component.rb', line 130 def find_data_service_from_type(service_type) if service_model = model.find_data_service_from_type(service_type) return service_model.bind(self) end end |
#find_through_method_missing(m, args) ⇒ Object
469 470 471 472 |
# File 'lib/syskit/component.rb', line 469 def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( self, m, args, '_srv' => :find_data_service) || super end |
#has_data_service?(service_name) ⇒ Boolean
108 109 110 |
# File 'lib/syskit/component.rb', line 108 def has_data_service?(service_name) !!model.find_data_service(service_name) end |
#has_through_method_missing?(m) ⇒ Boolean
464 465 466 467 |
# File 'lib/syskit/component.rb', line 464 def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( self, m, '_srv' => :has_data_service?) || super end |
#initialize_copy(source) ⇒ Object
55 56 57 58 59 60 61 62 |
# File 'lib/syskit/component.rb', line 55 def initialize_copy(source) super @requirements = @requirements.dup if source.specialized_model? specialize end duplicate_missing_services_from(source) end |
#meets_configurationg_precedence_constraints? ⇒ Boolean
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/syskit/component.rb', line 150 def meets_configurationg_precedence_constraints? waiting_precedence_relation = start_event. parent_objects(Roby::EventStructure::SyskitConfigurationPrecedence). find do |event| !event.emitted? && !event.unreachable? end if waiting_precedence_relation debug { "#{self} not ready for setup: waiting on #{waiting_precedence_relation}" } false else true end end |
#merge(merged_task) ⇒ Object
Updates self so that it is a valid replacement for merged_task
This method assumes that #can_merge?(task) has already been called and returned true
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/syskit/component.rb', line 315 def merge(merged_task) # Copy arguments of +merged_task+ that are not yet assigned in # +self+ arguments.semantic_merge!(merged_task.arguments) # Merge the fullfilled model if set explicitely explicit_merged_fullfilled_model = merged_task.explicit_fullfilled_model explicit_this_fullfilled_model = explicit_fullfilled_model if explicit_this_fullfilled_model && explicit_merged_fullfilled_model self.fullfilled_model = Roby::TaskStructure::Dependency.merge_fullfilled_model( explicit_merged_fullfilled_model, [explicit_this_fullfilled_model[0]] + explicit_this_fullfilled_model[1], explicit_this_fullfilled_model[2]) elsif explicit_merged_fullfilled_model self.fullfilled_model = explicit_merged_fullfilled_model.dup end # Merge the InstanceRequirements objects update_requirements(merged_task.requirements) # If merged_task has instantiated dynamic services, instantiate # them on self if merged_task.model.private_specialization? duplicate_missing_services_from(merged_task) end nil end |
#perform_setup(promise) ⇒ Object
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.
The actual setup operations. #setup is the user-facing part of the setup API, which creates the promise and sets up the setup-related bookkeeping operations
209 210 211 212 213 214 215 216 217 |
# File 'lib/syskit/component.rb', line 209 def perform_setup(promise) promise.on_success(description: "#{self}#perform_setup#configure") do freeze_delayed_arguments if self.model.needs_stub?(self) self.model.prepare_stub(self) end configure end end |
#placeholder? ⇒ Boolean
Whether this component instance is a placeholder for an abstract combination of a component model and data services
74 75 76 |
# File 'lib/syskit/component.rb', line 74 def placeholder? false end |
#ready_for_setup? ⇒ Boolean
Returns true if the underlying Orocos task is in a state that allows it to be configured
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/syskit/component.rb', line 167 def ready_for_setup? # :nodoc: if garbage? debug { "#{self} not ready for setup: garbage collected but not yet finalized" } return false elsif !fully_instanciated? debug { "#{self} not ready for setup: not fully instanciated" } return false end meets_configurationg_precedence_constraints? end |
#removed_input_port_connection(source_task, source_port, sink_port) ⇒ Object
Hook called when a connection has been removed from an input port
This is called after the connection has been removed on the underlying ports. It will be called only if this task is set up
Unlike the add hooks, this does not deal with the syskit-level representation of tasks, but with the underlying component handler. The root cause of it is that disconnection can be performed after a Roby task got finalized.
714 715 716 |
# File 'lib/syskit/component.rb', line 714 def removed_input_port_connection(source_task, source_port, sink_port) super if defined? super end |
#removed_output_port_connection(source_port, sink_task, sink_port) ⇒ Object
Hook called when a connection has been removed from an output port
This is called after the connection has been removed on the underlying ports. It will be called only if this task is set up
Unlike the add hooks, this does not deal with the syskit-level representation of tasks, but with the underlying component handler. The root cause of it is that disconnection can be performed after a Roby task got finalized.
748 749 750 |
# File 'lib/syskit/component.rb', line 748 def removed_output_port_connection(source_port, sink_task, sink_port) super if defined? super end |
#removing_input_port_connection(source_task, source_port, sink_port) ⇒ Object
Hook called when a connection will be removed from an input port
This is called before the connection gets removed on the underlying ports. It will be called only if this task is set up
Unlike the add hooks, this does not deal with the syskit-level representation of tasks, but with the underlying component handler. The root cause of it is that disconnection can be performed after a Roby task got finalized.
697 698 699 |
# File 'lib/syskit/component.rb', line 697 def removing_input_port_connection(source_task, source_port, sink_port) super if defined? super end |
#removing_output_port_connection(source_port, sink_task, sink_port) ⇒ Object
Hook called when a connection will be removed from an output port
This is called before the connection gets removed on the underlying ports. It will be called only if this task is set up
Unlike the add hooks, this does not deal with the syskit-level representation of tasks, but with the underlying component handler. The root cause of it is that disconnection can be performed after a Roby task got finalized.
731 732 733 |
# File 'lib/syskit/component.rb', line 731 def removing_output_port_connection(source_port, sink_task, sink_port) super if defined? super end |
#require_dynamic_service(dynamic_service_name, as: nil, **dyn_options) ⇒ BoundDataService
Requires a new dynamic service on this task context
As Models::Component#dynamic_service already stated, the new dynamic service is a description of what the task should provide. One needs to reimplement the model's #configure method to actually configure the task properly.
540 541 542 543 544 545 546 547 548 549 |
# File 'lib/syskit/component.rb', line 540 def require_dynamic_service(dynamic_service_name, as: nil, **) specialize bound_service = self.model.require_dynamic_service( dynamic_service_name, as: as, **) srv = bound_service.bind(self) if plan && plan.executable? && setup? added_dynamic_service(srv) end srv end |
#self_port_to_actual_port(port) ⇒ Syskit::Port
It should not be used directly. One should usually use Port#to_actual_port instead
494 495 496 |
# File 'lib/syskit/component.rb', line 494 def self_port_to_actual_port(port) port end |
#self_port_to_component_port(port) ⇒ Syskit::Port
Resolves the given Syskit::Port object into a Port object where #component is guaranteed to be a proper component instance
It should not be used directly. One should usually use Port#to_component_port
507 508 509 |
# File 'lib/syskit/component.rb', line 507 def self_port_to_component_port(port) model.self_port_to_component_port(port.model).bind(self) end |
#setting_up!(promise) ⇒ Object
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.
Called once at the beginning of a setup promise
222 223 224 225 226 227 |
# File 'lib/syskit/component.rb', line 222 def setting_up!(promise) if @setting_up raise InvalidState, "#{self} is already setting up" end @setting_up = promise end |
#setting_up? ⇒ Boolean
Whether the task is being set up
251 252 253 |
# File 'lib/syskit/component.rb', line 251 def setting_up? !!@setting_up end |
#setup ⇒ Promise
Create a Roby::Promise object that configures the component
Never overload this method. Overload #perform_setup instead.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/syskit/component.rb', line 188 def setup if setup? raise ArgumentError, "#{self} is already set up" end promise = self.promise(description: "promise:#{self}#setup") perform_setup(promise) promise.on_error(description: "#{self}#setup#setup_failed!") do |e| setup_failed!(e) end promise.on_success(description: "#{self}#setup#setup_successful!") do setup_successful! end setting_up!(promise) promise end |
#setup=(value) ⇒ Object
Returns true if the underlying Orocos task has been properly configured
181 |
# File 'lib/syskit/component.rb', line 181 attr_predicate :setup?, true |
#setup? ⇒ Boolean
Returns true if the underlying Orocos task has been properly configured
181 |
# File 'lib/syskit/component.rb', line 181 attr_predicate :setup?, true |
#setup_failed!(exception) ⇒ Object
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.
Called when the setup process failed
241 242 243 244 245 246 247 248 |
# File 'lib/syskit/component.rb', line 241 def setup_failed!(exception) if start_event.plan start_event.emit_failed(exception) else Roby.execution_engine.add_framework_error(e, "#{self} got finalized before the setting_up! error handler was called") end @setting_up = nil end |
#setup_successful! ⇒ Object
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.
Called once the setup process is finished to mark the task as set up
233 234 235 236 |
# File 'lib/syskit/component.rb', line 233 def setup_successful! @setting_up = nil self.setup = true end |
#should_configure_after(object) ⇒ Object
Declare that this component should not be configured until
event
has been emitted. This is used to sequence
configurations with other system events, but should not be required in most
cases
139 140 141 142 143 |
# File 'lib/syskit/component.rb', line 139 def should_configure_after(object) # To make the scheduler happy should_start_after object object.add_syskit_configuration_precedence(start_event) end |
#specialize ⇒ Object
Sets up this task to use its singleton class as model instead of the plain class. It is useful in particular for dynamic services
593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/syskit/component.rb', line 593 def specialize if model != singleton_class @model = singleton_class model.name = self.class.name model.concrete_model = self.class.concrete_model model.private_specialization = true model.private_model self.class.setup_submodel(model) true end end |
#specialized_model? ⇒ Boolean
587 588 589 |
# File 'lib/syskit/component.rb', line 587 def specialized_model? concrete_model != model end |
#start_only_when_connected? ⇒ Boolean
Whether this task should be started only after all its inputs have been connected
270 271 272 |
# File 'lib/syskit/component.rb', line 270 def start_only_when_connected? true end |
#to_instance_requirements ⇒ Syskit::InstanceRequirements
Generates the InstanceRequirements object that represents self
best
614 615 616 617 618 619 620 621 622 623 |
# File 'lib/syskit/component.rb', line 614 def to_instance_requirements # Do not use #model here as we don't want a requirement that # uses a specialized model req = self.class.to_instance_requirements req.with_arguments(arguments.assigned_arguments) if required_host req.on_server(required_host) end req end |
#update_requirements(new_requirements, name: nil, keep_abstract: false) ⇒ Object
526 527 528 529 |
# File 'lib/syskit/component.rb', line 526 def update_requirements(new_requirements, name: nil, keep_abstract: false) requirements.name = name if name requirements.merge(new_requirements, keep_abstract: keep_abstract) end |
#will_never_setup? ⇒ Boolean
Whether this task context will ever configurable
146 147 148 |
# File 'lib/syskit/component.rb', line 146 def will_never_setup? false end |