class Orocos::RubyTasks::TaskContext
A TaskContext that lives inside this Ruby process
For now, it has very limited functionality: mainly managing ports
Public Class Methods
Creates a new local task context that fits the given oroGen model
@return [TaskContext]
# File lib/orocos/ruby_tasks/task_context.rb, line 25 def self.from_orogen_model(name, orogen_model) new(name, model: orogen_model) end
Creates a new ruby task context with the given name
@param [String] name the task name @return [TaskContext]
# File lib/orocos/ruby_tasks/task_context.rb, line 33 def self.new(name, options = Hash.new, &block) options, _ = Kernel.filter_options options, model: nil, project: OroGen::Spec::Project.new(Orocos.default_loader) project = options.delete(:project) if block && !options[:model] model = OroGen::Spec::TaskContext.new(project, name) model.instance_eval(&block) options[:model] = model end local_task = LocalTaskContext.new(name) if options[:model] && options[:model].name local_task.model_name = options[:model].name end remote_task = super(local_task.ior, name: name, **options) local_task.instance_variable_set :@remote_task, remote_task remote_task.instance_variable_set :@local_task, local_task if options[:model] remote_task.setup_from_orogen_model(options[:model]) else remote_task.model.extended_state_support end remote_task rescue ::Exception local_task.dispose if local_task raise end
# File lib/orocos/ruby_tasks/task_context.rb, line 65 def initialize(ior, name: self.name, **other_options) @local_ports = Hash.new @local_properties = Hash.new @local_attributes = Hash.new super(ior, name: name, **other_options) end
Public Instance Methods
Creates a new attribute on this task context
@param [String] name the attribute name @param [Model<Typelib::Type>,String] type the type or type name @option options [Boolean] :init (true) if true, the new attribute will
be initialized with a fresh sample. Otherwise, it is left alone. This is mostly to avoid crashes / misbehaviours in case smart pointers are used
@return [Property] the attribute object
# File lib/orocos/ruby_tasks/task_context.rb, line 141 def create_attribute(name, type, options = Hash.new) options = Kernel.validate_options options, :init => true Orocos.load_typekit_for(type, false) orocos_type_name = Orocos.find_orocos_type_name_by_type(type) Orocos.load_typekit_for(orocos_type_name, true) local_attribute = @local_task.do_create_attribute(Attribute, name, orocos_type_name) @local_attributes[local_attribute.name] = local_attribute @attributes[local_attribute.name] = local_attribute if options[:init] local_attribute.write(local_attribute.new_sample) end local_attribute end
Create a new input port on this task context
@param [String] name the port name. It must be unique among all port
types
@param [String] orocos_type_name the name of the port's type, as
recognized by Orocos. In most cases, it is the same than the typelib type name
@option options [Boolean] :permanent if true (the default), the port
will be stored permanently on the task. Otherwise, it will be removed as soon as the port object gets garbage collected by Ruby
@option options [Class] :class the class that should be used to
represent the port on the Ruby side. Do not change unless you know what you are doing
# File lib/orocos/ruby_tasks/task_context.rb, line 85 def create_input_port(name, orocos_type_name, options = Hash.new) options, other_options = Kernel.filter_options options, :class => LocalInputPort create_port(false, options[:class], name, orocos_type_name, other_options) end
Create a new output port on this task context
@param [String] name the port name. It must be unique among all port
types
@param [String] orocos_type_name the name of the port's type, as
recognized by Orocos. In most cases, it is the same than the typelib type name
@option options [Boolean] :permanent if true (the default), the port
will be stored permanently on the task. Otherwise, it will be removed as soon as the port object gets garbage collected by Ruby
@option options [Class] :class the class that should be used to
represent the port on the Ruby side. Do not change unless you know what you are doing
# File lib/orocos/ruby_tasks/task_context.rb, line 103 def create_output_port(name, orocos_type_name, options = Hash.new) options, other_options = Kernel.filter_options options, :class => LocalOutputPort create_port(true, options[:class], name, orocos_type_name, other_options) end
Creates a new property on this task context
@param [String] name the property name @param [Model<Typelib::Type>,String] type the type or type name @option options [Boolean] :init (true) if true, the new property will
be initialized with a fresh sample. Otherwise, it is left alone. This is mostly to avoid crashes / misbehaviours in case smart pointers are used
@return [Property] the property object
# File lib/orocos/ruby_tasks/task_context.rb, line 166 def create_property(name, type, options = Hash.new) options = Kernel.validate_options options, :init => true Orocos.load_typekit_for(type, false) orocos_type_name = Orocos.find_orocos_type_name_by_type(type) Orocos.load_typekit_for(orocos_type_name, true) local_property = @local_task.do_create_property(Property, name, orocos_type_name) @local_properties[local_property.name] = local_property @properties[local_property.name] = local_property if options[:init] local_property.write(local_property.new_sample) end local_property end
Deregisters this task context.
This is done automatically when the object is garbage collected. However, it is sometimes better to do this explicitely, for instance to avoid the name clash warning.
# File lib/orocos/ruby_tasks/task_context.rb, line 123 def dispose @local_task.dispose end
Transition to an exception state
# File lib/orocos/ruby_tasks/task_context.rb, line 128 def exception @local_task.exception end
# File lib/orocos/ruby_tasks/task_context.rb, line 235 def has_port?(name) @local_ports.has_key?(name) || super end
Remove the given port from this task's interface
@param [LocalInputPort,LocalOutputPort] port the port to be removed @return [void]
# File lib/orocos/ruby_tasks/task_context.rb, line 112 def remove_port(port) @local_ports.delete(port.name) port.disconnect_all # don't wait for the port to be garbage collected by Ruby @local_task.do_remove_port(port.name) end
Sets up the interface of this task context so that it matches the given oroGen model
@param [OroGen::Spec::TaskContext] orogen_model the oroGen model @return [void]
# File lib/orocos/ruby_tasks/task_context.rb, line 187 def setup_from_orogen_model(orogen_model) new_properties, new_outputs, new_inputs = [], [], [] remove_outputs, remove_inputs = [], [] orogen_model.each_property do |p| if has_property?(p.name) if property(p.name).orocos_type_name != p.orocos_type_name raise IncompatibleInterface, "cannot adapt the interface of #{self} to match the model in #{orogen_model}: #{self} already has a property called #{p.name}, but with a different type" end else new_properties << p end end orogen_model.each_input_port do |p| if has_port?(p.name) existing_port = port(p.name) if existing_port.orocos_type_name != p.orocos_type_name remove_inputs << existing_port new_inputs << p end else new_inputs << p end end orogen_model.each_output_port do |p| if has_port?(p.name) existing_port = port(p.name) if existing_port.orocos_type_name != p.orocos_type_name remove_outputs << existing_port new_outputs << p end else new_outputs << p end end remove_inputs.each { |p| remove_port p } remove_outputs.each { |p| remove_port p } new_properties.each do |p| create_property(p.name, p.type) end new_inputs.each do |p| create_input_port(p.name, p.type) end new_outputs.each do |p| create_output_port(p.name, p.type) end @model = orogen_model nil end