All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.almasb.fxgl.entity.action.ActionComponent Maven / Gradle / Ivy

There is a newer version: 21.1
Show newest version
/*
 * FXGL - JavaFX Game Library. The MIT License (MIT).
 * Copyright (c) AlmasB ([email protected]).
 * See LICENSE for details.
 */

package com.almasb.fxgl.entity.action;

import com.almasb.fxgl.entity.component.Component;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 * Allows queueing new actions, querying and cancelling existing actions.
 *
 * @author Almas Baimagambetov ([email protected])
 */
public final class ActionComponent extends Component {

    private final Action IDLE = new IdleAction();

    private CancelPolicy cancelPolicy = CancelPolicy.ONE;

    /**
     * The head (if exists) of the queue is the current action.
     */
    private ObservableList actions = FXCollections.observableArrayList();

    private Action currentAction = IDLE;

    @Override
    public void onUpdate(double tpf) {
        if (currentAction != IDLE && currentAction.isCancelled()) {
            switch (cancelPolicy) {
                case ONE:
                    removeCurrentActionAndSetNext();
                    break;

                case ALL:
                    cancelActions();
                    break;
            }
        }

        if (currentAction.isComplete()) {
            currentAction.onCompleted();
            removeCurrentActionAndSetNext();
        }

        if (!currentAction.isCancelled()) {
            currentAction.onUpdate(tpf);
        }
    }

    @Override
    public void onRemoved() {
        cancelActions();
    }

    public CancelPolicy getCancelPolicy() {
        return cancelPolicy;
    }

    public void setCancelPolicy(CancelPolicy cancelPolicy) {
        this.cancelPolicy = cancelPolicy;
    }

    public ObservableList actionsProperty() {
        return FXCollections.unmodifiableObservableList(actions);
    }

    public Action getCurrentAction() {
        return currentAction;
    }

    /**
     * @return true when not performing any actions
     */
    public boolean isIdle() {
        return currentAction == IDLE;
    }

    /**
     * @return true if there are more actions (apart from Idle) in the queue
     */
    public boolean hasNextActions() {
        return !actions.isEmpty();
    }

    /**
     * Clears all running and pending actions.
     */
    public void cancelActions() {
        actions.forEach(Action::cancel);
        actions.clear();
        removeCurrentActionAndSetNext();
    }

    /**
     * Add an action to the queue for this entity to execute.
     * The action is notified that it was put in a queue.
     *
     * @param action next action to execute
     */
    public void addAction(Action action) {
        action.setEntity(entity);
        actions.add(action);
        action.onQueued();
    }

    /**
     * Removing an action also cancels it.
     *
     * @param action the action to remove
     */
    public void removeAction(Action action) {
        action.cancel();
        actions.remove(action);
    }

    /**
     * Remove current executing action.
     * If there are more actions pending, the first pending action becomes current.
     */
    private void removeCurrentActionAndSetNext() {
        if (!isIdle() && !actions.isEmpty()) {
            actions.remove(0);
        }

        currentAction = getNextAction();

        // check if the action is cancelled before it started
        if (!currentAction.isCancelled())
            currentAction.onStarted();
    }

    /**
     * @return next action in the queue or Idle if queue is empty
     */
    public Action getNextAction() {
        return hasNextActions() ? actions.get(0) : IDLE;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy