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