lib/statemachine/transition.rb in MINT-statemachine-1.2.3 vs lib/statemachine/transition.rb in MINT-statemachine-1.3.0
- old
+ new
@@ -11,36 +11,77 @@
@event = event
@action = action
@cond = cond
end
+ def is_self_transition?
+ @origin_id == @destination_id
+ end
+
def invoke(origin, statemachine, args)
+ old_abstract_states = statemachine.abstract_states
+ old_atomic_states = statemachine.states_id
+
destination = statemachine.get_state(@destination_id)
exits, entries = exits_and_entries(origin, destination)
exits.each { |exited_state| exited_state.exit(args) }
messenger = origin.statemachine.messenger
message_queue = origin.statemachine.message_queue
- if @action # changed this if statement to return if action fails
+ if @action # changed this if statement to return if action fails
if not origin.statemachine.invoke_action(@action, args, "transition action from #{origin} invoked by '#{@event}' event", messenger, message_queue)
raise StatemachineException.new("Transition to state #{destination.id} failed because action for event #{@event} return false.")
end
end
# origin.statemachine.invoke_action(@action, args, "transition action from #{origin} invoked by '#{@event}' event", messenger, message_queue) if @action
terminal_state = entries.last
- terminal_state.activate if terminal_state and not terminal_state.is_parallel
+ terminal_state.activate if terminal_state and not terminal_state.is_parallel
entries.each { |entered_state| entered_state.enter(args) }
- entries.each { |entered_state| entered_state.activate(terminal_state.id) if entered_state.is_parallel }
+#entries.each { |entered_state| entered_state.activate(terminal_state.id) if entered_state.is_parallel }
statemachine.state = terminal_state if statemachine.has_state(terminal_state.id) and statemachine.is_parallel
+ if is_self_transition? # handle special case of self transition
+ new_states = [@destination_id]
+ else
+ new_states = statemachine.states_id - (old_atomic_states & statemachine.states_id)
+ new_states = (statemachine.abstract_states - old_abstract_states) + new_states
+ end
+
+ if statemachine.activation
+ sm = statemachine
+ while (sm.is_parallel)
+ sm = sm.is_parallel.statemachine
+ end
+ sm.activation.call(new_states,sm.abstract_states,sm.states_id) if sm.activation # and not @statemachine.is_parallel
+ end
+
+ # Take any valid spontaneous transitions
+ transition = destination.spontaneous_transition
+
+ if transition
+ if destination.is_parallel
+ transition.each do |trans,statem|
+ trans.each do |t|
+ t[0].invoke(t[1], statem, args) if t[0].is_a? Transition
+ end
+ end
+ else
+
+ if transition.is_a? Array
+ transition.each do |t|
+ t[0].invoke(t[1], statemachine, args) if t[0].is_a? Transition
+ end
+ end
+ end
+ end
end
def exits_and_entries(origin, destination)
- # return [], [] if origin == destination
+ # return [], [] if origin == destination
exits = []
entries = exits_and_entries_helper(exits, origin, destination)
return exits, entries.reverse
end
\ No newline at end of file