def trigger!(event_name, *data, &block)
      from = current # Save away current state

      sync_exclusive do
        notify HookEvent::Before, event_name, from, *data

        status = try_trigger(event_name) do
          if can?(event_name, *data)
            notify HookEvent::Exit, event_name, from, *data

            stat = transition!(event_name, *data, &block)

            notify HookEvent::Transition, event_name, from, *data
            notify HookEvent::Enter, event_name, from, *data
          else
            stat = false
          end
          stat
        end

        notify HookEvent::After, event_name, from, *data

        status
      end
    rescue Exception => err
      self.state = from # rollback transition
      raise err
    end
def trigger!(event_name, *data, &block)
      from = current # Save away current state

      sync_exclusive do
        notify HookEvent::Before, event_name, from, *data

        status = try_trigger(event_name) do
          if can?(event_name, *data)
            notify HookEvent::Exit, event_name, from, *data

            stat = transition!(event_name, *data, &block)

            notify HookEvent::Transition, event_name, from, *data
            notify HookEvent::Enter, event_name, from, *data
          else
            stat = false
          end
          stat
        end

        notify HookEvent::After, event_name, from, *data

        status
      end
    rescue Exception => err
      self.state = from # rollback transition
      raise err
    end
Trigger transition event with data

 @param [Symbol] event_name
   the event name
 @param [Array] data

 @return [Boolean]
   true when transition is successful, false otherwise

 @api public