Module: Roby::Actions::Models::InterfaceBase
- Extended by:
- MetaRuby::Attributes
- Defined in:
- lib/roby/actions/models/interface_base.rb
Defined Under Namespace
Classes: ArgumentCountMismatch
Instance Method Summary collapse
-
#action_script(name, options = Hash.new) { ... } ⇒ Action, Coordination::Models::ActionScript
Defines an action from an Coordination::Models::ActionScript.
-
#action_state_machine(name) { ... } ⇒ Action, Coordination::Models::ActionStateMachine
Defines an action from an Coordination::Models::ActionStateMachine.
-
#clear_model ⇒ Object
Clears everything stored on this model.
- #create_and_register_coordination_action(name, coordination_class, action_model: require_current_description, &block) ⇒ Object
-
#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(m, *args) ⇒ 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 a new action on this model.
-
#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?(m, include_private) ⇒ Boolean
-
#state_machine(name, &block) ⇒ Object
deprecated
Deprecated.
use #action_state_machine instead
-
#use_fault_response_table(table_model, arguments = Hash.new) ⇒ 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(m, *args) ⇒ Action
Returns an action description if ‘m’ is the name of a known action
274 275 276 277 278 279 280 281 282 |
# File 'lib/roby/actions/models/interface_base.rb', line 274 def method_missing(m, *args) if model = find_action_by_name(m.to_s) if args.size > 1 raise ArgumentError, "expected zero or one argument, got #{args.size}" end return model.new(*args) end super end |
Instance Method Details
#action_script(name, options = Hash.new) { ... } ⇒ Action, Coordination::Models::ActionScript
Defines an action from an Coordination::Models::ActionScript
The action script model can later be retrieved using Action#coordination_model
263 264 265 |
# File 'lib/roby/actions/models/interface_base.rb', line 263 def action_script(name, = Hash.new, &block) create_and_register_coordination_action(name, Coordination::ActionScript, &block) end |
#action_state_machine(name) { ... } ⇒ Action, Coordination::Models::ActionStateMachine
Defines an action from an Coordination::Models::ActionStateMachine
The action state machine model can later be retrieved using Action#coordination_model
238 239 240 241 242 243 244 245 246 247 |
# File 'lib/roby/actions/models/interface_base.rb', line 238 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 |
#clear_model ⇒ Object
Clears everything stored on this model
64 65 66 67 |
# File 'lib/roby/actions/models/interface_base.rb', line 64 def clear_model super actions.clear end |
#create_and_register_coordination_action(name, coordination_class, action_model: require_current_description, &block) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/roby/actions/models/interface_base.rb', line 189 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 return action_model, coordination_model end |
#create_coordination_action(action_model, coordination_class, &block) ⇒ Object
Helper method for #action_state_machine and #action_script
221 222 223 224 225 |
# File 'lib/roby/actions/models/interface_base.rb', line 221 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) return action_model, coordination_model end |
#create_coordination_model(action_model, coordination_class, &block) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/roby/actions/models/interface_base.rb', line 204 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)
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/roby/actions/models/interface_base.rb', line 99 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 = self.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
74 75 76 77 78 79 |
# File 'lib/roby/actions/models/interface_base.rb', line 74 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
56 57 58 59 60 61 |
# File 'lib/roby/actions/models/interface_base.rb', line 56 def each_action return enum_for(:each_action) if !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
28 |
# File 'lib/roby/actions/models/interface_base.rb', line 28 inherited_attribute(:fault_response_table, :fault_response_tables) { Array.new } |
#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
153 154 155 |
# File 'lib/roby/actions/models/interface_base.rb', line 153 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
162 163 164 165 166 167 168 169 170 |
# File 'lib/roby/actions/models/interface_base.rb', line 162 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
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/roby/actions/models/interface_base.rb', line 117 def method_added(method_name) super if @current_description name = method_name.to_s description, @current_description = @current_description, nil description = MethodAction.new(self, description) if existing = find_action_by_name(name) if description.returned_type == Roby::Task description.returns(existing.returned_type) end description.overloads(existing) end expected_argument_count = if description.arguments.empty? then 0 else 1 end begin check_arity(instance_method(name), expected_argument_count) rescue ArgumentError => e 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 register_action(name, description) end 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
16 17 18 |
# File 'lib/roby/actions/models/interface_base.rb', line 16 def promote_registered_action(name, action) action end |
#register_action(name, action_model) ⇒ Object
Registers a new action on this model
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.
87 88 89 90 91 92 |
# File 'lib/roby/actions/models/interface_base.rb', line 87 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 |
#registered_action ⇒ Hash<String,Models::Action>
The set of actions defined on this interface
24 |
# File 'lib/roby/actions/models/interface_base.rb', line 24 inherited_attribute(:registered_action, :actions, map: true) { Hash.new } |
#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
180 181 182 183 184 185 186 187 |
# File 'lib/roby/actions/models/interface_base.rb', line 180 def require_current_description action_model, @current_description = @current_description, nil if action_model action_model else raise ArgumentError, "you must describe the action with #describe before calling #action_coordination" end end |
#respond_to_missing?(m, include_private) ⇒ Boolean
267 268 269 |
# File 'lib/roby/actions/models/interface_base.rb', line 267 def respond_to_missing?(m, include_private) find_action_by_name(m.to_s) || super end |
#state_machine(name, &block) ⇒ Object
use #action_state_machine instead
250 251 252 |
# File 'lib/roby/actions/models/interface_base.rb', line 250 def state_machine(name, &block) action_state_machine(name, &block) end |
#use_fault_response_table(table_model, arguments = Hash.new) ⇒ Object
Declare that this fault response table should be used on all plans that are going to use this action interface
286 287 288 289 |
# File 'lib/roby/actions/models/interface_base.rb', line 286 def use_fault_response_table(table_model, arguments = Hash.new) 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
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/roby/actions/models/interface_base.rb', line 40 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 |