Class: Roby::TaskStateMachine
- Defined in:
- lib/roby/coordination/task_state_machine.rb
Overview
The state machine that can be associate with a task
Instance Attribute Summary collapse
-
#machine ⇒ Object
Underlying state machine.
-
#proxy ⇒ Object
The proxy object class the state machine is working on.
-
#states ⇒ Object
readonly
All state of the state machine.
-
#transitions ⇒ Object
readonly
Existing transitions Transition comes with methods: event, from_name, to_name.
Instance Method Summary collapse
-
#do_poll(task) ⇒ Object
Define general poll handler.
-
#identify_state(event_list) ⇒ Object
Identifies the current state given a list of subsequent events Provides a list with the most recent event being last in the list.
-
#initialize(machine) ⇒ TaskStateMachine
constructor
A new instance of TaskStateMachine.
- #initialize_copy(other) ⇒ Object
- #method_missing(m, *args, &block) ⇒ Object
- #respond_to_missing?(m, include_private) ⇒ Boolean
- #update ⇒ Object
Constructor Details
#initialize(machine) ⇒ TaskStateMachine
Returns a new instance of TaskStateMachine.
67 68 69 70 71 72 73 74 75 |
# File 'lib/roby/coordination/task_state_machine.rb', line 67 def initialize(machine) # Required to initialize underlying state_machine super() @proxy = machine.owner_class.new @machine = machine update end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &block) ⇒ Object
110 111 112 113 114 115 116 117 118 |
# File 'lib/roby/coordination/task_state_machine.rb', line 110 def method_missing(m, *args, &block) # If proxy provides missing method, then use the proxy if proxy.respond_to?(m) proxy.public_send(m, *args, &block) else # otherwise pass it on super end end |
Instance Attribute Details
#machine ⇒ Object
Underlying state machine
58 59 60 |
# File 'lib/roby/coordination/task_state_machine.rb', line 58 def machine @machine end |
#proxy ⇒ Object
The proxy object class the state machine is working on
55 56 57 |
# File 'lib/roby/coordination/task_state_machine.rb', line 55 def proxy @proxy end |
#states ⇒ Object (readonly)
All state of the state machine
65 66 67 |
# File 'lib/roby/coordination/task_state_machine.rb', line 65 def states @states end |
#transitions ⇒ Object (readonly)
Existing transitions Transition comes with methods: event, from_name, to_name
62 63 64 |
# File 'lib/roby/coordination/task_state_machine.rb', line 62 def transitions @transitions end |
Instance Method Details
#do_poll(task) ⇒ Object
Define general poll handler
121 122 123 124 125 126 127 |
# File 'lib/roby/coordination/task_state_machine.rb', line 121 def do_poll(task) begin proxy.poll(task) rescue NoMethodError => e # poll only if the state has a poll handler defined end end |
#identify_state(event_list) ⇒ Object
Identifies the current state given a list of subsequent events Provides a list with the most recent event being last in the list
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/roby/coordination/task_state_machine.rb', line 132 def identify_state(event_list) # initalize with all transitions possible paths = {} @transitions.each do |transition| paths[transition] = [] end paths = [] new_paths = [] initialized = false until event_list.empty? current_event = event_list.first # expand path @transitions.each do |transition| # Get transitions that match event if current_event == transition.event # expand first set of transactions if !initialized new_paths << [transition] else # find transitions that lead to the last transition paths.each do |path| if path.last.from_name == transition.to_name path << transition new_paths << path end end end end end paths = new_paths new_paths = [] initialized = true event_list.delete_at(0) end if paths.size == 1 # Retrieve last (by time) transitions target state return paths[0].last.to_name elsif !paths.empty? raise "event list is ambiguous, requiring more events" end raise "event list is invalid" end |
#initialize_copy(other) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/roby/coordination/task_state_machine.rb', line 99 def initialize_copy(other) other.name = name other.proxy = name.new other.machine = machine.dup other.update end |
#respond_to_missing?(m, include_private) ⇒ Boolean
106 107 108 |
# File 'lib/roby/coordination/task_state_machine.rb', line 106 def respond_to_missing?(m, include_private) proxy.respond_to?(m) || super end |
#update ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/roby/coordination/task_state_machine.rb', line 77 def update @states = [] # introspect to retrieve all transactions of the statemachine @transitions = [] collection = @machine.states collection.each do |s_o| collection.each do |s_i| # status_transitions is added to TaskStateMachine using meta programming transitions = proxy.status_transitions(from: s_o.name.to_sym, to: s_i.name.to_sym) @transitions << transitions end @transitions.flatten! end # Infer all available states from existing transitions @transitions.each do |t| @states << t.from_name unless @states.index(t.from_name) @states << t.to_name unless @states.index(t.to_name) end end |