diff --git a/src/api b/src/api index bbbea878f..3efd012ae 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit bbbea878fe30ea033112b0c5f1604417d4197447 +Subproject commit 3efd012ae0c465ff39ccfa85986ea966cc1bfa26 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 9bf4e745e..6b2eb6336 100644 --- a/src/main/java/noppes/npcs/controllers/data/action/Action.java +++ b/src/main/java/noppes/npcs/controllers/data/action/Action.java @@ -16,8 +16,10 @@ public class Action implements IAction { protected int maxDuration = -1; protected int updateEveryXTick = 5; protected Consumer task; - private boolean done; - private final Map dataStore = new HashMap<>(); + protected boolean done; + protected final Map dataStore = new HashMap<>(); + protected boolean isThreaded; + protected ActionThread threaded; public Action(ScriptedActionManager manager, String name) { this.manager = manager; @@ -68,13 +70,17 @@ public class Action implements IAction { return; } if (ticksExisted % updateEveryXTick == 0 && task != null) { - try { - task.accept(this); - count++; - } catch (Throwable t) { - System.err.println("Scripted action '" + name + "' threw an exception:"); - t.printStackTrace(); - markDone(); + if (isThreaded) + threaded.run(); + else { + try { + task.accept(this); + count++; + } catch (Throwable t) { + System.err.println("Scripted action '" + name + "' threw an exception:"); + t.printStackTrace(); + markDone(); + } } } duration++; @@ -161,10 +167,34 @@ public class Action implements IAction { @Override public IAction pauseFor(int ticks) { + if (isThreaded) + return threaded.pauseFor(ticks); + this.startAfterTicks = ticks; return this; } + @Override + public IAction pauseFor(long millis) { + if (isThreaded) + return threaded.pauseFor(millis); + + return pauseFor((int) (millis / 50)); + } + + @Override + public boolean isPaused() { + if (isThreaded) + return threaded.isPaused(); + + return startAfterTicks > 0; + } + + @Override + public void threadify() { + isThreaded = true; + threaded = new ActionThread(this); + } @Override public IAction getNext() { boolean seenMe = false; diff --git a/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java b/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java new file mode 100644 index 000000000..c0009d940 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/action/ActionThread.java @@ -0,0 +1,71 @@ +package noppes.npcs.controllers.data.action; + +import noppes.npcs.api.handler.data.IAction; + +public class ActionThread { + private Action action; + private Thread thread; + private volatile boolean threadPaused; + private boolean threadRunning; + + public ActionThread(Action action) { + this.action = action; + createThread(); + } + + private void createThread() { + thread = new Thread(() -> { + threadRunning = true; + action.task.accept(action); + threadRunning = false; + action.count++; + }); + } + + public IAction pauseFor(long millis) { + if (Thread.currentThread() == thread) { + try { + threadPaused = true; + Thread.sleep(millis); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + threadPaused = false; + return action; + } + } else + return 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; + } + } else + return action.pauseFor(ticks); + } + + public boolean isPaused() { + return threadPaused; + } + + public void run() { + if (threadRunning) + return; + + try { + thread.start(); + } catch (Throwable t) { + System.err.println("Scripted threaded action '" + action.name + "' threw an exception:"); + t.printStackTrace(); + action.markDone(); + } + } +}