Class: Syskit::Component

Inherits:
Roby::Task
  • Object
show all
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

Composition, TaskContext

Defined Under Namespace

Modules: Proxying

Constant Summary

Constants included from Models::Component

Models::Component::PROVIDES_ARGUMENTS

Instance Attribute Summary collapse

Instance Method Summary collapse

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

#using_data_service?

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

#dynamicsNetworkGeneration::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_hostObject

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

#requirementsObject (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)

Parameters:

  • srv (BoundDynamicDataService)

    the newly created service

See Also:

  • Syskit::Component.{{#require_dynamic_service}


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

Parameters:

  • source_port (Port)
  • sink_port (Port)
  • policy (Hash)


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

Parameters:

  • source_port (Port)
  • sink_port (Port)
  • policy (Hash)


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

Parameters:

  • source_port (Port)
  • sink_port (Port)
  • policy (Hash)


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

Parameters:

  • source_port (Port)
  • sink_port (Port)
  • policy (Hash)


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

Parameters:

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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_modelObject

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

#configureObject

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_copyObject



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.filter_options 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_contextObject

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|
            options = parent_task[self,
                                  Roby::TaskStructure::Dependency]
            [options[:roles].to_a.first, parent_task]
        end
end

#deployment_hintsObject

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
        dynamic_service_options = Hash[as: srv.name].
            merge(srv.dynamic_service_options)
        require_dynamic_service srv.dynamic_service.name, **dynamic_service_options
    end
end

#each_data_serviceObject

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

Deprecated.

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

Yield Parameters:



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

Parameters:

  • service_name (String)

    the data service name

Returns:

  • (BoundDataService, nil)

    the found data service, or nil if there are no services with that name in self



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

Parameters:

  • service_type (Model<DataService>)

    the data service model we want to find in self

Returns:

  • (BoundDataService, nil)

    the found data service, or nil if there are no services of that type in self



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

Returns:

  • (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

Returns:

  • (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

Returns:

  • (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

Returns:

  • (Boolean)

See Also:



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

Returns:

  • (Boolean)


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.

Parameters:

  • source_task (Orocos::TaskContext)
  • source_port (String)
  • sink_port (String)


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.

Parameters:

  • source_port (String)
  • sink_task (Orocos::TaskContext)
  • sink_port (String)


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.

Parameters:

  • source_task (Orocos::TaskContext)
  • source_port (String)
  • sink_port (String)


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.

Parameters:

  • source_port (String)
  • sink_task (Orocos::TaskContext)
  • sink_port (String)


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.

Parameters:

  • dynamic_service_name (String)

    the name under which the dynamic service got registered when calling Models::Component#dynamic_service

  • as (String)

    the name of the newly created service

  • dyn_options

    options passed to the dynamic service block through DynamicDataService#instanciate

Returns:



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, **dyn_options)
    specialize
    bound_service = self.model.require_dynamic_service(
        dynamic_service_name, as: as, **dyn_options)
    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

Returns:



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

Parameters:

Returns:

  • (Syskit::Port)

    a port in which Port#component is guaranteed to be a proper component (e.g. not BoundDataService)



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

Returns:

  • (Boolean)


251
252
253
# File 'lib/syskit/component.rb', line 251

def setting_up?
    !!@setting_up
end

#setupPromise

Create a Roby::Promise object that configures the component

Never overload this method. Overload #perform_setup instead.

Returns:

  • (Promise)


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

Returns:

  • (Boolean)


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

#specializeObject

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

Returns:

  • (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

Returns:

  • (Boolean)


270
271
272
# File 'lib/syskit/component.rb', line 270

def start_only_when_connected?
    true
end

#to_instance_requirementsSyskit::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

Returns:

  • (Boolean)


146
147
148
# File 'lib/syskit/component.rb', line 146

def will_never_setup?
    false
end