Module: Roby::Actions::Models::InterfaceBase
- Extended by:
- MetaRuby::Attributes
- Defined in:
- lib/roby/actions/models/interface_base.rb
Overview
Model-level API for Interface
Defined Under Namespace
Classes: ArgumentCountMismatch
Instance Method Summary collapse
-
#action_script(name, **options) { ... } ⇒ Action, Coordination::Models::ActionScript
Defines an action from an Coordination::Models::ActionScript.
-
#action_state_machine(name) { ... } ⇒ (CoordinationAction,ActionStateMachine)
Defines an action from an Coordination::Models::ActionStateMachine.
- #added_method_action_check_arity(name, description) ⇒ Object
-
#clear_model ⇒ Object
Clears everything stored on this model.
-
#create_and_register_coordination_action(name, coordination_class, action_model: require_current_description, &block) ⇒ (CoordinationAction,Action)
private
Create an action that will instanciate a coordination model.
-
#create_coordination_action(action_model, coordination_class, &block) ⇒ Object
Helper method for #action_state_machine and #action_script.
- #create_coordination_model(action_model, coordination_class, &block) ⇒ Object
-
#create_default_action_return_type(name, action_model) ⇒ Object
private
Create and register the default task model for a given action model if needed (i.e. if the action model does not have an explicit return type yet).
-
#describe(doc = nil) ⇒ Object
Create a new action description that is going to be used to describe the next method.
-
#each_action {|action| ... } ⇒ Object
Enumerates the actions registered on this interface.
-
#fault_response_table ⇒ Array<Model<FaultResponseTable>>
The set of fault response tables added to this action interface.
-
#find_action_by_name(name) ⇒ Models::Action?
Returns the action description for the given action name, or nil if there are none with that name.
-
#find_all_actions_by_type(type) ⇒ Array<Models::Action>
Returns all the action description for the actions that can produce such a task.
-
#method_added(method_name) ⇒ Object
Hook used to export methods for which there is a description.
-
#method_missing(name, *args, **kw) ⇒ Action
Returns an action description if ‘m’ is the name of a known action.
-
#promote_registered_action(_name, action) ⇒ Object
private
Internal handler for MetaRuby’s inherited-attribute functionality.
-
#register_action(name, action_model) ⇒ Object
Registers an action on this model.
-
#register_action!(name, action_model) ⇒ Object
private
Internal, no-check version of #register_action.
-
#register_added_method_as_action(method_name, description) ⇒ Object
Register an existing instance method as action.
-
#registered_action ⇒ Hash<String,Models::Action>
The set of actions defined on this interface.
-
#require_current_description ⇒ Object
private
Verifies that #describe was called to describe an action that is now being defined, and returns it.
- #respond_to_missing?(name, include_private) ⇒ Boolean
-
#state_machine(name, &block) ⇒ Object
deprecated
Deprecated.
use #action_state_machine instead
-
#use_fault_response_table(table_model, arguments = {}) ⇒ Object
Declare that this fault response table should be used on all plans that are going to use this action interface.
-
#use_library(library) ⇒ void
Adds all actions defined in another action interface or in an action library in this interface.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, **kw) ⇒ Action
Returns an action description if ‘m’ is the name of a known action
361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/roby/actions/models/interface_base.rb', line 361 def method_missing(name, *args, **kw) if (model = find_action_by_name(name.to_s)) if args.size > 1 raise ArgumentError, "expected zero or one argument, got #{args.size}" end return model.new(*args, **kw) end super end |
Instance Method Details
#action_script(name, **options) { ... } ⇒ Action, Coordination::Models::ActionScript
Defines an action from an Coordination::Models::ActionScript
The action script model can later be retrieved using Action#coordination_model
348 349 350 351 352 |
# File 'lib/roby/actions/models/interface_base.rb', line 348 def action_script(name, **, &block) create_and_register_coordination_action( name, Coordination::ActionScript, **, &block ) end |
#action_state_machine(name) { ... } ⇒ (CoordinationAction,ActionStateMachine)
Defines an action from an Coordination::Models::ActionStateMachine
The action state machine model can later be retrieved using Action#coordination_model
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/roby/actions/models/interface_base.rb', line 312 def action_state_machine(name, &block) action_model = require_current_description # Define user-possible starting states, this will override # the default starting state if action_model.has_arg?("start_state") raise ArgumentError, "A argument \"start_state\" has defined for the "\ "statemachine, but this keyword is reserved" end action_model.optional_arg( "start_state", "name of the state in which the state machine should start", nil ) create_and_register_coordination_action( name, Coordination::ActionStateMachine, action_model: action_model, &block ) end |
#added_method_action_check_arity(name, description) ⇒ Object
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/roby/actions/models/interface_base.rb', line 181 def added_method_action_check_arity(name, description) expected_argument_count = if description.arguments.empty? then 0 else 1 end begin check_arity(instance_method(name), expected_argument_count) rescue ArgumentError if expected_argument_count == 0 raise ArgumentCountMismatch, "action #{name} has been declared to have no "\ "arguments, the #{name} method must be callable "\ "without any arguments" else raise ArgumentCountMismatch, "action #{name} has been declared to have "\ "arguments, the #{name} method must be "\ "callable with a single Hash argument" end end end |
#clear_model ⇒ Object
Clears everything stored on this model
68 69 70 71 |
# File 'lib/roby/actions/models/interface_base.rb', line 68 def clear_model super actions.clear end |
#create_and_register_coordination_action(name, coordination_class, action_model: require_current_description, &block) ⇒ (CoordinationAction,Action)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create an action that will instanciate a coordination model
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/roby/actions/models/interface_base.rb', line 255 def create_and_register_coordination_action( name, coordination_class, action_model: require_current_description, &block ) name = name.to_s create_default_action_return_type(name, action_model) action_model, coordination_model = create_coordination_action( action_model, coordination_class, &block ) register_action!(name, action_model) coordination_model.name = name define_method(name) do |**arguments| action_model.instanciate(plan, **arguments) end [action_model, coordination_model] end |
#create_coordination_action(action_model, coordination_class, &block) ⇒ Object
Helper method for #action_state_machine and #action_script
292 293 294 295 296 297 298 299 |
# File 'lib/roby/actions/models/interface_base.rb', line 292 def create_coordination_action(action_model, coordination_class, &block) coordination_model = create_coordination_model( action_model, coordination_class, &block ) action_model = CoordinationAction.new(coordination_model, action_model) [action_model, coordination_model] end |
#create_coordination_model(action_model, coordination_class, &block) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/roby/actions/models/interface_base.rb', line 274 def create_coordination_model(action_model, coordination_class, &block) root_m = action_model.returned_type coordination_model = coordination_class .new_submodel(action_interface: self, root: root_m) action_model.arguments.each do |arg| if !arg.required coordination_model.argument arg.name, default: arg.default else coordination_model.argument arg.name end end coordination_model.parse(&block) coordination_model end |
#create_default_action_return_type(name, action_model) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create and register the default task model for a given action model if needed (i.e. if the action model does not have an explicit return type yet)
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/roby/actions/models/interface_base.rb', line 136 def create_default_action_return_type(name, action_model) return if action_model.returned_type != Roby::Task task_model_name = name.camelcase(:upper) if const_defined_here?(task_model_name) action_model.returns(const_get(task_model_name)) else task_model = Roby::Task.new_submodel do terminates end const_set task_model_name, task_model task_model.permanent_model = permanent_model? action_model.returns(task_model) end end |
#describe(doc = nil) ⇒ Object
Create a new action description that is going to be used to describe the next method. Note that only methods that have a description are exported as actions
78 79 80 81 82 83 84 85 86 87 |
# File 'lib/roby/actions/models/interface_base.rb', line 78 def describe(doc = nil) if @current_description Actions::Interface.warn( "the last #describe call was not followed by an action "\ "definition. Did you forget to add a method to your "\ "action interface ?" ) end @current_description = Models::Action.new(doc) end |
#each_action {|action| ... } ⇒ Object
Enumerates the actions registered on this interface
59 60 61 62 63 64 65 |
# File 'lib/roby/actions/models/interface_base.rb', line 59 def each_action return enum_for(:each_action) unless block_given? each_registered_action do |_, description| yield(description) end end |
#fault_response_table ⇒ Array<Model<FaultResponseTable>>
The set of fault response tables added to this action interface
31 |
# File 'lib/roby/actions/models/interface_base.rb', line 31 inherited_attribute(:fault_response_table, :fault_response_tables) { [] } |
#find_action_by_name(name) ⇒ Models::Action?
Returns the action description for the given action name, or nil if there are none with that name
210 211 212 |
# File 'lib/roby/actions/models/interface_base.rb', line 210 def find_action_by_name(name) find_registered_action(name.to_s) end |
#find_all_actions_by_type(type) ⇒ Array<Models::Action>
Returns all the action description for the actions that can produce such a task
219 220 221 222 223 224 225 226 227 |
# File 'lib/roby/actions/models/interface_base.rb', line 219 def find_all_actions_by_type(type) result = [] each_action do |description| if description.returned_type.fullfills?(type) result << description end end result end |
#method_added(method_name) ⇒ Object
Hook used to export methods for which there is a description
153 154 155 156 157 158 159 160 |
# File 'lib/roby/actions/models/interface_base.rb', line 153 def method_added(method_name) super return unless @current_description description = @current_description @current_description = nil register_added_method_as_action(method_name, description) end |
#promote_registered_action(_name, action) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Internal handler for MetaRuby’s inherited-attribute functionality. This method does nothing, it’s here so that the registered_action attribute gets promotion enabled. It’s overloaded in Interface to actually rebind the action to the interface
19 20 21 |
# File 'lib/roby/actions/models/interface_base.rb', line 19 def promote_registered_action(_name, action) action end |
#register_action(name, action_model) ⇒ Object
Registers an action on this model
This is used to selectively reuse an action from a different action interface, for instance:
class < Roby::Actions::Interface
action_state_machine 'go_to' do
end
end
class UI < Roby::Actions::Interface
register_action 'go_to', .go_to.model
end
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/roby/actions/models/interface_base.rb', line 103 def register_action(name, action_model) unless action_model.respond_to?(:to_action_model) raise ArgumentError, "register_action expects an action model, "\ "got #{action_model.class} instead" end # Copy is performed to avoid changing the original models and # really only share the action to another interface action_model = action_model.to_action_model.dup register_action!(name, action_model) action_model end |
#register_action!(name, action_model) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Internal, no-check version of #register_action
If no specific return type has been specified, one is created automatically and registered as a constant on this action interface. For instance, the start_all_devices action would create a simple StartAllDevices task model.
124 125 126 127 128 129 |
# File 'lib/roby/actions/models/interface_base.rb', line 124 def register_action!(name, action_model) name = name.to_s create_default_action_return_type(name, action_model) action_model.name = name actions[action_model.name] = action_model end |
#register_added_method_as_action(method_name, description) ⇒ Object
Register an existing instance method as action
166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/roby/actions/models/interface_base.rb', line 166 def register_added_method_as_action(method_name, description) name = method_name.to_s action_m = MethodAction.new(self, description) if (existing = find_action_by_name(name)) if action_m.returned_type == Roby::Task action_m.returns(existing.returned_type) end action_m.overloads(existing) end added_method_action_check_arity(name, action_m) register_action!(name, action_m) end |
#registered_action ⇒ Hash<String,Models::Action>
The set of actions defined on this interface
27 |
# File 'lib/roby/actions/models/interface_base.rb', line 27 inherited_attribute(:registered_action, :actions, map: true) { {} } |
#require_current_description ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Verifies that #describe was called to describe an action that is now being defined, and returns it
The current description is nil after this call
237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/roby/actions/models/interface_base.rb', line 237 def require_current_description action_model = @current_description @current_description = nil unless action_model raise ArgumentError, "you must describe the action with #describe "\ "before calling #action_coordination" end action_model end |
#respond_to_missing?(name, include_private) ⇒ Boolean
354 355 356 |
# File 'lib/roby/actions/models/interface_base.rb', line 354 def respond_to_missing?(name, include_private) find_action_by_name(name.to_s) || super end |
#state_machine(name, &block) ⇒ Object
use #action_state_machine instead
335 336 337 |
# File 'lib/roby/actions/models/interface_base.rb', line 335 def state_machine(name, &block) action_state_machine(name, &block) end |
#use_fault_response_table(table_model, arguments = {}) ⇒ Object
Declare that this fault response table should be used on all plans that are going to use this action interface
376 377 378 379 |
# File 'lib/roby/actions/models/interface_base.rb', line 376 def use_fault_response_table(table_model, arguments = {}) table_model.validate_arguments(arguments) fault_response_tables << [table_model, arguments] end |
#use_library(library) ⇒ void
This method returns an undefined value.
Adds all actions defined in another action interface or in an action library in this interface
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/roby/actions/models/interface_base.rb', line 43 def use_library(library) if library <= Actions::Interface library.each_registered_action do |name, action| actions[name] ||= action end library.each_fault_response_table do |table| use_fault_response_table table end else include library end end |