Class: Orocos::Operation

Inherits:
Object
  • Object
show all
Defined in:
lib/orocos/operations.rb,
ext/rorocos/operations.cc

Overview

Base class for RTTMethod and Command

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(task, name, return_spec, arguments_spec) ⇒ Operation

Returns a new instance of Operation



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/orocos/operations.rb', line 81

def initialize(task, name, return_spec, arguments_spec)
    @task, @name, @return_spec, @arguments_spec =
        task, name, return_spec, arguments_spec

    @orocos_return_typenames = return_spec.map do |type_name|
        type_name = OroGen.unqualified_cxx_type(type_name)
        Orocos.normalize_typename(type_name)
    end
    @orocos_arguments_typenames = arguments_spec.map do |_, _, type_name|
        type_name = OroGen.unqualified_cxx_type(type_name)
        Orocos.normalize_typename(type_name)
    end
    @inout_arguments = arguments_spec.each_with_index.map do |(_, _, type_name), i|
        if type_name =~ /&/ && type_name !~ /(^|[^\w])const($|[^\w])/
            i
        end
    end.compact

    # Remove a void return type
    if Orocos.registry.get(orocos_return_typenames.first).null?
        @void_return = true
        orocos_return_typenames.shift 
    else
        @void_return = false
    end

    @return_types    = typelib_types_for(orocos_return_typenames)
    @arguments_types = typelib_types_for(orocos_arguments_typenames)
end

Instance Attribute Details

#arguments_specObject (readonly)

An array describing the arguments. Each element is a [name, doc, type_name] tuple



67
68
69
# File 'lib/orocos/operations.rb', line 67

def arguments_spec
  @arguments_spec
end

#arguments_typesObject (readonly)

The typelib types for the arguments. This is an array of subclasses of Typelib::Type, with each element being the type of the corresponding element in #arguments_spec. It describes the types that the Ruby side will manipulate



77
78
79
# File 'lib/orocos/operations.rb', line 77

def arguments_types
  @arguments_types
end

#descriptionObject (readonly)

The method description



57
58
59
# File 'lib/orocos/operations.rb', line 57

def description
  @description
end

#inout_argumentsObject (readonly)

Returns the value of attribute inout_arguments



79
80
81
# File 'lib/orocos/operations.rb', line 79

def inout_arguments
  @inout_arguments
end

#nameObject (readonly)

The method name



55
56
57
# File 'lib/orocos/operations.rb', line 55

def name
  @name
end

#orocos_arguments_typenamesObject (readonly)

The typelib types for the arguments. This is an array of subclasses of Typelib::Type, with each element being the type of the corresponding element in #arguments_spec. It describes the types that the C++ side manipulates (i.e. declared in the Orocos component)



72
73
74
# File 'lib/orocos/operations.rb', line 72

def orocos_arguments_typenames
  @orocos_arguments_typenames
end

#orocos_return_typenamesObject (readonly)

The subclass of Typelib::Type that represents the type of the return value, as declared by the Orocos



61
62
63
# File 'lib/orocos/operations.rb', line 61

def orocos_return_typenames
  @orocos_return_typenames
end

#return_specObject (readonly)

The type name of the return value



59
60
61
# File 'lib/orocos/operations.rb', line 59

def return_spec
  @return_spec
end

#return_typesObject (readonly)

The subclass of Typelib::Type that will be manipulated by the Ruby code



64
65
66
# File 'lib/orocos/operations.rb', line 64

def return_types
  @return_types
end

#taskObject (readonly)

The task this method is part of



52
53
54
# File 'lib/orocos/operations.rb', line 52

def task
  @task
end

Instance Method Details

#callop(*args) ⇒ Object

Calls the method with the provided arguments, waiting for the method to finish. It returns the value returned by the remote method.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/orocos/operations.rb', line 174

def callop(*args)
    raw_result = common_call(args) do |filtered|
        return_typename, return_value = nil
        if !@void_return
            return_typename = orocos_return_typenames[0]
            return_value = result_value_for(return_types.first)
        end

        task.do_operation_call(name, return_typename, return_value,
                   orocos_arguments_typenames, filtered)

        result = []
        if return_value
            result << return_value
        end
        inout_arguments.each do |index|
            result << filtered[index]
        end
        result
    end

    result = []
    raw_result.each_with_index do |v, i|
        result << Typelib.to_ruby(v, return_types[i])
    end
    if result.empty? then nil
    elsif result.size == 1 then result.first
    else result
    end
end

#common_call(args) ⇒ Object

Helper method for RTTMethod and Command



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/orocos/operations.rb', line 130

def common_call(args) # :nodoc:
    if args.size != arguments_spec.size
        raise ArgumentError, "expected #{arguments_spec.size} arguments but got #{args.size}"
    end

    filtered = []
    args.each_with_index do |v, i|
        filtered << Typelib.from_ruby(v, arguments_types[i])
    end
    CORBA.refine_exceptions(self) do
        yield(filtered)
    end
end

#new_argument(index) ⇒ Object

Returns a new Typelib value for the Nth argument



125
126
127
# File 'lib/orocos/operations.rb', line 125

def new_argument(index)
    arguments_types[index].new
end

#new_resultObject

Returns a Typelib value that can store the result of this operation



153
154
155
156
157
# File 'lib/orocos/operations.rb', line 153

def new_result
    return_types.map do |type|
        result_value_for(type)
    end
end

#result_value_for(type) ⇒ Object



144
145
146
147
148
149
150
# File 'lib/orocos/operations.rb', line 144

def result_value_for(type)
    if type.opaque?
        raise ArgumentError, "I don't know how to handle #{type.name}"
    else
        type.new
    end
end

#sendop(*args) ⇒ Object

Requests the operation to be started. It does not wait for it to finish, returning instead an OperationHandle object that can be used to query the operation status and return value



162
163
164
165
166
167
168
169
170
# File 'lib/orocos/operations.rb', line 162

def sendop(*args)
    common_call(args) do |filtered|
        handle = task.do_operation_send(name, orocos_arguments_typenames, filtered)
        handle.instance_variable_set :@operation, self
        handle.instance_variable_set :@orocos_return_types, @orocos_return_typenames.dup
        handle.instance_variable_set :@return_values, new_result
        handle
    end
end

#typelib_types_for(types) ⇒ Object

Replaces in types the opaque types by the types that should be used on the Ruby side



113
114
115
116
117
118
119
120
121
122
# File 'lib/orocos/operations.rb', line 113

def typelib_types_for(types)
    types.map do |t|
        begin
            Orocos.typelib_type_for(t)
        rescue Typelib::NotFound
            Orocos.load_typekit_for(t)
            Orocos.typelib_type_for(t)
        end
    end
end