From 70cc7b75e48a1931d8f4d6bbfe847707ac530d3e Mon Sep 17 00:00:00 2001 From: bigguy345 Date: Sat, 28 Jun 2025 19:07:19 +0300 Subject: [PATCH] More important ActionThread pausing frameworks and documentation --- .../npcs/controllers/data/action/Action.java | 45 ++++++++-- .../controllers/data/action/ActionThread.java | 82 +++++++++++++------ 2 files changed, 97 insertions(+), 30 deletions(-) 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 6b2eb6336..f61ddb6cd 100644 --- a/src/main/java/noppes/npcs/controllers/data/action/Action.java +++ b/src/main/java/noppes/npcs/controllers/data/action/Action.java @@ -1,11 +1,13 @@ package noppes.npcs.controllers.data.action; import noppes.npcs.api.handler.data.IAction; +import noppes.npcs.scripted.CustomNPCsException; import noppes.npcs.scripted.ScriptedActionManager; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Supplier; public class Action implements IAction { protected final ScriptedActionManager manager; @@ -168,20 +170,45 @@ public class Action implements IAction { @Override public IAction pauseFor(int ticks) { if (isThreaded) - return threaded.pauseFor(ticks); + threaded.pauseFor(ticks); + else + this.startAfterTicks = ticks; - this.startAfterTicks = ticks; return this; } @Override public IAction pauseFor(long millis) { - if (isThreaded) - return threaded.pauseFor(millis); + if (isThreaded) { + threaded.pauseFor(millis); + return this; + } return pauseFor((int) (millis / 50)); } + @Override + public void pause() { + if (isThreaded) + threaded.pause(); + else + throw new CustomNPCsException("Must threadify() IAction before pausing!"); + } + + @Override + public void pauseUntil(Supplier until) { + if (isThreaded) + threaded.pauseUntil(until); + else + throw new CustomNPCsException("Must threadify() IAction before pausing!"); + } + + @Override + public void resume() { + if (isThreaded) + threaded.resume(); + } + @Override public boolean isPaused() { if (isThreaded) @@ -191,9 +218,13 @@ public class Action implements IAction { } @Override - public void threadify() { - isThreaded = true; - threaded = new ActionThread(this); + public IAction threadify() { + if (!isThreaded) { + isThreaded = true; + threaded = new ActionThread(this); + } + + return this; } @Override public IAction getNext() { diff --git a/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java b/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java index c0009d940..6effa1310 100644 --- a/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java +++ b/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java @@ -1,13 +1,17 @@ package noppes.npcs.controllers.data.action; -import noppes.npcs.api.handler.data.IAction; +import java.util.function.Supplier; public class ActionThread { - private Action action; + private final Action action; + + private final Object lock = new Object(); private Thread thread; - private volatile boolean threadPaused; + private volatile boolean threadPaused, threadSleeping; private boolean threadRunning; + private Supplier pauseUntil; + public ActionThread(Action action) { this.action = action; createThread(); @@ -22,41 +26,73 @@ public class ActionThread { }); } - public IAction pauseFor(long millis) { - if (Thread.currentThread() == thread) { + + public void pauseFor(long millis) { + if (isPaused()) + return; + + if (inActionThread()) { try { - threadPaused = true; + threadSleeping = true; Thread.sleep(millis); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { - threadPaused = false; - return action; + threadSleeping = false; } } else - return action.pauseFor((int) (millis / 50)); + action.pauseFor((int) (millis / 50)); } - public IAction pauseFor(int ticks) { - if (Thread.currentThread() == thread) { - try { - threadPaused = true; - Thread.sleep(ticks * 50); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - threadPaused = false; - return action; + public void pauseFor(int ticks) { + pauseFor(ticks * 50L); + } + + public void pause() { + if (!inActionThread() || isPaused()) + return; + + threadPaused = true; + synchronized (lock) { + while (threadPaused) { + try { + lock.wait(); // Wait until notified + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } - } else - return action.pauseFor(ticks); + } + } + + public void pauseUntil(Supplier until) { + this.pauseUntil = until; + pause(); + } + + public void resume() { + synchronized (lock) { + if (threadPaused) { + threadPaused = false; + lock.notify(); + } + + if (threadSleeping) + thread.interrupt(); + } } public boolean isPaused() { - return threadPaused; + return threadPaused || threadSleeping; } - public void run() { + public boolean inActionThread() { + return Thread.currentThread() == thread; + } + + protected void run() { + if (threadPaused && pauseUntil != null && pauseUntil.get()) + resume(); + if (threadRunning) return;