Class: OroGen::Spec::Operation
- Inherits:
-
Object
- Object
- OroGen::Spec::Operation
- Defined in:
- lib/orogen/spec/operation.rb
Overview
Representation of a RTT operation. Instances of this object are usually created through 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);
Constant Summary collapse
- RTT_ARGUMENT_COUNT_LIMIT =
4
Instance Attribute Summary collapse
-
#arguments ⇒ Object
readonly
The set of arguments of this operation, as an array of [name, type, doc] elements.
-
#in_caller_thread ⇒ Object
readonly
True if this operation runs its associated C++ method in caller thread (default is false).
-
#name ⇒ Object
readonly
The operation name.
-
#return_type ⇒ Object
readonly
The return type of this operation, as a [type_object, qualified_cxx_type] pair.
-
#task ⇒ Object
readonly
The TaskContext instance this operation is part of.
Instance Method Summary collapse
-
#arg(*args, &block) ⇒ Object
Shortcut for #arg.
-
#argument(name, qualified_type, doc = "") ⇒ Object
Defines the next argument of this operation.
- #each_interface_type ⇒ Object
-
#find_interface_type(qualified_type) ⇒ Object
This version of find_interface_type returns both a Typelib::Type object and a normalized version for
name
. -
#has_return_value? ⇒ Boolean
Returns true if this operation's signature is not void.
- #hidden=(value) ⇒ Boolean
- #hidden? ⇒ Boolean
-
#initialize(task, name) ⇒ Operation
constructor
A new instance of Operation.
- #pretty_print(pp) ⇒ Object
-
#returns(type, doc = "") ⇒ Object
Sets the return type for this operation.
-
#runs_in_callee_thread ⇒ Object
Declares that the C++ method associated with this operation should be executed in the caller thread.
-
#runs_in_caller_thread ⇒ Object
Declares that the C++ method associated with this operation should be executed in the caller thread (default is callee thread).
-
#to_h ⇒ Hash
Converts this model into a representation that can be fed to e.g.
Constructor Details
#initialize(task, name) ⇒ Operation
Returns a new instance of Operation
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# 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 |
Instance Attribute Details
#arguments ⇒ Object (readonly)
The set of arguments of this operation, as an array of [name, type, doc]
elements. The type
objects are Typelib::Type instances.
See #argument
102 103 104 |
# File 'lib/orogen/spec/operation.rb', line 102 def arguments @arguments end |
#in_caller_thread ⇒ Object (readonly)
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
43 44 45 |
# File 'lib/orogen/spec/operation.rb', line 43 def in_caller_thread @in_caller_thread end |
#name ⇒ Object (readonly)
The operation name
38 39 40 |
# File 'lib/orogen/spec/operation.rb', line 38 def name @name end |
#return_type ⇒ Object (readonly)
The return type of this operation, as a [type_object, qualified_cxx_type] pair.
See #returns
147 148 149 |
# File 'lib/orogen/spec/operation.rb', line 147 def return_type @return_type end |
#task ⇒ Object (readonly)
The TaskContext instance this operation is part of
36 37 38 |
# File 'lib/orogen/spec/operation.rb', line 36 def task @task end |
Instance Method Details
#arg(*args, &block) ⇒ Object
Shortcut for #arg
139 140 141 |
# File 'lib/orogen/spec/operation.rb', line 139 def arg(*args, &block) argument(*args, &block) end |
#argument(name, qualified_type, doc = "") ⇒ Object
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
128 129 130 131 132 133 134 135 136 |
# 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 ⇒ Object
63 64 65 66 67 68 69 70 71 |
# 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) ⇒ Object
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
.
107 108 109 110 111 112 113 114 115 116 |
# 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? ⇒ Boolean
Returns true if this operation's signature is not void
166 167 168 |
# File 'lib/orogen/spec/operation.rb', line 166 def has_return_value? !!@return_type.first end |
#hidden=(value) ⇒ Boolean
188 |
# File 'lib/orogen/spec/operation.rb', line 188 attr_predicate :hidden?, true |
#hidden? ⇒ Boolean
188 |
# File 'lib/orogen/spec/operation.rb', line 188 attr_predicate :hidden?, true |
#pretty_print(pp) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# 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 = "") ⇒ Object
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.
154 155 156 157 158 159 160 161 162 163 |
# 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 ⇒ Object
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
86 87 88 89 |
# File 'lib/orogen/spec/operation.rb', line 86 def runs_in_callee_thread @in_caller_thread = false self end |
#runs_in_caller_thread ⇒ Object
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
77 78 79 80 |
# File 'lib/orogen/spec/operation.rb', line 77 def runs_in_caller_thread @in_caller_thread = true self end |
#to_h ⇒ Hash
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
208 209 210 211 212 213 214 215 216 217 |
# 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 |