Class: Orocos::RubyTasks::TaskContext

Inherits:
TaskContext
  • Object
show all
Defined in:
lib/orocos/ruby_tasks/task_context.rb,
ext/rorocos/ruby_task_context.cc

Overview

A TaskContext that lives inside this Ruby process

For now, it has very limited functionality: mainly managing ports

Direct Known Subclasses

StubTaskContext

Defined Under Namespace

Classes: LocalTaskContext

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ior, options = Hash.new) ⇒ TaskContext

Returns a new instance of TaskContext.


63
64
65
66
67
68
69
# File 'lib/orocos/ruby_tasks/task_context.rb', line 63

def initialize(ior, options = Hash.new)
    @local_ports = Hash.new
    @local_properties = Hash.new
    @local_attributes = Hash.new
    options, other_options = Kernel.filter_options options, :name => name
    super(ior, other_options.merge(options))
end

Class Method Details

.from_orogen_model(name, orogen_model) ⇒ TaskContext

Creates a new local task context that fits the given oroGen model

Returns:


25
26
27
# File 'lib/orocos/ruby_tasks/task_context.rb', line 25

def self.from_orogen_model(name, orogen_model)
    new(name, model: orogen_model)
end

.new(name, options = Hash.new, &block) ⇒ TaskContext

Creates a new ruby task context with the given name

Parameters:

  • name (String)

    the task name

Returns:


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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, 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])
    end
    remote_task
rescue ::Exception
    local_task.dispose if local_task
    raise
end

Instance Method Details

#create_attribute(name, type, options = Hash.new) ⇒ Property

Creates a new attribute on this task context

Parameters:

  • name (String)

    the attribute name

  • type (Model<Typelib::Type>, String)

    the type or type name

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • :init (Boolean) — default: 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

Returns:


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/orocos/ruby_tasks/task_context.rb', line 135

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_input_port(name, orocos_type_name, options = Hash.new) ⇒ Object

Create a new input port on this task context

Parameters:

  • name (String)

    the port name. It must be unique among all port types

  • orocos_type_name (String)

    the name of the port's type, as recognized by Orocos. In most cases, it is the same than the typelib type name

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • :permanent (Boolean)

    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

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


84
85
86
87
# File 'lib/orocos/ruby_tasks/task_context.rb', line 84

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_output_port(name, orocos_type_name, options = Hash.new) ⇒ Object

Create a new output port on this task context

Parameters:

  • name (String)

    the port name. It must be unique among all port types

  • orocos_type_name (String)

    the name of the port's type, as recognized by Orocos. In most cases, it is the same than the typelib type name

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • :permanent (Boolean)

    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

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


102
103
104
105
# File 'lib/orocos/ruby_tasks/task_context.rb', line 102

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

#create_property(name, type, options = Hash.new) ⇒ Property

Creates a new property on this task context

Parameters:

  • name (String)

    the property name

  • type (Model<Typelib::Type>, String)

    the type or type name

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • :init (Boolean) — default: 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

Returns:


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/orocos/ruby_tasks/task_context.rb', line 160

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

#disposeObject

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.


122
123
124
# File 'lib/orocos/ruby_tasks/task_context.rb', line 122

def dispose
    @local_task.dispose
end

#remove_port(port) ⇒ void

This method returns an undefined value.

Remove the given port from this task's interface

Parameters:


111
112
113
114
115
# File 'lib/orocos/ruby_tasks/task_context.rb', line 111

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

#setup_from_orogen_model(orogen_model) ⇒ void

This method returns an undefined value.

Sets up the interface of this task context so that it matches the given oroGen model

Parameters:

  • orogen_model (OroGen::Spec::TaskContext)

    the oroGen model


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/orocos/ruby_tasks/task_context.rb', line 181

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)
            if port(p.name).orocos_type_name != p.orocos_type_name
                remove_inputs << p
                new_inputs << p
            end
        else new_inputs << p
        end
    end
    orogen_model.each_output_port do |p|
        if has_port?(p.name)
            if port(p.name).orocos_type_name != p.orocos_type_name
                remove_outputs << p
                new_outputs << p
            end
        else new_outputs << p
        end
    end

    remove_inputs.each { |p| remove_input_port p }
    remove_outputs.each { |p| remove_output_port p }
    new_properties.each do |p|
        create_property(p.name, p.orocos_type_name)
    end
    new_inputs.each do |p|
        create_input_port(p.name, p.orocos_type_name)
    end
    new_outputs.each do |p|
        create_output_port(p.name, p.orocos_type_name)
    end
    @model = orogen_model
    nil
end