Files
CustomNPC-Plus/src/main/java/noppes/npcs/controllers/data/action/ActionQueue.java
T

322 lines
7.8 KiB
Java
Raw Normal View History

2025-07-02 20:15:24 +03:00
package noppes.npcs.controllers.data.action;
2025-07-03 23:17:25 +03:00
import noppes.npcs.api.handler.IActionManager;
2025-07-02 20:15:24 +03:00
import noppes.npcs.api.handler.data.IAction;
2025-07-02 21:46:44 +03:00
import noppes.npcs.api.handler.data.IActionChain;
2025-07-02 20:15:24 +03:00
import noppes.npcs.api.handler.data.IActionQueue;
2025-07-02 21:46:44 +03:00
import noppes.npcs.controllers.data.action.chain.ActionChain;
2025-07-02 20:15:24 +03:00
import java.util.*;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Consumer;
public class ActionQueue implements IActionQueue {
protected final Deque<IAction> queue = new ConcurrentLinkedDeque<>();
protected final ActionManager manager;
protected final String name;
2025-07-03 18:07:18 +03:00
protected boolean isWorking = true;
protected boolean isParallel;
2025-07-03 18:07:18 +03:00
2025-07-05 10:19:11 +03:00
protected boolean isDead;
protected boolean killWhenEmpty;
2025-07-03 23:45:16 +03:00
protected int killWhenEmptyAfter = 100;
2025-07-02 20:15:24 +03:00
2025-07-05 10:19:11 +03:00
protected Action autoKill;
2025-07-03 18:07:18 +03:00
2025-07-02 20:15:24 +03:00
public ActionQueue(ActionManager manager, String name) {
this.manager = manager;
this.name = name;
}
public ActionQueue(ActionManager manager, String name, boolean isParallel) {
this(manager, name);
this.isParallel = isParallel;
}
2025-07-02 20:15:24 +03:00
@Override
public IActionQueue start() {
isWorking = true;
return this;
}
@Override
public IActionQueue stop() {
isWorking = false;
return this;
}
@Override
2025-07-03 23:17:25 +03:00
public IActionManager getManager() {
2025-07-02 20:15:24 +03:00
return manager;
}
@Override
public String getName() {
return name;
}
@Override
public Queue<IAction> getQueue() {
return queue;
}
2025-07-02 20:15:24 +03:00
@Override
public boolean isParallel() {
return isParallel;
}
@Override
public IActionQueue setParallel(boolean parallel) {
isParallel = parallel;
return this;
}
@Override
public boolean isKilledWhenEmpty() {
return killWhenEmpty;
}
2025-07-02 20:15:24 +03:00
@Override
2025-07-03 23:45:16 +03:00
public int getKillWhenEmptyAfter() {
return killWhenEmptyAfter;
2025-07-02 20:15:24 +03:00
}
@Override
public IActionQueue killWhenEmpty(boolean killWhenEmpty) {
this.killWhenEmpty = killWhenEmpty;
return this;
}
@Override
2025-07-03 23:45:16 +03:00
public IActionQueue killWhenEmptyAfter(int ticks) {
this.killWhenEmptyAfter = ticks;
return this;
}
2025-07-03 18:07:18 +03:00
@Override
2025-07-05 10:19:11 +03:00
public boolean isDead() {
return isDead;
2025-07-03 18:07:18 +03:00
}
@Override
public IActionQueue kill() {
2025-07-05 10:19:11 +03:00
this.isDead = true;
2025-07-03 18:07:18 +03:00
return this;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Schedulers
2025-07-02 20:15:24 +03:00
@Override
public IAction schedule(IAction action) {
Action act = (Action) action;
2025-07-03 18:07:18 +03:00
if (act.queue != this)
act.setQueue(this);
act.isScheduled = true;
if (!isParallel && act.unscheduledList != null) {
act.unscheduledList.scheduleAll(this).forEach((act1) -> act1.unscheduledList = null).kill();
return action;
}
2025-07-02 20:15:24 +03:00
queue.addLast(action);
return action;
}
@Override
public void schedule(IAction... actions) {
for (IAction act : actions)
schedule(act);
}
@Override
public IAction schedule(Consumer<IAction> task) {
return schedule(manager.create(task));
}
2025-07-02 20:15:24 +03:00
@Override
public void schedule(Consumer<IAction>... tasks) {
for (Consumer<IAction> task : tasks)
schedule(task);
}
@Override
public IAction schedule(int delay, Consumer<IAction> task) {
return schedule(manager.create(delay, task));
}
@Override
public IAction schedule(int maxDuration, int delay, Consumer<IAction> task) {
return schedule(manager.create(maxDuration, delay, task));
}
@Override
public IAction schedule(String name, Consumer<IAction> task) {
return schedule(manager.create(name, task));
}
@Override
public IAction schedule(String name, int delay, Consumer<IAction> task) {
return schedule(manager.create(name, delay, task));
}
@Override
public IAction schedule(String name, int maxDuration, int delay, Consumer<IAction> task) {
return schedule(manager.create(name, maxDuration, delay, task));
}
@Override
public IAction scheduleActionAt(int index, IAction action) {
int size = queue.size();
if (index <= 0) {
queue.addFirst(action);
} else if (index >= size) {
queue.addLast(action);
} else {
List<IAction> tmp = new ArrayList<>(queue);
tmp.add(index, action);
queue.clear();
queue.addAll(tmp);
}
((Action) action).queue = this;
2025-07-02 20:15:24 +03:00
((Action) action).isScheduled = true;
return action;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Queue Data
2025-07-03 18:07:18 +03:00
public boolean hasActiveTasks() {
return !queue.isEmpty();
}
2025-07-02 20:15:24 +03:00
@Override
public int getIndex(IAction action) {
int i = 0;
for (IAction a : queue) {
if (a.equals(action))
return i;
i++;
}
return -1;
}
@Override
public IAction getCurrentAction() {
return queue.peekFirst();
}
@Override
public boolean has(IAction action) {
return has(action.getName());
}
@Override
public boolean has(String actionName) {
for (IAction act : queue)
if (act.getName().equals(actionName))
return true;
return false;
}
@Override
public IAction get(String actionName) {
for (IAction action : queue) {
if (action.getName().equals(actionName))
return action;
}
return null;
}
@Override
public boolean cancel(IAction action) {
2025-07-03 18:07:18 +03:00
if (queue.remove(action)) {
action.kill();
return true;
}
return false;
2025-07-02 20:15:24 +03:00
}
@Override
public boolean cancel(String actionName) {
Iterator<IAction> acts = queue.iterator();
while (acts.hasNext()) {
IAction act = acts.next();
if (act.getName().equals(actionName)) {
act.kill();
acts.remove();
return true;
}
}
return false;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Handling
protected void tick() {
2025-07-05 10:19:11 +03:00
if (!isWorking || isDead)
2025-07-02 20:15:24 +03:00
return;
if (!isParallel) {
IAction current = getCurrentAction();
if (current instanceof Action) {
Action cab = (Action) current;
cab.tick();
2025-07-02 20:15:24 +03:00
if (cab.isDone()) {
cab.kill();
queue.pollFirst();
}
}
} else {
Iterator<IAction> pit = queue.iterator();
while (pit.hasNext()) {
Action a = (Action) pit.next();
a.tick();
2025-07-02 20:15:24 +03:00
if (a.isDone()) {
a.kill();
pit.remove();
}
}
}
2025-07-04 00:10:12 +03:00
killWhenEmpty();
2025-07-03 18:07:18 +03:00
}
protected void killWhenEmpty() {
2025-07-03 18:07:18 +03:00
if (killWhenEmpty && !hasActiveTasks() && autoKill == null)
2025-07-03 23:45:16 +03:00
autoKill = (Action) manager.create(killWhenEmptyAfter, (act) -> {
2025-07-03 18:07:18 +03:00
if (hasActiveTasks())
return;
manager.removeQueue(name);
2025-07-05 10:19:11 +03:00
}).everyTick().once();
2025-07-03 18:07:18 +03:00
if (autoKill != null) {
autoKill.tick();
2025-07-03 18:07:18 +03:00
if (autoKill.isDone())
autoKill = null;
}
2025-07-02 20:15:24 +03:00
}
@Override
public void clear() {
queue.forEach((act) -> act.kill());
queue.clear();
}
2025-07-02 21:46:44 +03:00
@Override
public IActionChain chain() {
return new ActionChain(manager, this, isParallel ? "parallel#" : "sequential#");
}
2025-07-02 20:15:24 +03:00
}