X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fmain%2FSimulationRunDialog.java;h=65fabb8fa36430ef8384c7a2dd5749ba0bc10e7c;hb=77f2457dc781c8c517ddef157c18491ad770f6c6;hp=c108030567921690797a37cf7f477ca796a417f0;hpb=8654c7d5a9d56274a296500d40c7f74229cdf6f1;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/gui/main/SimulationRunDialog.java b/core/src/net/sf/openrocket/gui/main/SimulationRunDialog.java index c1080305..65fabb8f 100644 --- a/core/src/net/sf/openrocket/gui/main/SimulationRunDialog.java +++ b/core/src/net/sf/openrocket/gui/main/SimulationRunDialog.java @@ -10,8 +10,11 @@ import java.awt.event.WindowAdapter; 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; @@ -21,6 +24,7 @@ import javax.swing.JPanel; 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; @@ -32,6 +36,8 @@ import net.sf.openrocket.rocketcomponent.MotorMount; 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; @@ -47,7 +53,7 @@ public class SimulationRunDialog extends JDialog { private static final LogHelper log = Application.getLogger(); private static final Translator trans = Application.getTranslator(); - + /** Update the dialog status every this many ms */ private static final long UPDATE_MS = 200; @@ -57,25 +63,42 @@ public class SimulationRunDialog extends JDialog { /** Flight progress at apogee */ private static final double APOGEE_PROGRESS = 0.7; - - /* - * The executor service is not static since we want concurrent simulation - * dialogs to run in parallel, ie. they both have their own executor service. + + /** + * A single ThreadPoolExecutor that will be used for all simulations. + * This executor must not be shut down. */ - private final ExecutorService executor = Executors.newFixedThreadPool( - SwingPreferences.getMaxThreadCount()); + private static final ThreadPoolExecutor executor; + static { + int n = SwingPreferences.getMaxThreadCount(); + executor = new ThreadPoolExecutor(n, n, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(), + 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; private final JProgressBar progressBar; - + /* * NOTE: Care must be used when accessing the simulation parameters, since they * are being run in another thread. Mutexes are used to avoid concurrent usage, which * 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; @@ -83,9 +106,10 @@ public class SimulationRunDialog extends JDialog { 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.DOCUMENT_MODAL); + 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"); @@ -93,7 +117,7 @@ public class SimulationRunDialog extends JDialog { this.simulations = simulations; - + // Randomize the simulation random seeds for (Simulation sim : simulations) { sim.getOptions().randomizeSeed(); @@ -110,7 +134,7 @@ public class SimulationRunDialog extends JDialog { 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]); } @@ -138,7 +162,7 @@ public class SimulationRunDialog extends JDialog { progressBar = new JProgressBar(); panel.add(progressBar, "spanx, growx, wrap para"); - + // Add cancel button JButton cancel = new JButton(trans.get("dlg.but.cancel")); cancel.addActionListener(new ActionListener() { @@ -149,7 +173,7 @@ public class SimulationRunDialog extends JDialog { }); panel.add(cancel, "spanx, tag cancel"); - + // Cancel simulations when user closes the window this.addWindowListener(new WindowAdapter() { @Override @@ -158,7 +182,7 @@ public class SimulationRunDialog extends JDialog { } }); - + this.add(panel); this.setMinimumSize(new Dimension(300, 0)); this.setLocationByPlatform(true); @@ -176,10 +200,10 @@ public class SimulationRunDialog extends JDialog { * the Cancel button on the dialog. */ public void cancelSimulations() { - executor.shutdownNow(); for (SimulationWorker w : simulationWorkers) { w.cancel(true); } + executor.purge(); } @@ -189,13 +213,13 @@ public class SimulationRunDialog extends JDialog { * @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 void updateProgress() { int index; for (index = 0; index < simulations.length; index++) { @@ -242,7 +266,7 @@ public class SimulationRunDialog extends JDialog { } - + /** * A SwingWorker that performs a flight simulation. It periodically updates the * simulation statuses of the parent class and calls updateProgress(). @@ -258,6 +282,8 @@ public class SimulationRunDialog extends JDialog { private volatile double burnoutVelocity; private volatile double apogeeAltitude; + private final CustomExpressionSimulationListener exprListener; + /* * -2 = time from 0 ... burnoutTimeEstimate * -1 = velocity from v(burnoutTimeEstimate) ... 0 @@ -268,8 +294,10 @@ public class SimulationRunDialog extends JDialog { private int progress = 0; - public InteractiveSimulationWorker(Simulation sim, int index) { + public InteractiveSimulationWorker(OpenRocketDocument doc, Simulation sim, int index) { super(sim); + List exprs = doc.getCustomExpressions(); + exprListener = new CustomExpressionSimulationListener(exprs); this.index = index; // Calculate estimate of motor burn time @@ -295,7 +323,7 @@ public class SimulationRunDialog extends JDialog { */ @Override protected SimulationListener[] getExtraListeners() { - return new SimulationListener[] { new SimulationProgressListener() }; + return new SimulationListener[] { new SimulationProgressListener(), exprListener }; }