diff --git a/src/main/java/noppes/npcs/controllers/data/action/Action.java b/src/main/java/noppes/npcs/controllers/data/action/Action.java index 18c1f2de4..02ca835df 100644 --- a/src/main/java/noppes/npcs/controllers/data/action/Action.java +++ b/src/main/java/noppes/npcs/controllers/data/action/Action.java @@ -31,6 +31,9 @@ public class Action implements IAction { protected ActionThread actionThread; protected ScriptContainer reportTo; + //allows chaining .before() and .after() on unscheduled actions + protected ActionList unscheduledList; + public Action(ActionManager manager, String name) { this.manager = manager; this.name = name; @@ -337,61 +340,6 @@ public class Action implements IAction { /////////////////////////////////////////////////// // Sequential - protected Action unscheduledBefore, unscheduledAfter; - - protected LinkedList allUnscheduledBefore() { - Action before = unscheduledBefore; - - LinkedList befores = new LinkedList<>(); - while (before != null) { - befores.addFirst(before); - before = before.unscheduledBefore; - } - - return befores; - } - - protected void scheduleAllBefore(Deque deque) { - allUnscheduledBefore().forEach((bef) -> { - if (bef.unscheduledAfter != null) - bef.unscheduledAfter.unscheduledBefore = null; - bef.unscheduledAfter = null; - - deque.addLast(bef); - - if (bef.queue != queue) - bef.queue = queue; - - bef.isScheduled = true; - }); - } - - protected LinkedList allUnscheduledAfter() { - Action after = unscheduledAfter; - - LinkedList afters = new LinkedList<>(); - while (after != null) { - afters.add(after); - after = after.unscheduledAfter; - } - return afters; - } - - protected void scheduleAllAfter(Deque deque) { - allUnscheduledAfter().forEach((aft) -> { - if (aft.unscheduledBefore != null) - aft.unscheduledBefore.unscheduledAfter = null; - aft.unscheduledBefore = null; - - deque.addLast(aft); - - if (aft.queue != queue) - aft.queue = queue; - - aft.isScheduled = true; - }); - } - @Override public IAction getNext() { if (queue == null) @@ -429,12 +377,13 @@ public class Action implements IAction { return conditional((IConditionalAction) after); int idx = queue == null ? -1 : queue.getIndex(this); - if (idx >= 0) + if (idx >= 0 && !queue.isParallel()) queue.scheduleActionAt(idx + 1, after); else { - Action aft = (Action) after; - unscheduledAfter = aft; - aft.unscheduledBefore = this; + if (unscheduledList == null) + unscheduledList = new ActionList(this); + + unscheduledList.after(this, (Action) after); } return after; } @@ -486,12 +435,13 @@ public class Action implements IAction { return conditional((IConditionalAction) before); int idx = queue == null ? -1 : queue.getIndex(this); - if (idx >= 0) + if (idx >= 0 && !queue.isParallel()) queue.scheduleActionAt(Math.max(0, idx), before); else { - Action bef = (Action) before; - unscheduledBefore = bef; - bef.unscheduledAfter = this; + if (unscheduledList == null) + unscheduledList = new ActionList(this); + + unscheduledList.before(this, (Action) before); } return before; } @@ -528,6 +478,9 @@ public class Action implements IAction { @Override public IAction parallel(IAction act) { + if (unscheduledList != null) + ((Action) act).unscheduledList = unscheduledList; + if (queue != null && queue.isParallel() && queue != manager.conditionalQueue) return queue.schedule(act); @@ -576,6 +529,9 @@ public class Action implements IAction { @Override public IConditionalAction conditional(IConditionalAction after) { + if (unscheduledList != null) + ((Action) after).unscheduledList = unscheduledList; + return manager.schedule(after); } diff --git a/src/main/java/noppes/npcs/controllers/data/action/ActionList.java b/src/main/java/noppes/npcs/controllers/data/action/ActionList.java new file mode 100644 index 000000000..79ad8bcc0 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/action/ActionList.java @@ -0,0 +1,63 @@ +package noppes.npcs.controllers.data.action; + +import noppes.npcs.api.handler.data.IAction; +import noppes.npcs.api.handler.data.IActionQueue; + +import java.util.LinkedList; +import java.util.function.Consumer; + +public class ActionList { + + protected final LinkedList list = new LinkedList<>(); + protected final Action first; + protected IActionQueue originalQueue; + + public ActionList(Action action) { + list.addFirst(first = action); + originalQueue = action.getQueue(); + } + + public Action after(Action current, Action aft) { + int currentIndex = list.indexOf(current); + + if (currentIndex == -1) + list.addLast(aft); + else + list.add(currentIndex + 1, aft); + + aft.unscheduledList = this; + return aft; + } + + public Action before(Action current, Action bef) { + int currentIndex = list.indexOf(current); + + if (currentIndex == -1) + list.addLast(bef); + else + list.add(Math.max(0, currentIndex), bef); + + bef.unscheduledList = this; + return bef; + } + + public ActionList scheduleAll(IActionQueue queue) { + list.forEach(act -> { + queue.getQueue().add(act); + act.queue = queue; + act.isScheduled = true; + }); + + return this; + } + + public ActionList forEach(Consumer task) { + list.forEach(task); + return this; + } + + public ActionList kill() { + list.clear(); + return this; + } +} diff --git a/src/main/java/noppes/npcs/controllers/data/action/ActionQueue.java b/src/main/java/noppes/npcs/controllers/data/action/ActionQueue.java index a6fc2c054..d611a70fd 100644 --- a/src/main/java/noppes/npcs/controllers/data/action/ActionQueue.java +++ b/src/main/java/noppes/npcs/controllers/data/action/ActionQueue.java @@ -116,14 +116,13 @@ public class ActionQueue implements IActionQueue { act.isScheduled = true; - if (!isParallel && act.unscheduledBefore != null) - act.scheduleAllBefore(queue); + if (!isParallel && act.unscheduledList != null) { + act.unscheduledList.scheduleAll(this).forEach((act1) -> act1.unscheduledList = null).kill(); + return action; + } queue.addLast(action); - if (!isParallel && act.unscheduledAfter != null) - act.scheduleAllAfter(queue); - return action; } @@ -183,6 +182,7 @@ public class ActionQueue implements IActionQueue { queue.clear(); queue.addAll(tmp); } + ((Action) action).queue = this; ((Action) action).isScheduled = true; return action; }