[fixes #927] Fixed only current configuration updating instead of all the sims

This commit is contained in:
Sibo Van Gool 2021-07-11 23:14:42 +02:00
parent 2c2a7a2d3b
commit d74df08e04

View File

@ -8,11 +8,11 @@ import java.awt.Point;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.EventListener; import java.util.EventListener;
import java.util.EventObject; import java.util.EventObject;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
@ -63,6 +63,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.simulation.BasicEventSimulationEngine;
import net.sf.openrocket.simulation.FlightData; import net.sf.openrocket.simulation.FlightData;
import net.sf.openrocket.simulation.customexpression.CustomExpression; import net.sf.openrocket.simulation.customexpression.CustomExpression;
import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener; import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
@ -76,11 +77,13 @@ import net.sf.openrocket.util.Chars;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.StateChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* A JPanel that contains a RocketFigure and buttons to manipulate the figure. * A JPanel that contains a RocketFigure and buttons to manipulate the figure.
* *
* @author Sampo Niskanen <sampo.niskanen@iki.fi> * @author Sampo Niskanen <sampo.niskanen@iki.fi>
* @author Bill Kuker <bkuker@billkuker.com> * @author Bill Kuker <bkuker@billkuker.com>
*/ */
@ -88,6 +91,7 @@ import net.sf.openrocket.util.StateChangeListener;
public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource { public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private static final Logger log = LoggerFactory.getLogger(RocketPanel.class);
public enum VIEW_TYPE { public enum VIEW_TYPE {
SideView(false, RocketFigure.VIEW_SIDE), SideView(false, RocketFigure.VIEW_SIDE),
@ -129,7 +133,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
/* Calculation of CP and CG */ /* Calculation of CP and CG */
private AerodynamicCalculator aerodynamicCalculator; private AerodynamicCalculator aerodynamicCalculator;
private final OpenRocketDocument document; private final OpenRocketDocument document;
private Caret extraCP = null; private Caret extraCP = null;
@ -155,7 +159,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
* This uses a fixed-sized thread pool for all background simulations * This uses a fixed-sized thread pool for all background simulations
* with all threads in daemon mode and with minimum priority. * with all threads in daemon mode and with minimum priority.
*/ */
private static final Executor backgroundSimulationExecutor; private static final ExecutorService backgroundSimulationExecutor;
static { static {
backgroundSimulationExecutor = Executors.newFixedThreadPool(SwingPreferences.getMaxThreadCount(), backgroundSimulationExecutor = Executors.newFixedThreadPool(SwingPreferences.getMaxThreadCount(),
new ThreadFactory() { new ThreadFactory() {
@ -171,7 +175,6 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
}); });
} }
public OpenRocketDocument getDocument(){ public OpenRocketDocument getDocument(){
return this.document; return this.document;
} }
@ -369,7 +372,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
/** /**
* Get the center of pressure figure element. * Get the center of pressure figure element.
* *
* @return center of pressure info * @return center of pressure info
*/ */
public Caret getExtraCP() { public Caret getExtraCP() {
@ -378,7 +381,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
/** /**
* Get the center of gravity figure element. * Get the center of gravity figure element.
* *
* @return center of gravity info * @return center of gravity info
*/ */
public Caret getExtraCG() { public Caret getExtraCG() {
@ -387,7 +390,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
/** /**
* Get the extra text figure element. * Get the extra text figure element.
* *
* @return extra text that contains info about the rocket design * @return extra text that contains info about the rocket design
*/ */
public RocketInfo getExtraText() { public RocketInfo getExtraText() {
@ -492,12 +495,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
/** /**
* Handle clicking on figure shapes. The functioning is the following: * Handle clicking on figure shapes. The functioning is the following:
* *
* Get the components clicked. * Get the components clicked.
* If no component is clicked, do nothing. * If no component is clicked, do nothing.
* If the currently selected component is in the set, keep it, * If the currently selected component is in the set, keep it,
* unless the selector specified is pressed. If it is pressed, cycle to * unless the selector specified is pressed. If it is pressed, cycle to
* the next component. Otherwise select the first component in the list. * the next component. Otherwise select the first component in the list.
*/ */
public static final int CYCLE_SELECTION_MODIFIER = InputEvent.SHIFT_DOWN_MASK; public static final int CYCLE_SELECTION_MODIFIER = InputEvent.SHIFT_DOWN_MASK;
@ -647,7 +650,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
figure3d.setCG(new Coordinate(Double.NaN, Double.NaN)); figure3d.setCG(new Coordinate(Double.NaN, Double.NaN));
figure3d.setCP(new Coordinate(Double.NaN, Double.NaN)); figure3d.setCP(new Coordinate(Double.NaN, Double.NaN));
} }
if (figure.getType() == RocketPanel.VIEW_TYPE.SideView && length > 0) { if (figure.getType() == RocketPanel.VIEW_TYPE.SideView && length > 0) {
extraCP.setPosition(cpx, cpy); extraCP.setPosition(cpx, cpy);
extraCG.setPosition(cgx, cgy); extraCG.setPosition(cgx, cgy);
@ -686,34 +689,64 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
} }
// Start calculation process // Start calculation process
if(((SwingPreferences) Application.getPreferences()).computeFlightInBackground()){ if (Application.getPreferences().getAutoRunSimulations()) {
extraText.setCalculatingData(true); updateSims(false);
}
}
Rocket duplicate = (Rocket) document.getRocket().copy(); /**
* Updates the simulations. If *currentConfig* is true, only update the simulation of the current flight
* configuration. If it is false, update all the simulations.
*
* @param currentConfig flag to check whether to update all the simulations (false) or only the current
* flight config sim (true)
*/
private void updateSims(boolean currentConfig) {
// Stop previous computation (if any)
stopBackgroundSimulation();
// find a Simulation based on the current flight configuration FlightConfigurationId curID = document.getSelectedConfiguration().getFlightConfigurationID();
FlightConfigurationId curID = curConfig.getFlightConfigurationID(); extraText.setCalculatingData(true);
Simulation simulation = null; Rocket duplicate = (Rocket)document.getRocket().copy();
for (Simulation sim : document.getSimulations()) {
// Re-run the present simulation(s)
List<Simulation> sims = new LinkedList<>();
for (Simulation sim : document.getSimulations()) {
// Find a Simulation based on the current flight configuration
if (currentConfig) {
if (sim.getFlightConfigurationId().compareTo(curID) == 0) { if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
simulation = sim; sims.add(sim);
break; break;
} }
} }
else
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong, sims.add(sim);
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
// default simulation conditions
if (simulation == null) {
System.out.println("creating new simulation");
simulation = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(duplicate);
simulation.setFlightConfigurationId( document.getSelectedConfiguration().getId());
} else
System.out.println("using pre-existing simulation");
backgroundSimulationWorker = new BackgroundSimulationWorker(document, simulation);
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
} }
runBackgroundSimulations(sims, duplicate);
}
/**
* Runs a new background simulation for simulations *sims*. It will run all the simulations in sims sequentially
* in the background.
*
* @param sims simulations which should be run
* @param rkt rocket for which the simulations are run
*/
private void runBackgroundSimulations(List<Simulation> sims, Rocket rkt) {
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong,
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
// default simulation conditions
for (Simulation sim : sims) {
if (sim == null) {
log.info("creating new simulation");
sim = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(rkt);
sim.setFlightConfigurationId(document.getSelectedConfiguration().getId());
} else
log.info("using pre-existing simulation");
}
backgroundSimulationWorker = new BackgroundSimulationWorker(document, sims);
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
} }
/** /**
@ -734,16 +767,19 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
private class BackgroundSimulationWorker extends SimulationWorker { private class BackgroundSimulationWorker extends SimulationWorker {
private final CustomExpressionSimulationListener exprListener; private final CustomExpressionSimulationListener exprListener;
private final OpenRocketDocument doc;
private List<Simulation> sims;
public BackgroundSimulationWorker(OpenRocketDocument doc, Simulation sim) { public BackgroundSimulationWorker(OpenRocketDocument doc, List<Simulation> sims) {
super(sim); super(sims.get(0));
this.sims = sims;
this.doc = doc;
List<CustomExpression> exprs = doc.getCustomExpressions(); List<CustomExpression> exprs = doc.getCustomExpressions();
exprListener = new CustomExpressionSimulationListener(exprs); exprListener = new CustomExpressionSimulationListener(exprs);
} }
@Override @Override
protected FlightData doInBackground() { protected FlightData doInBackground() {
// Pause a little while to allow faster UI reaction // Pause a little while to allow faster UI reaction
try { try {
Thread.sleep(300); Thread.sleep(300);
@ -751,7 +787,6 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
} }
if (isCancelled() || backgroundSimulationWorker != this) if (isCancelled() || backgroundSimulationWorker != this)
return null; return null;
return super.doInBackground(); return super.doInBackground();
} }
@ -766,6 +801,13 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
figure.repaint(); figure.repaint();
figure3d.repaint(); figure3d.repaint();
document.fireDocumentChangeEvent(new SimulationChangeEvent(simulation)); document.fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
// Run the new simulation after this one has ended
this.sims.remove(0);
if (this.sims.size() > 0) {
backgroundSimulationWorker = new BackgroundSimulationWorker(this.doc, this.sims);
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
}
} }
@Override @Override
@ -815,7 +857,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
} }
/** /**
* Updates the selection in the FigureParameters and repaints the figure. * Updates the selection in the FigureParameters and repaints the figure.
* Ignores the event itself. * Ignores the event itself.
*/ */
@Override @Override