class Roby::Coordination::ActionStateMachine
A state machine defined on action interfaces
In such state machine, each state is represented by the task returned by the corresponding action, and the transitions are events on these tasks
Constants
- StateInfo
Attributes
current_state[R]
The current state
Public Class Methods
new(root_task, arguments = Hash.new)
click to toggle source
Calls superclass method
# File lib/roby/coordination/action_state_machine.rb, line 21 def initialize(root_task, arguments = Hash.new) super(root_task, arguments) @task_info = resolve_state_info start_state = model.starting_state if arguments[:start_state] start_state = model.find_state_by_name(arguments[:start_state]) if !start_state raise ArgumentError, "The starting state #{arguments[:start_state]} is unkown, make sure its definied in the statemachine #{self}" end end model.each_capture do |capture, (in_state, captured_event)| if in_state == model.root captured_event = instance_for(model.root).find_event(captured_event.symbol) captured_event.resolve.once do |event| if root_task.running? resolved_captures[capture] = capture.filter(self, event) end end end end root_task.execute do if start_state instanciate_state(instance_for(start_state)) end end end
Public Instance Methods
dependency_options_for(toplevel, task, roles)
click to toggle source
Calls superclass method
# File lib/roby/coordination/action_state_machine.rb, line 70 def dependency_options_for(toplevel, task, roles) options = super options[:success] = task_info[toplevel].transitions.map do |source, _| source.symbol.emitted?.from_now if source.task == task end.compact options end
instanciate_state(state)
click to toggle source
# File lib/roby/coordination/action_state_machine.rb, line 78 def instanciate_state(state) begin start_task(state) rescue Models::Capture::Unbound => e raise e, "in the action state machine #{model} running on #{root_task} while starting #{state.name}, #{e.message}", e.backtrace end state_info = task_info[state] tasks, known_transitions, captures = state_info.required_tasks, state_info.transitions, state_info.captures transitioned = false captures.each do |capture, captured_event| captured_event.resolve.once do |event| if !transitioned && root_task.running? resolved_captures[capture] = capture.filter(self, event) end end end known_transitions.each do |source_event, new_state| source_event.resolve.once do |event| if !transitioned && root_task.running? transitioned = true begin instanciate_state_transition(event.task, new_state) rescue Exception => e event.task.plan.add_error( ActionStateTransitionFailed.new(root_task, state, event, new_state, e) ) end end end end end
instanciate_state_transition(task, new_state)
click to toggle source
# File lib/roby/coordination/action_state_machine.rb, line 115 def instanciate_state_transition(task, new_state) remove_current_task begin instanciate_state(new_state) end run_hook :on_transition, task, new_state end
resolve_state_info()
click to toggle source
# File lib/roby/coordination/action_state_machine.rb, line 51 def resolve_state_info task_info.map_value do |task, task_info| task_info = StateInfo.new(task_info.required_tasks, task_info.forwards, Set.new, Hash.new) model.each_transition do |in_state, event, new_state| in_state = instance_for(in_state) if in_state == task task_info.transitions << [instance_for(event), instance_for(new_state)] end end model.each_capture do |capture, (in_state, event)| in_state = instance_for(in_state) if in_state == task task_info.captures[capture] = instance_for(event) end end task_info end end