package com.asteria.game.character;
import java.util.Objects;
import java.util.Optional;
import com.asteria.game.World;
import com.asteria.task.EventListener;
/**
* The container class that holds the movement queue listener. The listener
* allows for various actions to be appended to the end of the movement queue,
* this is useful for things such as "walking to actions".
*
* @author lare96 <http://github.com/lare96>
*/
public final class MovementQueueListener {
/**
* The character this listener is dedicated to.
*/
private final CharacterNode character;
/**
* The listener being used to execute tasks.
*/
private Optional<MovementQueueListenerTask> listener = Optional.empty();
/**
* Creates a new {@link MovementQueueListener}.
*
* @param character
* the character this listener is dedicated to.
*/
public MovementQueueListener(CharacterNode character) {
this.character = character;
}
/**
* Resets this {@link EventListener} so it may listen for the walking queue
* to finish. Once the walking queue is finished the listener will run the
* logic within {@code task}.
* <p>
* <p>
* Please note that appended tasks are not guaranteed to be ran! If a new
* task is being appended while the listener is already waiting to run
* another task, the existing listener is stopped, the old task discarded,
* and a new listener is started to run the new task.
*
* @param task
* the task that will be ran once the walking queue is finished.
*/
public void append(Runnable task) {
listener.ifPresent(t -> t.cancel());
listener = Optional.of(new MovementQueueListenerTask(character, task));
character.setFollowing(false);
World.submit(listener.get());
}
/**
* The action listener implementation that allows for a task to be appended
* to the end of the movement queue.
*
* @author lare96 <http://github.com/lare96>
*/
private static final class MovementQueueListenerTask extends EventListener {
/**
* The character that the queued task will be ran for.
*/
private final CharacterNode character;
/**
* The queued task that will be executed by this listener.
*/
private final Runnable task;
/**
* Creates a new {@link MovementQueueListenerTask}.
*
* @param character
* the character that the queued task will be ran for.
* @param task
* the queued task that will be executed by this listener.
*/
public MovementQueueListenerTask(CharacterNode character, Runnable task) {
this.character = character;
this.task = Objects.requireNonNull(task);
}
@Override
public boolean canExecute() {
return character.getMovementQueue().isMovementDone();
}
@Override
public void run() {
if (character.isRegistered()) {
try {
task.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}