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;fp=bundles%2Forg.simantics.simulation.sequences%2Fsrc%2Forg%2Fsimantics%2Fsimulation%2Fsequences%2Faction%2FAbstractActionContext.java;h=4fabd2243c98dedea07bb50de9dd9ac6b099270c;hp=4cba91d066e900a3c58f4c33fd4521960a5de5e1;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 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 4cba91d06..4fabd2243 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 @@ -1,115 +1,115 @@ -package org.simantics.simulation.sequences.action; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.PriorityQueue; - -import org.simantics.scl.runtime.SCLContext; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.scl.runtime.tuple.Tuple0; - -public abstract class AbstractActionContext implements ActionContext { - public static final double TIME_TOLERANCE = 1e-6; - - double currentTime; - volatile boolean stopped; - ArrayList> scheduledNow = new ArrayList>(); - ArrayList> scheduledNextStep = new ArrayList>(); - PriorityQueue scheduledAt = new PriorityQueue(); - - public List exceptions; - - private static class Task implements Comparable { - final double time; - final Function1 continuation; - - public Task(double time, Function1 continuation) { - this.time = time; - this.continuation = continuation; - } - - @Override - public int compareTo(Task o) { - return Double.compare(time, o.time); - } - } - - @Override - public double time() { - return currentTime; - } - - @Override - public void scheduleNow(Function1 continuation) { - scheduledNow.add(continuation); - } - - @Override - public void scheduleNextStep(Function1 continuation) { - scheduledNextStep.add(continuation); - } - - @Override - public void scheduleAt(double time, Function1 continuation) { - if(time <= currentTime) - scheduleNow(continuation); - else - scheduledAt.add(new Task(time, continuation)); - } - - @Override - public void stop() { - stopped = true; - } - - public boolean isStopped() { - synchronized (this) { - return stopped || (scheduledNextStep.isEmpty() && scheduledAt.isEmpty()); - } - } - - public double handleStep(double currentTime) { - synchronized (this) { - this.currentTime = currentTime; - { - ArrayList> temp = scheduledNow; - scheduledNow = scheduledNextStep; - scheduledNextStep = temp; - Collections.reverse(scheduledNow); - } - - SCLContext context = SCLContext.getCurrent(); - Object oldActionContext = context.put("sequenceAction", this); - try { - Task firstTask = scheduledAt.peek(); - while(true) { - while(!scheduledNow.isEmpty()) { - try { - Function1 currentContinuation = scheduledNow.remove(scheduledNow.size()-1); - currentContinuation.apply(Tuple0.INSTANCE); - currentContinuation = null; - } catch (Exception e) { - if (this.exceptions == null) - this.exceptions = new ArrayList(); - this.exceptions.add(new RuntimeException("Action failure at " + currentTime + ": " + e.getMessage(), e)); - } - } - if(firstTask == null) - return Double.POSITIVE_INFINITY; - else if(firstTask.time > currentTime+TIME_TOLERANCE) - return firstTask.time; - else { - firstTask.continuation.apply(Tuple0.INSTANCE); - synchronized (this) { - scheduledAt.remove(); - } - firstTask = scheduledAt.peek(); - } - } - } finally { - context.put("sequenceAction", oldActionContext); - } - } - } -} +package org.simantics.simulation.sequences.action; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; + +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.tuple.Tuple0; + +public abstract class AbstractActionContext implements ActionContext { + public static final double TIME_TOLERANCE = 1e-6; + + double currentTime; + volatile boolean stopped; + ArrayList> scheduledNow = new ArrayList>(); + ArrayList> scheduledNextStep = new ArrayList>(); + PriorityQueue scheduledAt = new PriorityQueue(); + + public List exceptions; + + private static class Task implements Comparable { + final double time; + final Function1 continuation; + + public Task(double time, Function1 continuation) { + this.time = time; + this.continuation = continuation; + } + + @Override + public int compareTo(Task o) { + return Double.compare(time, o.time); + } + } + + @Override + public double time() { + return currentTime; + } + + @Override + public void scheduleNow(Function1 continuation) { + scheduledNow.add(continuation); + } + + @Override + public void scheduleNextStep(Function1 continuation) { + scheduledNextStep.add(continuation); + } + + @Override + public void scheduleAt(double time, Function1 continuation) { + if(time <= currentTime) + scheduleNow(continuation); + else + scheduledAt.add(new Task(time, continuation)); + } + + @Override + public void stop() { + stopped = true; + } + + public boolean isStopped() { + synchronized (this) { + return stopped || (scheduledNextStep.isEmpty() && scheduledAt.isEmpty()); + } + } + + public double handleStep(double currentTime) { + synchronized (this) { + this.currentTime = currentTime; + { + ArrayList> temp = scheduledNow; + scheduledNow = scheduledNextStep; + scheduledNextStep = temp; + Collections.reverse(scheduledNow); + } + + SCLContext context = SCLContext.getCurrent(); + Object oldActionContext = context.put("sequenceAction", this); + try { + Task firstTask = scheduledAt.peek(); + while(true) { + while(!scheduledNow.isEmpty()) { + try { + Function1 currentContinuation = scheduledNow.remove(scheduledNow.size()-1); + currentContinuation.apply(Tuple0.INSTANCE); + currentContinuation = null; + } catch (Exception e) { + if (this.exceptions == null) + this.exceptions = new ArrayList(); + this.exceptions.add(new RuntimeException("Action failure at " + currentTime + ": " + e.getMessage(), e)); + } + } + if(firstTask == null) + return Double.POSITIVE_INFINITY; + else if(firstTask.time > currentTime+TIME_TOLERANCE) + return firstTask.time; + else { + firstTask.continuation.apply(Tuple0.INSTANCE); + synchronized (this) { + scheduledAt.remove(); + } + firstTask = scheduledAt.peek(); + } + } + } finally { + context.put("sequenceAction", oldActionContext); + } + } + } +}