diff --git a/.classpath b/.classpath
index c71fbb9c8..31166a946 100644
--- a/.classpath
+++ b/.classpath
@@ -10,7 +10,6 @@
-
@@ -18,5 +17,10 @@
+
+
+
+
+
diff --git a/ChangeLog b/ChangeLog
index 0f4e934f3..efbb97935 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2010-10-25 Doug Pedrick
+
+ * [BUG] Take launch lug radial angle into account when loading rkt file
+
+2010-10-24 Sampo Niskane
+
+ * Added SafetyMutex and took into use in Simulation
+
+2010-10-18 Sampo Niskanen
+
+ * Ignore Sun JRE bug in D3D
+
2010-10-09 Sampo Niskanen
* [BUG] Fixed conversion to freeform fin set
diff --git a/build.xml b/build.xml
index 6262bc0da..0540b3dc6 100644
--- a/build.xml
+++ b/build.xml
@@ -36,8 +36,11 @@
-
-
+
+
+
+
+
diff --git a/doc/properties.txt b/doc/properties.txt
index ed0690416..cbddc55fb 100644
--- a/doc/properties.txt
+++ b/doc/properties.txt
@@ -25,6 +25,14 @@ openrocket.log.tracelevel
Debugging options
-----------------
+openrocket.debug
+ Turns on various options useful for debugging purposes. The parameters defined are:
+ openrocket.log.stdout=VBOSE
+ openrocket.log.tracelevel=VBOSE
+ openrocket.debug.menu=true
+ openrocket.debug.motordigest=true
+
+
openrocket.debug.menu
If defined the "Debug" menu will be displayed in the main application window.
diff --git a/lib-test/hamcrest-core-1.3.0RC1.jar b/lib-test/hamcrest-core-1.3.0RC1.jar
new file mode 100644
index 000000000..1195cb7f5
Binary files /dev/null and b/lib-test/hamcrest-core-1.3.0RC1.jar differ
diff --git a/lib-test/hamcrest-library-1.3.0RC1.jar b/lib-test/hamcrest-library-1.3.0RC1.jar
new file mode 100644
index 000000000..8e6568b55
Binary files /dev/null and b/lib-test/hamcrest-library-1.3.0RC1.jar differ
diff --git a/lib-test/jmock-2.6.0-RC2.jar b/lib-test/jmock-2.6.0-RC2.jar
new file mode 100644
index 000000000..a846450ff
Binary files /dev/null and b/lib-test/jmock-2.6.0-RC2.jar differ
diff --git a/lib-test/jmock-junit4-2.6.0-RC2.jar b/lib-test/jmock-junit4-2.6.0-RC2.jar
new file mode 100644
index 000000000..129e56136
Binary files /dev/null and b/lib-test/jmock-junit4-2.6.0-RC2.jar differ
diff --git a/lib-test/junit-4.7.jar b/lib-test/junit-dep-4.8.2.jar
similarity index 62%
rename from lib-test/junit-4.7.jar
rename to lib-test/junit-dep-4.8.2.jar
index 700ad6952..f28b4ef01 100644
Binary files a/lib-test/junit-4.7.jar and b/lib-test/junit-dep-4.8.2.jar differ
diff --git a/src/net/sf/openrocket/document/Simulation.java b/src/net/sf/openrocket/document/Simulation.java
index db462aad8..9d5d0cd35 100644
--- a/src/net/sf/openrocket/document/Simulation.java
+++ b/src/net/sf/openrocket/document/Simulation.java
@@ -27,8 +27,16 @@ import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource;
+import net.sf.openrocket.util.SafetyMutex;
-
+/**
+ * A class defining a simulation, its conditions and simulated data.
+ *
+ * This class is not thread-safe and enforces single-threaded access with a
+ * SafetyMutex.
+ *
+ * @author Sampo Niskanen
+ */
public class Simulation implements ChangeSource, Cloneable {
private static final LogHelper log = Application.getLogger();
@@ -49,6 +57,7 @@ public class Simulation implements ChangeSource, Cloneable {
NOT_SIMULATED
}
+ private final SafetyMutex mutex = new SafetyMutex();
private final Rocket rocket;
@@ -146,6 +155,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the rocket.
*/
public Rocket getRocket() {
+ mutex.verify();
return rocket;
}
@@ -157,6 +167,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return a newly created Configuration of the launch conditions.
*/
public Configuration getConfiguration() {
+ mutex.verify();
Configuration c = new Configuration(rocket);
c.setMotorConfigurationID(conditions.getMotorConfigurationID());
c.setAllStages();
@@ -171,6 +182,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the simulation conditions.
*/
public GUISimulationConditions getConditions() {
+ mutex.verify();
return conditions;
}
@@ -182,6 +194,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the actual list of simulation listeners.
*/
public List getSimulationListeners() {
+ mutex.verify();
return simulationListeners;
}
@@ -192,6 +205,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the name for the simulation.
*/
public String getName() {
+ mutex.verify();
return name;
}
@@ -202,15 +216,20 @@ public class Simulation implements ChangeSource, Cloneable {
* @param name the name of the simulation.
*/
public void setName(String name) {
- if (this.name.equals(name))
- return;
-
- if (name == null)
- this.name = "";
- else
- this.name = name;
-
- fireChangeEvent();
+ mutex.lock("setName");
+ try {
+ if (this.name.equals(name))
+ return;
+
+ if (name == null)
+ this.name = "";
+ else
+ this.name = name;
+
+ fireChangeEvent();
+ } finally {
+ mutex.unlock("setName");
+ }
}
@@ -222,6 +241,8 @@ public class Simulation implements ChangeSource, Cloneable {
* @see Status
*/
public Status getStatus() {
+ mutex.verify();
+
if (status == Status.UPTODATE || status == Status.LOADED) {
if (rocket.getFunctionalModID() != simulatedRocketID ||
!conditions.equals(simulatedConditions))
@@ -236,54 +257,59 @@ public class Simulation implements ChangeSource, Cloneable {
public void simulate(SimulationListener... additionalListeners)
throws SimulationException {
-
- if (this.status == Status.EXTERNAL) {
- throw new SimulationException("Cannot simulate imported simulation.");
- }
-
- SimulationEngine simulator;
-
+ mutex.lock("simulate");
try {
- simulator = simulationEngineClass.newInstance();
- } catch (InstantiationException e) {
- throw new IllegalStateException("Cannot instantiate simulator.", e);
- } catch (IllegalAccessException e) {
- throw new IllegalStateException("Cannot access simulator instance?! BUG!", e);
- } catch (NullPointerException e) {
- throw new IllegalStateException("Simulator null", e);
- }
-
- SimulationConditions simulationConditions = conditions.toSimulationConditions();
- for (SimulationListener l : additionalListeners) {
- simulationConditions.getSimulationListenerList().add(l);
- }
-
- for (String className : simulationListeners) {
- SimulationListener l = null;
- try {
- Class> c = Class.forName(className);
- l = (SimulationListener) c.newInstance();
- } catch (Exception e) {
- throw new SimulationListenerException("Could not instantiate listener of " +
- "class: " + className, e);
+
+ if (this.status == Status.EXTERNAL) {
+ throw new SimulationException("Cannot simulate imported simulation.");
}
- simulationConditions.getSimulationListenerList().add(l);
+
+ SimulationEngine simulator;
+
+ try {
+ simulator = simulationEngineClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new IllegalStateException("Cannot instantiate simulator.", e);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Cannot access simulator instance?! BUG!", e);
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("Simulator null", e);
+ }
+
+ SimulationConditions simulationConditions = conditions.toSimulationConditions();
+ for (SimulationListener l : additionalListeners) {
+ simulationConditions.getSimulationListenerList().add(l);
+ }
+
+ for (String className : simulationListeners) {
+ SimulationListener l = null;
+ try {
+ Class> c = Class.forName(className);
+ l = (SimulationListener) c.newInstance();
+ } catch (Exception e) {
+ throw new SimulationListenerException("Could not instantiate listener of " +
+ "class: " + className, e);
+ }
+ simulationConditions.getSimulationListenerList().add(l);
+ }
+
+ long t1, t2;
+ log.debug("Simulation: calling simulator");
+ t1 = System.currentTimeMillis();
+ simulatedData = simulator.simulate(simulationConditions);
+ t2 = System.currentTimeMillis();
+ log.debug("Simulation: returning from simulator, simulation took " + (t2 - t1) + "ms");
+
+ // Set simulated info after simulation, will not be set in case of exception
+ simulatedConditions = conditions.clone();
+ simulatedMotors = getConfiguration().getMotorConfigurationDescription();
+ simulatedRocketID = rocket.getFunctionalModID();
+
+ status = Status.UPTODATE;
+ fireChangeEvent();
+ } finally {
+ mutex.unlock("simulate");
}
-
- long t1, t2;
- log.debug("Simulation: calling simulator");
- t1 = System.currentTimeMillis();
- simulatedData = simulator.simulate(simulationConditions);
- t2 = System.currentTimeMillis();
- log.debug("Simulation: returning from simulator, simulation took " + (t2 - t1) + "ms");
-
- // Set simulated info after simulation, will not be set in case of exception
- simulatedConditions = conditions.clone();
- simulatedMotors = getConfiguration().getMotorConfigurationDescription();
- simulatedRocketID = rocket.getFunctionalModID();
-
- status = Status.UPTODATE;
- fireChangeEvent();
}
@@ -294,6 +320,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the conditions used in the previous simulation, or null.
*/
public GUISimulationConditions getSimulatedConditions() {
+ mutex.verify();
return simulatedConditions;
}
@@ -306,6 +333,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @see FlightData#getWarningSet()
*/
public WarningSet getSimulatedWarnings() {
+ mutex.verify();
if (simulatedData == null)
return null;
return simulatedData.getWarningSet();
@@ -321,6 +349,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @see Rocket#getMotorConfigurationNameOrDescription(String)
*/
public String getSimulatedMotorDescription() {
+ mutex.verify();
return simulatedMotors;
}
@@ -331,6 +360,7 @@ public class Simulation implements ChangeSource, Cloneable {
* @return the flight data of the previous simulation, or null.
*/
public FlightData getSimulatedData() {
+ mutex.verify();
return simulatedData;
}
@@ -344,6 +374,7 @@ public class Simulation implements ChangeSource, Cloneable {
*/
@SuppressWarnings("unchecked")
public Simulation copy() {
+ mutex.lock("copy");
try {
Simulation copy = (Simulation) super.clone();
@@ -359,9 +390,10 @@ public class Simulation implements ChangeSource, Cloneable {
return copy;
-
} catch (CloneNotSupportedException e) {
throw new BugException("Clone not supported, BUG", e);
+ } finally {
+ mutex.unlock("copy");
}
}
@@ -375,26 +407,33 @@ public class Simulation implements ChangeSource, Cloneable {
*/
@SuppressWarnings("unchecked")
public Simulation duplicateSimulation(Rocket newRocket) {
- Simulation copy = new Simulation(newRocket);
-
- copy.name = this.name;
- copy.conditions.copyFrom(this.conditions);
- copy.simulationListeners = (ArrayList) this.simulationListeners.clone();
- copy.simulationStepperClass = this.simulationStepperClass;
- copy.aerodynamicCalculatorClass = this.aerodynamicCalculatorClass;
-
- return copy;
+ mutex.lock("duplicateSimulation");
+ try {
+ Simulation copy = new Simulation(newRocket);
+
+ copy.name = this.name;
+ copy.conditions.copyFrom(this.conditions);
+ copy.simulationListeners = (ArrayList) this.simulationListeners.clone();
+ copy.simulationStepperClass = this.simulationStepperClass;
+ copy.aerodynamicCalculatorClass = this.aerodynamicCalculatorClass;
+
+ return copy;
+ } finally {
+ mutex.unlock("duplicateSimulation");
+ }
}
@Override
public void addChangeListener(ChangeListener listener) {
+ mutex.verify();
listeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
+ mutex.verify();
listeners.remove(listener);
}
diff --git a/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java b/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java
index c67568fc7..927cc5483 100644
--- a/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java
+++ b/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java
@@ -141,7 +141,8 @@ public class DebugLogDialog extends JDialog {
panel.add(new JLabel("Display log lines:"), "gapright para, split");
for (LogLevel l : LogLevel.values()) {
JCheckBox box = new JCheckBox(l.toString());
- box.setSelected(true);
+ // By default display DEBUG and above
+ box.setSelected(l.atLeast(LogLevel.DEBUG));
box.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -279,6 +280,7 @@ public class DebugLogDialog extends JDialog {
sorter.setComparator(1, NumericComparator.INSTANCE);
sorter.setComparator(4, new LocationComparator());
table.setRowSorter(sorter);
+ sorter.setRowFilter(new LogFilter());
panel.add(new JScrollPane(table), "span, grow, width " +
diff --git a/src/net/sf/openrocket/gui/dialogs/DetailDialog.java b/src/net/sf/openrocket/gui/dialogs/DetailDialog.java
index 05a19950d..87e36e678 100644
--- a/src/net/sf/openrocket/gui/dialogs/DetailDialog.java
+++ b/src/net/sf/openrocket/gui/dialogs/DetailDialog.java
@@ -3,16 +3,31 @@ package net.sf.openrocket.gui.dialogs;
import java.awt.Component;
import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import net.sf.openrocket.util.GUIUtil;
public class DetailDialog {
-
- public static void showDetailedMessageDialog(Component parentComponent, Object message,
- String details, String title, int messageType) {
+
+ public static void showDetailedMessageDialog(Component parentComponent, Object message,
+ String details, String title, int messageType) {
- // TODO: HIGH: Detailed dialog
- JOptionPane.showMessageDialog(parentComponent, message, title, messageType, null);
+ if (details != null) {
+ JTextArea textArea = null;
+ textArea = new JTextArea(5, 40);
+ textArea.setText(details);
+ textArea.setCaretPosition(0);
+ textArea.setEditable(false);
+ GUIUtil.changeFontSize(textArea, -2);
+ JOptionPane.showMessageDialog(parentComponent,
+ new Object[] { message, new JScrollPane(textArea) },
+ title, messageType, null);
+ } else {
+ JOptionPane.showMessageDialog(parentComponent, message, title, messageType, null);
+ }
}
-
+
}
diff --git a/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java b/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java
index 39f9d2b2f..ed55079f0 100644
--- a/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java
+++ b/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java
@@ -12,15 +12,15 @@ import java.util.ServiceLoader;
import javax.swing.JDialog;
import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.optimization.rocketoptimization.RocketOptimizationParameter;
-import net.sf.openrocket.optimization.rocketoptimization.RocketOptimizationParameterService;
+import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameter;
+import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameterService;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifierService;
import net.sf.openrocket.util.BugException;
public class GeneralOptimizationDialog extends JDialog {
- private final List optimizationParameters = new ArrayList();
+ private final List optimizationParameters = new ArrayList();
private final Map