X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.simulation.sequences%2Fsrc%2Forg%2Fsimantics%2Fsimulation%2Fsequences%2Faction%2FAbstractActionContext.java;h=2adb9a045cf8a06fb525124b1a109b73f2163559;hp=4fabd2243c98dedea07bb50de9dd9ac6b099270c;hb=8d1b4f05e2b2302ad9dabc74f54bd45997ab3a4b;hpb=f37ba060464d2230f86c6786572d33026800eedc diff --git a/bundles/org.simantics.simulation.sequences/src/org/simantics/simulation/sequences/action/AbstractActionContext.java b/bundles/org.simantics.simulation.sequences/src/org/simantics/simulation/sequences/action/AbstractActionContext.java index 4fabd2243..2adb9a045 100644 --- a/bundles/org.simantics.simulation.sequences/src/org/simantics/simulation/sequences/action/AbstractActionContext.java +++ b/bundles/org.simantics.simulation.sequences/src/org/simantics/simulation/sequences/action/AbstractActionContext.java @@ -14,9 +14,10 @@ public abstract class AbstractActionContext implements ActionContext { double currentTime; volatile boolean stopped; - ArrayList> scheduledNow = new ArrayList>(); - ArrayList> scheduledNextStep = new ArrayList>(); - PriorityQueue scheduledAt = new PriorityQueue(); + ArrayList> scheduledNow = new ArrayList<>(); + ArrayList> scheduledNextStep = new ArrayList<>(); + ArrayList> scheduledWhenStopped = new ArrayList<>(); + PriorityQueue scheduledAt = new PriorityQueue<>(); public List exceptions; @@ -57,12 +58,22 @@ public abstract class AbstractActionContext implements ActionContext { else scheduledAt.add(new Task(time, continuation)); } - + + @Override + public void scheduleWhenStopped(Function1 continuation) { + scheduledWhenStopped.add(continuation); + } + @Override public void stop() { + stop(StopReason.STOPPED); + } + + public void stop(StopReason reason) { stopped = true; + handleStop(reason); } - + public boolean isStopped() { synchronized (this) { return stopped || (scheduledNextStep.isEmpty() && scheduledAt.isEmpty()); @@ -91,7 +102,7 @@ public abstract class AbstractActionContext implements ActionContext { currentContinuation = null; } catch (Exception e) { if (this.exceptions == null) - this.exceptions = new ArrayList(); + this.exceptions = new ArrayList<>(); this.exceptions.add(new RuntimeException("Action failure at " + currentTime + ": " + e.getMessage(), e)); } } @@ -112,4 +123,27 @@ public abstract class AbstractActionContext implements ActionContext { } } } + + private void handleStop(StopReason reason) { + synchronized (this) { + List> stopFunctions = new ArrayList<>(scheduledWhenStopped); + scheduledWhenStopped.clear(); + + SCLContext context = SCLContext.getCurrent(); + Object oldActionContext = context.put("sequenceAction", this); + try { + stopFunctions.forEach(f -> { + try { + f.apply(reason); + } catch (Exception e) { + if (this.exceptions == null) + this.exceptions = new ArrayList<>(); + this.exceptions.add(new RuntimeException("Stop action failure at " + currentTime + ": " + e.getMessage(), e)); + } + }); + } finally { + context.put("sequenceAction", oldActionContext); + } + } + } }