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.
66 67 68 69 70 71 72 73 74 |
# File 'lib/roby/coordination/task_state_machine.rb', line 66 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
109 110 111 112 113 114 115 116 117 |
# File 'lib/roby/coordination/task_state_machine.rb', line 109 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
57 58 59 |
# File 'lib/roby/coordination/task_state_machine.rb', line 57 def machine @machine end |
#proxy ⇒ Object
The proxy object class the state machine is working on
54 55 56 |
# File 'lib/roby/coordination/task_state_machine.rb', line 54 def proxy @proxy end |
#states ⇒ Object (readonly)
All state of the state machine
64 65 66 |
# File 'lib/roby/coordination/task_state_machine.rb', line 64 def states @states end |
#transitions ⇒ Object (readonly)
Existing transitions Transition comes with methods: event, from_name, to_name
61 62 63 |
# File 'lib/roby/coordination/task_state_machine.rb', line 61 def transitions @transitions end |
Instance Method Details
#do_poll(task) ⇒ Object
Define general poll handler
120 121 122 123 124 125 126 |
# File 'lib/roby/coordination/task_state_machine.rb', line 120 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
131 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 |
# File 'lib/roby/coordination/task_state_machine.rb', line 131 def identify_state(event_list) # initalize with all transitions possible paths = {} @transitions.each do |transition| paths[transition] = [] end paths = [] new_paths = [] initialized = false while event_list.size > 0 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 not 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.size > 0 throw "Event list is ambigious, requiring more events" end throw "Event list is invalid" end |
#initialize_copy(other) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/roby/coordination/task_state_machine.rb', line 98 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
105 106 107 |
# File 'lib/roby/coordination/task_state_machine.rb', line 105 def respond_to_missing?(m, include_private) proxy.respond_to?(m) || super end |
#update ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/roby/coordination/task_state_machine.rb', line 76 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 |