import java.awt.event.WindowEvent;
import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JProgressBar;
import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.gui.dialogs.DetailDialog;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
import net.sf.openrocket.simulation.FlightEvent;
import net.sf.openrocket.simulation.SimulationStatus;
+import net.sf.openrocket.simulation.customexpression.CustomExpression;
+import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
private static final double APOGEE_PROGRESS = 0.7;
- private final static ExecutorService executor = Executors.newFixedThreadPool(
- SwingPreferences.getMaxThreadCount());
+ /**
+ * A single ThreadPoolExecutor that will be used for all simulations.
+ * This executor must not be shut down.
+ */
+ private static final ThreadPoolExecutor executor;
+ static {
+ int n = SwingPreferences.getMaxThreadCount();
+ executor = new ThreadPoolExecutor(n, n,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new ThreadFactory() {
+ private ThreadFactory factory = Executors.defaultThreadFactory();
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = factory.newThread(r);
+ t.setDaemon(true);
+ return t;
+ }
+ });
+ }
+
private final JLabel simLabel, timeLabel, altLabel, velLabel;
* will result in an exception being thrown!
*/
private final Simulation[] simulations;
+ private final OpenRocketDocument document;
private final String[] simulationNames;
private final SimulationWorker[] simulationWorkers;
private final SimulationStatus[] simulationStatuses;
private final double[] simulationMaxVelocity;
private final boolean[] simulationDone;
- public SimulationRunDialog(Window window, Simulation... simulations) {
+ public SimulationRunDialog(Window window, OpenRocketDocument document, Simulation... simulations) {
//// Running simulations...
super(window, trans.get("SimuRunDlg.title.RunSim"), Dialog.ModalityType.APPLICATION_MODAL);
+ this.document = document;
if (simulations.length == 0) {
throw new IllegalArgumentException("Called with no simulations to run");
for (int i = 0; i < n; i++) {
simulationNames[i] = simulations[i].getName();
- simulationWorkers[i] = new InteractiveSimulationWorker(simulations[i], i);
+ simulationWorkers[i] = new InteractiveSimulationWorker(document, simulations[i], i);
executor.execute(simulationWorkers[i]);
}
* the Cancel button on the dialog.
*/
public void cancelSimulations() {
- executor.shutdownNow();
for (SimulationWorker w : simulationWorkers) {
w.cancel(true);
}
+ executor.purge();
}
* @param parent the parent Window of the dialog to use.
* @param simulations the simulations to run.
*/
- public static void runSimulations(Window parent, Simulation... simulations) {
- new SimulationRunDialog(parent, simulations).setVisible(true);
+ public static void runSimulations(Window parent, OpenRocketDocument document, Simulation... simulations) {
+ new SimulationRunDialog(parent, document, simulations).setVisible(true);
}
private volatile double burnoutVelocity;
private volatile double apogeeAltitude;
+ private final CustomExpressionSimulationListener exprListener;
+
/*
* -2 = time from 0 ... burnoutTimeEstimate
* -1 = velocity from v(burnoutTimeEstimate) ... 0
private int progress = 0;
- public InteractiveSimulationWorker(Simulation sim, int index) {
+ public InteractiveSimulationWorker(OpenRocketDocument doc, Simulation sim, int index) {
super(sim);
+ List<CustomExpression> exprs = doc.getCustomExpressions();
+ exprListener = new CustomExpressionSimulationListener(exprs);
this.index = index;
// Calculate estimate of motor burn time
*/
@Override
protected SimulationListener[] getExtraListeners() {
- return new SimulationListener[] { new SimulationProgressListener() };
+ return new SimulationListener[] { new SimulationProgressListener(), exprListener };
}