
com.almasb.fxgl.entity.action.ActionComponent Maven / Gradle / Ivy
/*
* 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;
}
@Override
public boolean isComponentInjectionRequired() {
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy