Ejemplo n.º 1
0
  /**
   * Sets this actor as the event {@link Event#setTarget(Actor) target} and propagates the event to
   * this actor and ancestor actors as necessary. If this actor is not in the stage, the stage must
   * be set before calling this method.
   *
   * <p>Events are fired in 2 phases. The first phase notifies listeners on each actor starting at
   * the root and propagating downward to (and including) this actor. The second phase notifes
   * listeners on each actor starting at this actor and, if {@link Event#getBubbles()} is true,
   * propagating upward to the root. If the event is {@link Event#stop() stopped} at any time, it
   * will not propagate to the next actor.
   *
   * @return true of the event was {@link Event#cancel() cancelled}.
   */
  public boolean fire(Event event) {
    if (event.getStage() == null) event.setStage(getStage());
    event.setTarget(this);

    // Collect ancestors so event propagation is unaffected by hierarchy changes.
    Array<Group> ancestors = Pools.obtain(Array.class);
    Group parent = getParent();
    while (parent != null) {
      ancestors.add(parent);
      parent = parent.getParent();
    }

    try {
      // Notify all parent capture listeners, starting at the root. Ancestors may stop an event
      // before children receive it.
      for (int i = ancestors.size - 1; i >= 0; i--) {
        Group currentTarget = ancestors.get(i);
        currentTarget.notify(event, true);
        if (event.isStopped()) return event.isCancelled();
      }

      // Notify the target capture listeners.
      notify(event, true);
      if (event.isStopped()) return event.isCancelled();

      // Notify the target listeners.
      notify(event, false);
      if (!event.getBubbles()) return event.isCancelled();
      if (event.isStopped()) return event.isCancelled();

      // Notify all parent listeners, starting at the target. Children may stop an event before
      // ancestors receive it.
      for (int i = 0, n = ancestors.size; i < n; i++) {
        ancestors.get(i).notify(event, false);
        if (event.isStopped()) return event.isCancelled();
      }

      return event.isCancelled();
    } finally {
      ancestors.clear();
      Pools.free(ancestors);
    }
  }