class OroGen::Spec::Operation

Representation of a RTT operation. Instances of this object are usually created through OroGen::Spec::TaskContext#operation. The generated code will expect the class implementation (user-visible part) to define one method, to serve the call, with almost the same name that the method itself.

For instance, the following definition

operation('MyMethod')

will require the user-visible part to define

[return value] myMethod([arguments]);

(note that the first character of the method name has been set to lowercase to generate the C++ method name)

The argument list of the C++ method (the first one) can be defined using Callable#argument. Its return type by using returns. The default method signature is no return type (i.e. void) and no arguments.

The name of the C++ method can be changed method_name.

For instance,

operation('MyMethod').
  argument('x', 'double', 'the target X value').
  argument('y', 'double', 'the target Y value').
  method_name('move').
  returns('double')

will require the user-visible part to define

double move(double x, double y);

Constants

RTT_ARGUMENT_COUNT_LIMIT

Attributes

arguments[R]

The set of arguments of this operation, as an array of [name, type, doc] elements. The type objects are Typelib::Type instances.

See argument

in_caller_thread[R]

True if this operation runs its associated C++ method in caller thread (default is false)

See also runs_in_caller_thread and runs_in_callee_thread

name[R]

The operation name

return_type[R]

The return type of this operation, as a [type_object, qualified_cxx_type] pair.

See returns

task[R]

The TaskContext instance this operation is part of

Public Class Methods

new(task, name) click to toggle source
Calls superclass method
# File lib/orogen/spec/operation.rb, line 47
def initialize(task, name)
    name = name.to_s
    if name !~ /^\w+$/
        raise ArgumentError, "#{self.class.name.downcase} names need to be valid C++ identifiers, i.e. contain only alphanumeric characters and _ (got #{name})"
    end

    @task = task
    @name = name
    @return_type = [nil, 'void', ""]
    @arguments = []
    @in_caller_thread = false
    @doc = nil

    super()
end

Public Instance Methods

arg(*args, &block) click to toggle source

Shortcut for arg

# File lib/orogen/spec/operation.rb, line 139
def arg(*args, &block)
    argument(*args, &block)
end
argument(name, qualified_type, doc = "") click to toggle source

Defines the next argument of this operation. name is the argument name and type is either the type name as a string, or a Typelib::Type object. In both cases, the required type must be defined in the task context, either because it is part of its own typekit or because it has been imported by a Project#load_typekit call.

Note that RTT does not support having more than 4 arguments for an operation, and trying that will therefore raise an error

# File lib/orogen/spec/operation.rb, line 128
def argument(name, qualified_type, doc = "")
    if arguments.size >= RTT_ARGUMENT_COUNT_LIMIT
        raise ArgumentError, "RTT does not support having more than #{RTT_ARGUMENT_COUNT_LIMIT} arguments for an operation"
    end

    type, qualified_type = find_interface_type(qualified_type)
    arguments << [name, type, doc, qualified_type]
    self
end
each_interface_type() { |ret| ... } click to toggle source
# File lib/orogen/spec/operation.rb, line 63
def each_interface_type
    return enum_for(__method__) if !block_given?
    if ret = return_type.first
        yield(ret)
    end
    arguments.each do |_, t, _|
        yield(t)
    end
end
find_interface_type(qualified_type) click to toggle source

This version of #find_interface_type returns both a Typelib::Type object and a normalized version for name. It does accept const and reference qualifiers in name.

# File lib/orogen/spec/operation.rb, line 107
def find_interface_type(qualified_type)
    if qualified_type.respond_to?(:name)
        qualified_type = qualified_type.name
    end
    type_name = OroGen.unqualified_cxx_type(qualified_type)
    typelib_type_name = ::Typelib::GCCXMLLoader.cxx_to_typelib(type_name)
    type      = task.project.find_interface_type(typelib_type_name)
    OroGen.validate_toplevel_type(type)
    return type, qualified_type.gsub(type_name, type.cxx_name)
end
has_return_value?() click to toggle source

Returns true if this operation's signature is not void

# File lib/orogen/spec/operation.rb, line 166
def has_return_value?
    !!@return_type.first
end
pretty_print(pp) click to toggle source
# File lib/orogen/spec/operation.rb, line 170
def pretty_print(pp)
    pp.text name
    pp.nest(2) do
        if self.doc
            pp.breakable
            pp.text self.doc
        end
        if !self.return_type[2].empty?
            pp.breakable
            pp.text "Returns: #{self.return_type[2]}"
        end
        arguments.map do |name, type, doc, qualified_type|
            pp.breakable
            pp.text "#{name}: #{doc}"
        end
    end
end
returns(type, doc = "") click to toggle source

Sets the return type for this operation. type can either be the type name or a Typelib::Type object. In both cases, the required type must be defined in the underlying project, either because it is part of its own typekit or because it has been imported by a Project#load_typekit call.

# File lib/orogen/spec/operation.rb, line 154
def returns(type, doc = "")
    @return_type =
        if type
            type, qualified_type = find_interface_type(type)
            [type, qualified_type, doc]
        else [nil, 'void', doc]
        end

    self
end
runs_in_callee_thread() click to toggle source

Declares that the C++ method associated with this operation should be executed in the caller thread

See also runs_in_callee_thread and in_caller_thread

# File lib/orogen/spec/operation.rb, line 86
def runs_in_callee_thread
    @in_caller_thread = false
    self
end
runs_in_caller_thread() click to toggle source

Declares that the C++ method associated with this operation should be executed in the caller thread (default is callee thread)

See also runs_in_callee_thread and in_caller_thread

# File lib/orogen/spec/operation.rb, line 77
def runs_in_caller_thread
    @in_caller_thread = true
    self
end
to_h() click to toggle source

Converts this model into a representation that can be fed to e.g. a JSON dump, that is a hash with pure ruby key / values.

The generated hash has the following keys:

name: the operation name
returns: the operation return type. It is not present if the
  operation does not return anything
    type: the return type as marshalled with
      Typelib::Type#to_h
    doc: the return type documentation

arguments: the list of arguments as an array of
    name: the argument name
    type: the argument type as marshalled with
      Typelib::Type#to_h
    doc: the argument documentation

@return [Hash]

# File lib/orogen/spec/operation.rb, line 208
def to_h
    result = Hash[name: name, doc: (doc || "")]
    if has_return_value?
        result[:returns] = Hash[type: self.return_type[0].to_h, doc: self.return_type[2]]
    end
    result[:arguments] = arguments.map do |name, type, doc, qualified_type|
        Hash[name: name, type: type.to_h, doc: doc]
    end
    result
end