getSimulations() {
return simulations.clone();
}
+ /**
+ * gets the number of simulations in the document
+ * @return the number of simulations in the document
+ */
public int getSimulationCount() {
return simulations.size();
}
+ /**
+ * the the Nth simulation from the document
+ * @param n simulation index
+ * @return the Nth simulation from the document, null if there's none
+ */
public Simulation getSimulation(int n) {
return simulations.get(n);
}
+ /**
+ * gets the index of the given simulation
+ * @param simulation the simulation being searched
+ * @return the index of the simulation in the document
+ */
public int getSimulationIndex(Simulation simulation) {
return simulations.indexOf(simulation);
}
+ /**
+ * adds simulation into the document
+ * fires document change event
+ * @param simulation the simulation to be added
+ */
public void addSimulation(Simulation simulation) {
simulations.add(simulation);
+ FlightConfigurationId simId = simulation.getId();
+ if( !rocket.containsFlightConfigurationID( simId )){
+ rocket.createFlightConfiguration(simId);
+ }
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
}
+ /**
+ * adds the simulation to the Nth index, overwriting if there is already one
+ * fires change document event
+ * @param simulation the simulation to be added
+ * @param n the index to be added
+ */
public void addSimulation(Simulation simulation, int n) {
simulations.add(n, simulation);
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
}
+ /**
+ * removes the specific simulation from the list
+ * @param simulation the simulation to be removed
+ */
public void removeSimulation(Simulation simulation) {
simulations.remove(simulation);
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
}
+ /**
+ * removes the Nth simulation from the document
+ * fires document change event
+ * @param n the Nth simulation
+ * @return the removed simulation
+ */
public Simulation removeSimulation(int n) {
Simulation simulation = simulations.remove(n);
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
return simulation;
}
- public void removeFlightConfigurationAndSimulations(String configId) {
+ /**
+ * removes the flight configuration and simulation with the specific id
+ * @param configId
+ */
+ public void removeFlightConfigurationAndSimulations(FlightConfigurationId configId) {
if (configId == null) {
return;
}
+ removeSimulations(configId);
+ rocket.removeFlightConfiguration(configId);
+ }
+
+ /**
+ * removes all simulations with the specific configId
+ * @param configId the Flight Configuration Id that dictates which simulations shoul be removed
+ */
+ private void removeSimulations(FlightConfigurationId configId) {
for (Simulation s : getSimulations()) {
// Assumes modifiable collection - which it is
- if (configId.equals(s.getConfiguration().getFlightConfigurationID())) {
+ if (configId.equals(s.getId())) {
removeSimulation(s);
}
}
- rocket.removeFlightConfigurationID(configId);
}
@@ -327,42 +453,22 @@ public String getNextSimulationName() {
*/
public void addUndoPosition(String description) {
- if (storedDescription != null) {
- logUndoError("addUndoPosition called while storedDescription=" + storedDescription +
- " description=" + description);
- }
+ checkDescription(description);
// Check whether modifications have been done since last call
- if (isCleanState()) {
- // No modifications
- log.info("Adding undo position '" + description + "' to " + this + ", document was in clean state");
- nextDescription = description;
+ if(isCheckNoModification(description))
return;
- }
-
log.info("Adding undo position '" + description + "' to " + this + ", document is in unclean state");
+ checkUndoPositionConsistency();
+ addStateToUndoHistory(description);
- /*
- * Modifications have been made to the rocket. We should be at the end of the
- * undo history, but check for consistency and try to recover.
- */
- if (undoPosition != undoHistory.size() - 1) {
- logUndoError("undo position inconsistency");
- }
- while (undoPosition < undoHistory.size() - 1) {
- undoHistory.removeLast();
- undoDescription.removeLast();
- }
-
-
- // Add the current state to the undo history
- undoHistory.add(rocket.copyWithOriginalID());
- undoDescription.add(null);
- nextDescription = description;
- undoPosition++;
-
-
- // Maintain maximum undo size
+ maintainMaximumUndoSize();
+ }
+
+ /**
+ *
+ */
+ private void maintainMaximumUndoSize() {
if (undoHistory.size() > UNDO_LEVELS + UNDO_MARGIN && undoPosition > UNDO_MARGIN) {
for (int i = 0; i < UNDO_MARGIN; i++) {
undoHistory.removeFirst();
@@ -371,6 +477,57 @@ public void addUndoPosition(String description) {
}
}
}
+
+ /**
+ * @param description
+ */
+ private void addStateToUndoHistory(String description) {
+ // Add the current state to the undo history
+ undoHistory.add(rocket.copyWithOriginalID());
+ undoDescription.add(null);
+ nextDescription = description;
+ undoPosition++;
+ }
+
+ /**
+ * checks if there was or not modification, and logs
+ *
+ * @param description the description to be used in the log
+ * @return if there was or not modification
+ */
+ private boolean isCheckNoModification(String description){
+ if (isCleanState()) {
+ // No modifications
+ log.info("Adding undo position '" + description + "' to " + this + ", document was in clean state");
+ nextDescription = description;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * checks if the document already has a stored undo description
+ * logs if it has
+ *
+ * @param description undo description to be logged
+ */
+ private void checkDescription(String description) {
+ if (storedDescription != null) {
+ logUndoError("addUndoPosition called while storedDescription=" + storedDescription +
+ " description=" + description);
+ }
+ }
+
+ /**
+ * If modifications have been made to the rocket. We should be at the end of the
+ * undo history, but check for consistency and try to recover.
+ */
+ private void checkUndoPositionConsistency() {
+ if (undoPosition != undoHistory.size() - 1) {
+ logUndoError("undo position inconsistency");
+ }
+ removeRedoInfo();
+ }
/**
@@ -411,7 +568,7 @@ public void stopUndo() {
* Clear the undo history.
*/
public void clearUndo() {
- log.info("Clearing undo history of " + this);
+ //log.info("Clearing undo history of " + this);
undoHistory.clear();
undoDescription.clear();
@@ -432,18 +589,29 @@ public void componentChanged(ComponentChangeEvent e) {
" undoPosition=" + undoPosition + " undoHistory.size=" + undoHistory.size() +
" isClean=" + isCleanState());
}
- // Remove any redo information if available
- while (undoPosition < undoHistory.size() - 1) {
- undoHistory.removeLast();
- undoDescription.removeLast();
- }
-
- // Set the latest description
- undoDescription.set(undoPosition, nextDescription);
+ removeRedoInfo();
+ setLatestDescription();
}
fireUndoRedoChangeEvent();
}
+
+ /**
+ * Sets the latest description
+ */
+ private void setLatestDescription() {
+ undoDescription.set(undoPosition, nextDescription);
+ }
+
+ /**
+ * Removes any redo information if available
+ */
+ private void removeRedoInfo() {
+ while (undoPosition < undoHistory.size() - 1) {
+ undoHistory.removeLast();
+ undoDescription.removeLast();
+ }
+ }
/**
@@ -587,7 +755,7 @@ private void logUndoError(String error) {
public OpenRocketDocument copy() {
Rocket rocketCopy = rocket.copyWithOriginalID();
OpenRocketDocument documentCopy = OpenRocketDocumentFactory.createDocumentFromRocket(rocketCopy);
- documentCopy.getDefaultConfiguration().setFlightConfigurationID(configuration.getFlightConfigurationID());
+
for (Simulation s : simulations) {
documentCopy.addSimulation(s.duplicateSimulation(rocketCopy));
}
@@ -606,6 +774,7 @@ public void removeUndoRedoListener(UndoRedoListener listener) {
undoRedoListeners.remove(listener);
}
+
private void fireUndoRedoChangeEvent() {
UndoRedoListener[] array = undoRedoListeners.toArray(new UndoRedoListener[0]);
for (UndoRedoListener l : array) {
@@ -629,6 +798,17 @@ protected void fireDocumentChangeEvent(DocumentChangeEvent event) {
}
}
+ public String toSimulationDetail(){
+ StringBuilder str = new StringBuilder();
+ str.append(">> Dumping simulation list:\n");
+ int simNum = 0;
+ for( Simulation s : this.simulations ){
+ str.append(String.format(" [%d] %s (%s) \n", simNum, s.getName(), s.getId().toShortKey() ));
+ simNum++;
+ }
+
+ return str.toString();
+ }
diff --git a/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java b/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java
index e649a06d02..eefef3e8e0 100644
--- a/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java
+++ b/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java
@@ -2,7 +2,7 @@
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.Rocket;
-import net.sf.openrocket.rocketcomponent.Stage;
+import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.startup.Application;
public class OpenRocketDocumentFactory {
@@ -11,7 +11,7 @@ public class OpenRocketDocumentFactory {
public static OpenRocketDocument createNewRocket() {
Rocket rocket = new Rocket();
- Stage stage = new Stage();
+ AxialStage stage = new AxialStage();
//// Sustainer
stage.setName(trans.get("BasicFrame.StageName.Sustainer"));
rocket.addChild(stage);
diff --git a/core/src/net/sf/openrocket/document/Simulation.java b/core/src/net/sf/openrocket/document/Simulation.java
index 5a8b8ed23c..30b4d02c75 100644
--- a/core/src/net/sf/openrocket/document/Simulation.java
+++ b/core/src/net/sf/openrocket/document/Simulation.java
@@ -2,23 +2,19 @@
import java.util.EventListener;
import java.util.EventObject;
-import java.util.Iterator;
import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.formatting.RocketDescriptor;
-import net.sf.openrocket.masscalc.BasicMassCalculator;
import net.sf.openrocket.masscalc.MassCalculator;
-import net.sf.openrocket.motor.Motor;
-import net.sf.openrocket.motor.MotorInstanceConfiguration;
-import net.sf.openrocket.rocketcomponent.Configuration;
-import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
-import net.sf.openrocket.rocketcomponent.MotorConfiguration;
-import net.sf.openrocket.rocketcomponent.MotorMount;
+import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket;
-import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.simulation.BasicEventSimulationEngine;
import net.sf.openrocket.simulation.DefaultSimulationOptionFactory;
import net.sf.openrocket.simulation.FlightData;
@@ -37,9 +33,6 @@
import net.sf.openrocket.util.SafetyMutex;
import net.sf.openrocket.util.StateChangeListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* A class defining a simulation, its conditions and simulated data.
*
@@ -77,6 +70,7 @@ public static enum Status {
private SafetyMutex mutex = SafetyMutex.newInstance();
private final Rocket rocket;
+ FlightConfigurationId configId = FlightConfigurationId.ERROR_FCID;
private String name = "";
@@ -84,7 +78,7 @@ public static enum Status {
/** The conditions to use */
// TODO: HIGH: Change to use actual conditions class??
- private SimulationOptions options;
+ private SimulationOptions options = new SimulationOptions();
private ArrayList simulationExtensions = new ArrayList();
@@ -93,7 +87,7 @@ public static enum Status {
private Class extends SimulationStepper> simulationStepperClass = RK4SimulationStepper.class;
private Class extends AerodynamicCalculator> aerodynamicCalculatorClass = BarrowmanCalculator.class;
@SuppressWarnings("unused")
- private Class extends MassCalculator> massCalculatorClass = BasicMassCalculator.class;
+ private Class extends MassCalculator> massCalculatorClass = MassCalculator.class;
/** Listeners for this object */
private List listeners = new ArrayList();
@@ -101,7 +95,7 @@ public static enum Status {
/** The conditions actually used in the previous simulation, or null */
private SimulationOptions simulatedConditions = null;
- private String simulatedConfiguration = null;
+ private String simulatedConfigurationDescription = null;
private FlightData simulatedData = null;
private int simulatedRocketID = -1;
@@ -116,12 +110,12 @@ public Simulation(Rocket rocket) {
this.rocket = rocket;
this.status = Status.NOT_SIMULATED;
- options = new SimulationOptions(rocket);
-
DefaultSimulationOptionFactory f = Application.getInjector().getInstance(DefaultSimulationOptionFactory.class);
options.copyConditionsFrom(f.getDefault());
- options.setMotorConfigurationID(rocket.getDefaultConfiguration().getFlightConfigurationID());
+ FlightConfigurationId fcid = rocket.getSelectedConfiguration().getFlightConfigurationID();
+ setFlightConfigurationId(fcid);
+
options.addChangeListener(new ConditionListener());
}
@@ -139,7 +133,7 @@ public Simulation(Rocket rocket, Status status, String name, SimulationOptions o
throw new IllegalArgumentException("options cannot be null");
this.rocket = rocket;
-
+
if (status == Status.UPTODATE) {
this.status = Status.LOADED;
} else if (data == null) {
@@ -151,6 +145,9 @@ public Simulation(Rocket rocket, Status status, String name, SimulationOptions o
this.name = name;
this.options = options;
+
+ this.setFlightConfigurationId( rocket.getSelectedConfiguration().getFlightConfigurationID());
+
options.addChangeListener(new ConditionListener());
if (extensions != null) {
@@ -177,22 +174,66 @@ public Rocket getRocket() {
mutex.verify();
return rocket;
}
-
+
+ public FlightConfigurationId getFlightConfigurationId(){
+ return this.configId;
+ }
+ public FlightConfigurationId getId(){
+ return this.getFlightConfigurationId();
+ }
/**
- * Return a newly created Configuration for this simulation. The configuration
- * has the motor ID set and all stages active.
- *
- * @return a newly created Configuration of the launch conditions.
+ * Set the motor configuration ID. If this id does not yet exist, it will be created.
+ *
+ * @param id the configuration to set.
*/
- public Configuration getConfiguration() {
- mutex.verify();
- Configuration c = new Configuration(rocket);
- c.setFlightConfigurationID(options.getMotorConfigurationID());
- c.setAllStages();
- return c;
+ public void setFlightConfigurationId(FlightConfigurationId fcid) {
+ if ( null == fcid ){
+ throw new NullPointerException("Attempted to set a null Config id in simulation options. Not allowed!");
+ }else if ( fcid.hasError() ){
+ throw new IllegalArgumentException("Attempted to set the configuration to an error id. Not Allowed!");
+ }else if (!rocket.containsFlightConfigurationID(fcid)){
+ rocket.createFlightConfiguration(fcid);
+ }
+
+ if( fcid.equals(this.configId)){
+ return;
+ }
+
+ this.configId = fcid;
+ fireChangeEvent();
}
+
+// /**
+// * Return a newly created Configuration for this simulation. The configuration
+// * has the motor ID set and all stages active.
+// *
+// * @return a newly created Configuration of the launch conditions.
+// */
+// public FlightConfiguration getConfiguration() {
+// mutex.verify();
+// FlightConfiguration c = rocket.getDefaultConfiguration().clone();
+// c.setFlightConfigurationID(options.getConfigID());
+// c.setAllStages();
+// return c;
+// }
+//
+//
+// /**
+// * Return a newly created Configuration for this simulation. The configuration
+// * has the motor ID set and all stages active.
+// *
+// * @return a newly created Configuration of the launch conditions.
+// */
+// public FlightConfiguration setConfiguration( final FlightConfiguration fc ) {
+// mutex.verify();
+// //FlightConfiguration c = rocket.getDefaultConfiguration().clone();
+// //c.setFlightConfigurationID(options.getConfigID());
+// //c.setAllStages();
+// //return c;
+// }
+
/**
* Returns the simulation options attached to this simulation. The options
* may be modified freely, and the status of the simulation will change to reflect
@@ -266,29 +307,20 @@ public Status getStatus() {
status = Status.OUTDATED;
}
}
-
-
- //Make sure this simulation has motors.
- Configuration c = new Configuration(this.getRocket());
- MotorInstanceConfiguration motors = new MotorInstanceConfiguration();
- c.setFlightConfigurationID(options.getMotorConfigurationID());
- final String flightConfigId = c.getFlightConfigurationID();
-
- Iterator iterator = c.motorIterator();
- boolean no_motors = true;
-
- while (iterator.hasNext()) {
- MotorMount mount = iterator.next();
- RocketComponent component = (RocketComponent) mount;
- MotorConfiguration motorConfig = mount.getMotorConfiguration().get(flightConfigId);
- IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().get(flightConfigId);
- Motor motor = motorConfig.getMotor();
- if (motor != null)
- no_motors = false;
+
+ // if the id hasn't been set yet, skip.
+ if ( getId().hasError() ){
+ log.warn(" simulationOptions lacks a valid id. Skipping.");
+ status = Status.CANT_RUN;
+ return status;
}
- if (no_motors)
+ FlightConfiguration config = rocket.getFlightConfiguration( this.getId()).clone();
+
+ //Make sure this simulation has motors.
+ if ( ! config.hasMotors() ){
status = Status.CANT_RUN;
+ }
return status;
}
@@ -339,14 +371,11 @@ public void simulate(SimulationListener... additionalListeners)
// Set simulated info after simulation, will not be set in case of exception
simulatedConditions = options.clone();
- final Configuration configuration = getConfiguration();
-
- simulatedConfiguration = descriptor.format(configuration.getRocket(), configuration.getFlightConfigurationID());
+ simulatedConfigurationDescription = descriptor.format( this.rocket, getId());
simulatedRocketID = rocket.getFunctionalModID();
status = Status.UPTODATE;
fireChangeEvent();
- configuration.release();
} finally {
mutex.unlock("simulate");
}
@@ -389,7 +418,7 @@ public WarningSet getSimulatedWarnings() {
*/
public String getSimulatedConfigurationDescription() {
mutex.verify();
- return simulatedConfiguration;
+ return simulatedConfigurationDescription;
}
/**
@@ -441,7 +470,7 @@ public Simulation copy() {
}
copy.listeners = new ArrayList();
copy.simulatedConditions = null;
- copy.simulatedConfiguration = null;
+ copy.simulatedConfigurationDescription = null;
copy.simulatedData = null;
copy.simulatedRocketID = -1;
@@ -469,7 +498,7 @@ public Simulation duplicateSimulation(Rocket newRocket) {
copy.name = this.name;
copy.options.copyFrom(this.options);
- copy.simulatedConfiguration = this.simulatedConfiguration;
+ copy.simulatedConfigurationDescription = this.simulatedConfigurationDescription;
for (SimulationExtension c : this.simulationExtensions) {
copy.simulationExtensions.add(c.clone());
}
@@ -522,4 +551,5 @@ public void stateChanged(EventObject e) {
}
}
}
+
}
diff --git a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
index 28d737e440..763aa92e2f 100644
--- a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
+++ b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java
@@ -8,19 +8,38 @@
import net.sf.openrocket.document.Attachment;
+/**
+ *
+ * defines a file system attachment
+ * stores the attachment location
+ */
public class FileSystemAttachment extends Attachment {
-
+ /** the file location*/
private final File location;
+ /**
+ * main constructor,
+ *
+ * @param name name of attachment
+ * @param location File location of attachment
+ */
public FileSystemAttachment(String name, File location) {
super(name);
this.location = location;
}
+ /**
+ *
+ * @return the File object with the attachment location
+ */
public File getLocation() {
return location;
}
+ /**
+ * {@inheritDoc}
+ * creates the stream based on the location passed while building
+ */
@Override
public InputStream getBytes() throws FileNotFoundException, IOException {
return new FileInputStream(location);
diff --git a/core/src/net/sf/openrocket/file/DatabaseMotorFinder.java b/core/src/net/sf/openrocket/file/DatabaseMotorFinder.java
index 0232bbd1b1..a92e9f8e1b 100644
--- a/core/src/net/sf/openrocket/file/DatabaseMotorFinder.java
+++ b/core/src/net/sf/openrocket/file/DatabaseMotorFinder.java
@@ -1,5 +1,6 @@
package net.sf.openrocket.file;
+import java.util.Collections;
import java.util.List;
import net.sf.openrocket.aerodynamics.Warning;
@@ -45,12 +46,21 @@ public Motor findMotor(Type type, String manufacturer, String designation, doubl
return null;
}
- List extends Motor> motors = Application.getMotorSetDatabase().findMotors(type, manufacturer, designation, diameter, length);
+ List extends Motor> motors;
+
+ {
+ Motor m = Application.getMotorSetDatabase().findMotor(digest);
+ if (m != null) {
+ motors = Collections. singletonList(m);
+ } else {
+ motors = Application.getMotorSetDatabase().findMotors(type, manufacturer, designation, diameter, length);
+ }
+ }
// No motors
if (motors.size() == 0) {
return handleMissingMotor(type, manufacturer, designation, diameter, length, digest, warnings);
- }
+ }
// One motor
if (motors.size() == 1) {
diff --git a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
index 49f70c2ccc..f4e094328e 100644
--- a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
+++ b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
@@ -92,6 +92,7 @@ public final OpenRocketDocument load() throws RocketLoadException {
public final OpenRocketDocument load(InputStream source) throws RocketLoadException {
try {
loadStep1(source);
+ doc.getRocket().enableEvents();
return doc;
} catch (Exception e) {
throw new RocketLoadException("Exception loading stream: " + e.getMessage(), e);
@@ -146,7 +147,6 @@ private void loadStep1(InputStream source) throws IOException, RocketLoadExcepti
// Check for ZIP (for future compatibility)
if (buffer[0] == ZIP_SIGNATURE[0] && buffer[1] == ZIP_SIGNATURE[1]) {
- OpenRocketDocument doc;
isContainer = true;
setAttachmentFactory();
// Search for entry with name *.ork
@@ -158,11 +158,11 @@ private void loadStep1(InputStream source) throws IOException, RocketLoadExcepti
}
if (entry.getName().matches(".*\\.[oO][rR][kK]$")) {
loadRocket(in);
- return;
} else if (entry.getName().matches(".*\\.[rR][kK][tT]$")) {
loadRocket(in);
- return;
}
+ in.close();
+ return;
}
}
diff --git a/core/src/net/sf/openrocket/file/iterator/DirectoryIterator.java b/core/src/net/sf/openrocket/file/iterator/DirectoryIterator.java
index f1a28a8664..e80a1e2fd1 100644
--- a/core/src/net/sf/openrocket/file/iterator/DirectoryIterator.java
+++ b/core/src/net/sf/openrocket/file/iterator/DirectoryIterator.java
@@ -35,6 +35,7 @@ public class DirectoryIterator extends FileIterator {
*
* @param directory the directory to read.
* @param filter the filter for selecting files.
+ * @param recursive true for recursive search
* @throws IOException if the directory cannot be read.
*/
public DirectoryIterator(File directory, FileFilter filter, boolean recursive)
diff --git a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
index 842ce41fdd..478e9447a4 100644
--- a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
@@ -9,7 +9,7 @@
import java.util.Collections;
import java.util.List;
-import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.util.ArrayUtils;
import net.sf.openrocket.util.MathUtil;
@@ -23,7 +23,7 @@ public abstract class AbstractMotorLoader implements MotorLoader {
* returned by {@link #getDefaultCharset()}.
*/
@Override
- public List load(InputStream stream, String filename) throws IOException {
+ public List load(InputStream stream, String filename) throws IOException {
return load(new InputStreamReader(stream, getDefaultCharset()), filename);
}
@@ -37,7 +37,7 @@ public List load(InputStream stream, String filename) throws IOException
* @return a list of motors contained in the file.
* @throws IOException if an I/O exception occurs of the file format is invalid.
*/
- protected abstract List load(Reader reader, String filename) throws IOException;
+ protected abstract List load(Reader reader, String filename) throws IOException;
/**
diff --git a/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java b/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java
index 937c67903b..974a4afbd1 100644
--- a/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java
@@ -5,7 +5,7 @@
import java.util.List;
import net.sf.openrocket.file.UnknownFileTypeException;
-import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.ThrustCurveMotor;
/**
* A motor loader class that detects the file type based on the file name extension.
@@ -32,7 +32,7 @@ public GeneralMotorLoader() {
* @throws UnknownFileTypeException if the file format is not supported
*/
@Override
- public List load(InputStream stream, String filename) throws IOException {
+ public List load(InputStream stream, String filename) throws IOException {
return selectLoader(filename).load(stream, filename);
}
diff --git a/core/src/net/sf/openrocket/file/motor/MotorLoader.java b/core/src/net/sf/openrocket/file/motor/MotorLoader.java
index 46b3fb16a6..d945cf06d5 100644
--- a/core/src/net/sf/openrocket/file/motor/MotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/MotorLoader.java
@@ -5,10 +5,10 @@
import java.util.List;
import net.sf.openrocket.file.Loader;
-import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.ThrustCurveMotor;
-public interface MotorLoader extends Loader {
+public interface MotorLoader extends Loader {
/**
* Load motors from the specified InputStream.
@@ -20,6 +20,6 @@ public interface MotorLoader extends Loader {
* @throws IOException if an I/O exception occurs of the file format is invalid.
*/
@Override
- public List load(InputStream stream, String filename) throws IOException;
+ public List load(InputStream stream, String filename) throws IOException;
}
diff --git a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java
index 637aefae1b..26c102f71b 100644
--- a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java
@@ -42,8 +42,8 @@ protected Charset getDefaultCharset() {
* @throws IOException if an I/O error occurs or if the file format is illegal.
*/
@Override
- public List load(Reader reader, String filename) throws IOException {
- List motors = new ArrayList();
+ public List load(Reader reader, String filename) throws IOException {
+ List motors = new ArrayList<>();
BufferedReader in = new BufferedReader(reader);
String manufacturer = "";
@@ -108,7 +108,7 @@ public List load(Reader reader, String filename) throws IOException {
for (int i = 0; i < buf.length; i++) {
if (buf[i].equalsIgnoreCase("P") ||
buf[i].equalsIgnoreCase("plugged")) {
- delays.add(Motor.PLUGGED);
+ delays.add(Motor.PLUGGED_DELAY);
} else if (buf[i].matches("[0-9]+")) {
// Many RASP files have "100" as an only delay
double d = Double.parseDouble(buf[i]);
@@ -170,7 +170,7 @@ public List load(Reader reader, String filename) throws IOException {
* Create a motor from RASP file data.
* @throws IOException if the data is illegal for a thrust curve
*/
- private static Motor createRASPMotor(String manufacturer, String designation,
+ private static ThrustCurveMotor.Builder createRASPMotor(String manufacturer, String designation,
String comment, double length, double diameter, double[] delays,
double propW, double totalW, List time, List thrust)
throws IOException {
@@ -201,8 +201,19 @@ private static Motor createRASPMotor(String manufacturer, String designation,
try {
Manufacturer m = Manufacturer.getManufacturer(manufacturer);
- return new ThrustCurveMotor(m, designation, comment, m.getMotorType(),
- delays, diameter, length, timeArray, thrustArray, cgArray, digest);
+ ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder();
+ builder.setManufacturer(m)
+ .setDesignation(designation)
+ .setDescription(comment)
+ .setMotorType(m.getMotorType())
+ .setStandardDelays(delays)
+ .setDiameter(diameter)
+ .setLength(length)
+ .setTimePoints(timeArray)
+ .setThrustPoints(thrustArray)
+ .setCGPoints(cgArray)
+ .setDigest(digest);
+ return builder;
} catch (IllegalArgumentException e) {
diff --git a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
index 838e2d8fa6..b1fee26864 100644
--- a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
@@ -7,6 +7,11 @@
import java.util.HashMap;
import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
@@ -18,13 +23,9 @@
import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.MotorDigest.DataType;
import net.sf.openrocket.motor.ThrustCurveMotor;
+import net.sf.openrocket.motor.ThrustCurveMotor.Builder;
import net.sf.openrocket.util.Coordinate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
public class RockSimMotorLoader extends AbstractMotorLoader {
private static final Logger log = LoggerFactory.getLogger(RockSimMotorLoader.class);
@@ -60,7 +61,7 @@ protected Charset getDefaultCharset() {
* @throws IOException if an I/O error occurs or if the file format is invalid.
*/
@Override
- public List load(Reader reader, String filename) throws IOException {
+ public List load(Reader reader, String filename) throws IOException {
InputSource source = new InputSource(reader);
RSEHandler handler = new RSEHandler();
WarningSet warnings = new WarningSet();
@@ -79,11 +80,11 @@ public List load(Reader reader, String filename) throws IOException {
* Initial handler for the RockSim engine files.
*/
private static class RSEHandler extends AbstractElementHandler {
- private final List motors = new ArrayList();
+ private final List motors = new ArrayList<>();
private RSEMotorHandler motorHandler;
- public List getMotors() {
+ public List getMotors() {
return motors;
}
@@ -115,7 +116,7 @@ public void closeElement(String element, HashMap attributes,
String content, WarningSet warnings) throws SAXException {
if (element.equals("engine")) {
- Motor motor = motorHandler.getMotor();
+ ThrustCurveMotor.Builder motor = motorHandler.getMotor();
motors.add(motor);
}
}
@@ -173,12 +174,12 @@ public RSEMotorHandler(HashMap attributes) throws SAXException {
double d = Double.parseDouble(delay);
if (d >= DELAY_LIMIT)
- d = Motor.PLUGGED;
+ d = Motor.PLUGGED_DELAY;
delayList.add(d);
} catch (NumberFormatException e) {
if (str.equalsIgnoreCase("P") || str.equalsIgnoreCase("plugged")) {
- delayList.add(Motor.PLUGGED);
+ delayList.add(Motor.PLUGGED_DELAY);
}
}
}
@@ -320,7 +321,7 @@ public void closeElement(String element, HashMap attributes,
}
}
- public Motor getMotor() throws SAXException {
+ public Builder getMotor() throws SAXException {
if (time == null || time.size() == 0)
throw new SAXException("Illegal motor data");
@@ -380,8 +381,18 @@ public Motor getMotor() throws SAXException {
}
}
- return new ThrustCurveMotor(m, designation, description, t,
- delays, diameter, length, timeArray, thrustArray, cgArray, digest);
+ return new ThrustCurveMotor.Builder()
+ .setManufacturer(m)
+ .setDesignation(designation)
+ .setDescription(description)
+ .setMotorType(t)
+ .setStandardDelays(delays)
+ .setDiameter(diameter)
+ .setLength(length)
+ .setTimePoints(timeArray)
+ .setThrustPoints(thrustArray)
+ .setCGPoints(cgArray)
+ .setDigest(digest);
} catch (IllegalArgumentException e) {
throw new SAXException("Illegal motor data", e);
}
diff --git a/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java b/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java
index 193014588c..176da2dc61 100644
--- a/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java
@@ -11,7 +11,7 @@
import org.slf4j.LoggerFactory;
import net.sf.openrocket.file.UnknownFileTypeException;
-import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.util.UncloseableInputStream;
/**
@@ -44,8 +44,8 @@ public ZipFileMotorLoader(MotorLoader loader) {
@Override
- public List load(InputStream stream, String filename) throws IOException {
- List motors = new ArrayList();
+ public List load(InputStream stream, String filename) throws IOException {
+ List motors = new ArrayList<>();
ZipInputStream is = new ZipInputStream(stream);
@@ -71,7 +71,7 @@ public List load(InputStream stream, String filename) throws IOException
}
try {
- List m = loader.load(uncloseable, entry.getName());
+ List m = loader.load(uncloseable, entry.getName());
motors.addAll(m);
log.info("Loaded " + m.size() + " motors from ZIP entry " + entry.getName());
} catch (UnknownFileTypeException e) {
diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
index c22099caa1..ce929e85fd 100644
--- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
@@ -10,21 +10,16 @@
import java.util.List;
import java.util.Locale;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.document.StorageOptions;
import net.sf.openrocket.file.RocketSaver;
-import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
-import net.sf.openrocket.rocketcomponent.FinSet;
-import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
-import net.sf.openrocket.rocketcomponent.MotorMount;
-import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.Stage;
-import net.sf.openrocket.rocketcomponent.TubeCoupler;
-import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.simulation.FlightData;
import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType;
@@ -35,13 +30,9 @@
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.BuildProperties;
import net.sf.openrocket.util.Config;
-import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.Reflection;
import net.sf.openrocket.util.TextUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
public class OpenRocketSaver extends RocketSaver {
private static final Logger log = LoggerFactory.getLogger(OpenRocketSaver.class);
@@ -222,180 +213,65 @@ private int calculateNecessaryFileVersion(OpenRocketDocument document, StorageOp
/*
* NOTE: Remember to update the supported versions in DocumentConfig as well!
*
- * File version 1.7 is required for:
- * - simulation extensions
- * - saving tube fins.
- *
- * File version 1.6 is required for:
- * - saving files using appearances and textures, flight configurations.
- *
- * File version 1.5 is requires for:
- * - saving designs using ComponentPrests
- * - recovery device deployment on lower stage separation
- * - custom expressions
+ * File version 1.8 is required for:
+ * - new-style positioning
+ * - external/parallel booster stages
+ * - external pods
+ * - Rail Buttons
*
- * File version 1.4 is required for:
- * - saving simulation data
- * - saving motor data
- *
- * File version 1.1 is required for:
- * - fin tabs
- * - components attached to tube coupler
- *
- * Otherwise use version 1.0.
+ * Otherwise use version 1.8.
*/
/////////////////
- // Version 1.7 //
- /////////////////
- for (Simulation sim : document.getSimulations()) {
- if (!sim.getSimulationExtensions().isEmpty()) {
- return FILE_VERSION_DIVISOR + 7;
- }
- }
-
- // Search the rocket for any TubeFinSet objects (version 1.7)
- for (RocketComponent c : document.getRocket()) {
- if (c instanceof TubeFinSet) {
- return FILE_VERSION_DIVISOR + 7;
- }
- }
-
-
- /////////////////
- // Version 1.6 //
- /////////////////
-
- // Search the rocket for any Appearances or non-motor flight configurations (version 1.6)
- for (RocketComponent c : document.getRocket()) {
- if (c.getAppearance() != null) {
- return FILE_VERSION_DIVISOR + 6;
- }
- if (c instanceof FlightConfigurableComponent) {
- if (c instanceof MotorMount) {
- MotorMount mmt = (MotorMount) c;
- if (mmt.getIgnitionConfiguration().size() > 0) {
- return FILE_VERSION_DIVISOR + 6;
- }
- }
- if (c instanceof RecoveryDevice) {
- RecoveryDevice recovery = (RecoveryDevice) c;
- if (recovery.getDeploymentConfiguration().size() > 0) {
- return FILE_VERSION_DIVISOR + 6;
- }
- }
- if (c instanceof Stage) {
- Stage stage = (Stage) c;
- if (stage.getStageSeparationConfiguration().size() > 0) {
- return FILE_VERSION_DIVISOR + 6;
- }
- }
- }
- }
-
- /////////////////
- // Version 1.5 //
- /////////////////
-
- // Search the rocket for any ComponentPresets (version 1.5)
- for (RocketComponent c : document.getRocket()) {
- if (c.getPresetComponent() != null) {
- return FILE_VERSION_DIVISOR + 5;
- }
- }
-
- // Search for recovery device deployment type LOWER_STAGE_SEPARATION (version 1.5)
- for (RocketComponent c : document.getRocket()) {
- if (c instanceof RecoveryDevice) {
- if (((RecoveryDevice) c).getDeploymentConfiguration().getDefault().getDeployEvent() == DeployEvent.LOWER_STAGE_SEPARATION) {
- return FILE_VERSION_DIVISOR + 5;
- }
- }
- }
-
- // Check for custom expressions (version 1.5)
- if (!document.getCustomExpressions().isEmpty()) {
- return FILE_VERSION_DIVISOR + 5;
- }
-
- /////////////////
- // Version 1.4 //
+ // Version 1.8 //
/////////////////
+ // for any new-style positioning: 'axialoffset', 'angleoffset', 'radiusoffset' tags
+ // these tags are used for any RocketComponent child classes positioning... so... ALL the classes.
+ return FILE_VERSION_DIVISOR + 8;
- // Check if design has simulations defined (version 1.4)
- if (document.getSimulationCount() > 0) {
- return FILE_VERSION_DIVISOR + 4;
- }
-
- // Check for motor definitions (version 1.4)
- for (RocketComponent c : document.getRocket()) {
- if (!(c instanceof MotorMount))
- continue;
+ }
+
+
+ /**
+ * Finds a getElements method somewhere in the *saver class hiearchy corresponding to the given component.
+ */
+ private static Reflection.Method findGetElementsMethod(RocketComponent component) {
+ String currentclassname;
+ Class> currentclass;
+ String saverclassname;
+ Class> saverClass;
+
+ Reflection.Method mtr = null; // method-to-return
+
+ currentclass = component.getClass();
+ while ((currentclass != null) && (currentclass != Object.class)) {
+ currentclassname = currentclass.getSimpleName();
+ saverclassname = METHOD_PACKAGE + "." + currentclassname + METHOD_SUFFIX;
- MotorMount mount = (MotorMount) c;
- for (String id : document.getRocket().getFlightConfigurationIDs()) {
- if (mount.getMotor(id) != null) {
- return FILE_VERSION_DIVISOR + 4;
- }
- }
- }
-
- /////////////////
- // Version 1.3 //
- /////////////////
-
- // no version 1.3 file type exists
-
- /////////////////
- // Version 1.2 //
- /////////////////
-
- // no version 1.2 file type exists
-
- /////////////////
- // Version 1.1 //
- /////////////////
-
- // Check for fin tabs or tube coupler children (version 1.1)
- for (RocketComponent c : document.getRocket()) {
- // Check for fin tabs
- if (c instanceof FinSet) {
- FinSet fin = (FinSet) c;
- if (!MathUtil.equals(fin.getTabHeight(), 0) &&
- !MathUtil.equals(fin.getTabLength(), 0)) {
- return FILE_VERSION_DIVISOR + 1;
- }
+ try {
+ saverClass = Class.forName(saverclassname);
+
+ // if class exists
+ java.lang.reflect.Method m = saverClass.getMethod("getElements", RocketComponent.class);
+ mtr = new Reflection.Method(m);
+
+ return mtr;
+ } catch (Exception ignore) {
}
- // Check for components attached to tube coupler
- if (c instanceof TubeCoupler) {
- if (c.getChildCount() > 0) {
- return FILE_VERSION_DIVISOR + 1;
- }
- }
+ currentclass = currentclass.getSuperclass();
}
- /////////////////
- // Version 1.0 //
- /////////////////
-
- // Default (version 1.0)
- return FILE_VERSION_DIVISOR + 0;
+ // if( null == mtr ){
+ throw new BugException("Unable to find saving class for component " +
+ METHOD_PACKAGE + "." + component.getClass().getSimpleName() + " ... " + METHOD_SUFFIX);
}
-
-
@SuppressWarnings("unchecked")
private void saveComponent(RocketComponent component) throws IOException {
-
log.debug("Saving component " + component.getComponentName());
- Reflection.Method m = Reflection.findMethod(METHOD_PACKAGE, component, METHOD_SUFFIX,
- "getElements", RocketComponent.class);
- if (m == null) {
- throw new BugException("Unable to find saving class for component " +
- component.getComponentName());
- }
+ Reflection.Method m = findGetElementsMethod(component);
// Get the strings to save
List list = (List) m.invokeStatic(component);
@@ -454,7 +330,7 @@ private void saveSimulation(Simulation simulation, double timeSkip) throws IOExc
writeln("");
indent++;
- writeElement("configid", cond.getMotorConfigurationID());
+ writeElement("configid", simulation.getId().key);
writeElement("launchrodlength", cond.getLaunchRodLength());
writeElement("launchrodangle", cond.getLaunchRodAngle() * 180.0 / Math.PI);
writeElement("launchroddirection", cond.getLaunchRodDirection() * 360.0 / (2.0 * Math.PI));
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/AnglePositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/AnglePositionSetter.java
new file mode 100644
index 0000000000..06b6d97d2f
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/AnglePositionSetter.java
@@ -0,0 +1,38 @@
+package net.sf.openrocket.file.openrocket.importt;
+
+import java.util.HashMap;
+
+import net.sf.openrocket.aerodynamics.WarningSet;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.position.AngleMethod;
+import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
+
+class AnglePositionSetter implements Setter {
+
+ @Override
+ public void set(RocketComponent c, String value, HashMap attributes,
+ WarningSet warnings) {
+
+ AngleMethod method = (AngleMethod) DocumentConfig.findEnum(attributes.get("method"), AngleMethod.class);
+ if (null==method) {
+ method=AngleMethod.RELATIVE;
+ }
+
+ double pos;
+ try {
+ pos = Double.parseDouble(value) * Math.PI / 180.0 ;
+ } catch (NumberFormatException e) {
+ warnings.add(String.format("Warning: invalid value radius position. value=%s class: %s", value, c.getClass().getCanonicalName() ));
+ return;
+ }
+
+ if ( AnglePositionable.class.isAssignableFrom( c.getClass() ) ) {
+ AnglePositionable apc = (AnglePositionable)c;
+ apc.setAngleMethod(method);
+ apc.setAngleOffset(pos);
+ } else {
+ warnings.add(String.format("Warning: %s is not valid for class: %s", this.getClass().getCanonicalName(), c.getClass().getCanonicalName()));
+ }
+
+ }
+}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java
index 11b52f2ba5..b59cea9cdd 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java
@@ -51,7 +51,14 @@ public void closeElement(String element, HashMap attributes, Str
int red = Integer.parseInt(attributes.get("red"));
int green = Integer.parseInt(attributes.get("green"));
int blue = Integer.parseInt(attributes.get("blue"));
- builder.setPaint(new Color(red, green, blue));
+ int alpha = 255;//set default
+ // add a test if "alpha" was added to the XML / backwards compatibility
+ String a = attributes.get("alpha");
+ if (a != null){
+ // "alpha" string was present so load the value
+ alpha = Integer.parseInt(a);
+ }
+ builder.setPaint(new Color(red, green, blue, alpha));
return;
}
if ("shine".equals(element)) {
@@ -96,4 +103,4 @@ public void endHandler(String element, HashMap attributes,
super.endHandler(element, attributes, content, warnings);
}
-}
\ No newline at end of file
+}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/AxialPositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/AxialPositionSetter.java
new file mode 100644
index 0000000000..2fe5084a99
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/AxialPositionSetter.java
@@ -0,0 +1,45 @@
+package net.sf.openrocket.file.openrocket.importt;
+
+import java.util.HashMap;
+
+import net.sf.openrocket.aerodynamics.Warning;
+import net.sf.openrocket.aerodynamics.WarningSet;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.position.AxialMethod;
+import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
+class AxialPositionSetter implements Setter {
+
+ @Override
+ public void set(RocketComponent c, String value, HashMap attributes,
+ WarningSet warnings) {
+
+ // first check preferred attribute name:
+ AxialMethod type = (AxialMethod) DocumentConfig.findEnum(attributes.get("method"), AxialMethod.class);
+ // fall-back to old name
+ if (null == type) {
+ type = (AxialMethod) DocumentConfig.findEnum(attributes.get("type"), AxialMethod.class);
+ }
+
+ if (type == null) {
+ warnings.add(Warning.FILE_INVALID_PARAMETER);
+ return;
+ }
+
+ double pos;
+ try {
+ pos = Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ warnings.add(String.format("Warning: invalid value radius position. value=%s class: %s", value, c.getClass().getCanonicalName() ));
+ return;
+ }
+
+ if ( AxialPositionable.class.isAssignableFrom( c.getClass() ) ) {
+ AxialPositionable apc = (AxialPositionable)c;
+ apc.setAxialMethod(type);
+ apc.setAxialOffset(pos);
+ } else {
+ warnings.add(String.format("Warning: %s is not valid for class: %s", this.getClass().getCanonicalName(), c.getClass().getCanonicalName()));
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java
index 01e2bb3c79..7bc42fe546 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java
@@ -13,7 +13,7 @@
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.Stage;
+import net.sf.openrocket.rocketcomponent.AxialStage;
/**
* A handler that populates the parameters of a previously constructed rocket component.
@@ -61,6 +61,13 @@ public ElementHandler openElement(String element, HashMap attrib
}
return new MotorConfigurationHandler((Rocket) component, context);
}
+ if (element.equals("flightconfiguration")) {
+ if (!(component instanceof Rocket)) {
+ warnings.add(Warning.fromString("Illegal component defined for flight configuration."));
+ return null;
+ }
+ return new MotorConfigurationHandler((Rocket) component, context);
+ }
if ( element.equals("deploymentconfiguration")) {
if ( !(component instanceof RecoveryDevice) ) {
warnings.add(Warning.fromString("Illegal component defined as recovery device."));
@@ -69,11 +76,11 @@ public ElementHandler openElement(String element, HashMap attrib
return new DeploymentConfigurationHandler( (RecoveryDevice) component, context );
}
if ( element.equals("separationconfiguration")) {
- if ( !(component instanceof Stage) ) {
+ if ( !(component instanceof AxialStage) ) {
warnings.add(Warning.fromString("Illegal component defined as stage."));
return null;
}
- return new StageSeparationConfigurationHandler( (Stage) component, context );
+ return new StageSeparationConfigurationHandler( (AxialStage) component, context );
}
return PlainTextHandler.INSTANCE;
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java
index e40992bbbe..77b1573699 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java
@@ -2,6 +2,8 @@
import java.util.HashMap;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
@@ -10,10 +12,9 @@
import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
-import org.xml.sax.SAXException;
-
class DeploymentConfigurationHandler extends AbstractElementHandler {
private final RecoveryDevice recoveryDevice;
@@ -72,9 +73,9 @@ public void closeElement(String element, HashMap attributes, Str
@Override
public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException {
- String configId = attributes.get("configid");
- DeploymentConfiguration def = recoveryDevice.getDeploymentConfiguration().getDefault();
- recoveryDevice.getDeploymentConfiguration().set(configId, getConfiguration(def));
+ FlightConfigurationId configId = new FlightConfigurationId(attributes.get("configid"));
+ DeploymentConfiguration def = recoveryDevice.getDeploymentConfigurations().getDefault();
+ recoveryDevice.getDeploymentConfigurations().set(configId, getConfiguration(def));
}
}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
index 129f17bfeb..8393737f62 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
@@ -6,41 +6,9 @@
import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
-import net.sf.openrocket.rocketcomponent.BodyComponent;
-import net.sf.openrocket.rocketcomponent.BodyTube;
-import net.sf.openrocket.rocketcomponent.Bulkhead;
-import net.sf.openrocket.rocketcomponent.CenteringRing;
-import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
+import net.sf.openrocket.rocketcomponent.*;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
-import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
-import net.sf.openrocket.rocketcomponent.EngineBlock;
-import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
-import net.sf.openrocket.rocketcomponent.FinSet;
-import net.sf.openrocket.rocketcomponent.FreeformFinSet;
-import net.sf.openrocket.rocketcomponent.InnerTube;
-import net.sf.openrocket.rocketcomponent.LaunchLug;
-import net.sf.openrocket.rocketcomponent.MassComponent;
-import net.sf.openrocket.rocketcomponent.MassObject;
-import net.sf.openrocket.rocketcomponent.NoseCone;
-import net.sf.openrocket.rocketcomponent.Parachute;
-import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
-import net.sf.openrocket.rocketcomponent.RecoveryDevice;
-import net.sf.openrocket.rocketcomponent.ReferenceType;
-import net.sf.openrocket.rocketcomponent.RingComponent;
-import net.sf.openrocket.rocketcomponent.Rocket;
-import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.ShockCord;
-import net.sf.openrocket.rocketcomponent.Stage;
-import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
-import net.sf.openrocket.rocketcomponent.Streamer;
-import net.sf.openrocket.rocketcomponent.StructuralComponent;
-import net.sf.openrocket.rocketcomponent.SymmetricComponent;
-import net.sf.openrocket.rocketcomponent.ThicknessRingComponent;
-import net.sf.openrocket.rocketcomponent.Transition;
-import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
-import net.sf.openrocket.rocketcomponent.TubeCoupler;
-import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Color;
import net.sf.openrocket.util.LineStyle;
@@ -49,7 +17,7 @@
class DocumentConfig {
/* Remember to update OpenRocketSaver as well! */
- public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7" };
+ public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8" };
/**
* Divisor used in converting an integer version to the point-represented version.
@@ -72,6 +40,7 @@ class DocumentConfig {
constructors.put("freeformfinset", FreeformFinSet.class.getConstructor(new Class>[0]));
constructors.put("tubefinset", TubeFinSet.class.getConstructor(new Class>[0]));
constructors.put("launchlug", LaunchLug.class.getConstructor(new Class>[0]));
+ constructors.put("railbutton", RailButton.class.getConstructor(new Class>[0]));
// Internal components
constructors.put("engineblock", EngineBlock.class.getConstructor(new Class>[0]));
@@ -84,9 +53,13 @@ class DocumentConfig {
constructors.put("shockcord", ShockCord.class.getConstructor(new Class>[0]));
constructors.put("parachute", Parachute.class.getConstructor(new Class>[0]));
constructors.put("streamer", Streamer.class.getConstructor(new Class>[0]));
+ constructors.put("fueltank", FuelTank.class.getConstructor(new Class>[0]));
// Other
- constructors.put("stage", Stage.class.getConstructor(new Class>[0]));
+ constructors.put("stage", AxialStage.class.getConstructor(new Class>[0]));
+ constructors.put("boosterset", ParallelStage.class.getConstructor(new Class>[0]));
+ constructors.put("parallelstage", ParallelStage.class.getConstructor(new Class>[0]));
+ constructors.put("podset", PodSet.class.getConstructor(new Class>[0]));
} catch (NoSuchMethodException e) {
throw new BugException(
@@ -111,13 +84,17 @@ class DocumentConfig {
setters.put("RocketComponent:linestyle", new EnumSetter(
Reflection.findMethod(RocketComponent.class, "setLineStyle", LineStyle.class),
LineStyle.class));
- setters.put("RocketComponent:position", new PositionSetter());
+ setters.put("RocketComponent:position", new AxialPositionSetter() );
+ setters.put("RocketComponent:axialoffset", new AxialPositionSetter() );
setters.put("RocketComponent:overridemass", new OverrideSetter(
Reflection.findMethod(RocketComponent.class, "setOverrideMass", double.class),
Reflection.findMethod(RocketComponent.class, "setMassOverridden", boolean.class)));
setters.put("RocketComponent:overridecg", new OverrideSetter(
Reflection.findMethod(RocketComponent.class, "setOverrideCGX", double.class),
Reflection.findMethod(RocketComponent.class, "setCGOverridden", boolean.class)));
+ setters.put("RocketComponent:overridecd", new OverrideSetter(
+ Reflection.findMethod(RocketComponent.class, "setOverrideCD", double.class),
+ Reflection.findMethod(RocketComponent.class, "setCDOverridden", boolean.class)));
setters.put("RocketComponent:overridesubcomponents", new BooleanSetter(
Reflection.findMethod(RocketComponent.class, "setOverrideSubcomponents", boolean.class)));
setters.put("RocketComponent:comment", new StringSetter(
@@ -125,6 +102,7 @@ class DocumentConfig {
setters.put("RocketComponent:preset", new ComponentPresetSetter(
Reflection.findMethod(RocketComponent.class, "loadPreset", ComponentPreset.class)));
+
// ExternalComponent
setters.put("ExternalComponent:finish", new EnumSetter(
Reflection.findMethod(ExternalComponent.class, "setFinish", Finish.class),
@@ -136,19 +114,51 @@ class DocumentConfig {
// BodyComponent
setters.put("BodyComponent:length", new DoubleSetter(
Reflection.findMethod(BodyComponent.class, "setLength", double.class)));
-
- // SymmetricComponent
- setters.put("SymmetricComponent:thickness", new DoubleSetter(
- Reflection.findMethod(SymmetricComponent.class, "setThickness", double.class),
- "filled",
- Reflection.findMethod(SymmetricComponent.class, "setFilled", boolean.class)));
-
+
// BodyTube
setters.put("BodyTube:radius", new DoubleSetter(
Reflection.findMethod(BodyTube.class, "setOuterRadius", double.class),
"auto",
Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class)));
+
+ // Parallel Stage
+ setters.put("ParallelStage:instancecount", new IntSetter(
+ Reflection.findMethod(ParallelStage.class, "setInstanceCount",int.class)));
+ setters.put("ParallelStage:angleoffset", new AnglePositionSetter());
+ setters.put("ParallelStage:radiusoffset", new RadiusPositionSetter());
+
+ // SymmetricComponent
+ setters.put("SymmetricComponent:thickness", new DoubleSetter(
+ Reflection.findMethod(SymmetricComponent.class, "setThickness", double.class),
+ "filled",
+ Reflection.findMethod(SymmetricComponent.class, "setFilled", boolean.class)));
+ // LaunchLug
+ setters.put("LaunchLug:instancecount", new IntSetter(
+ Reflection.findMethod( LaunchLug.class, "setInstanceCount",int.class)));
+ setters.put("LaunchLug:instanceseparation", new DoubleSetter(
+ Reflection.findMethod( LaunchLug.class, "setInstanceSeparation", double.class)));
+ setters.put("LaunchLug:radialdirection", new DoubleSetter(
+ Reflection.findMethod( LaunchLug.class, "setAngleOffset", double.class), Math.PI / 180.0));
+ setters.put("LaunchLug:angleoffset", new AnglePositionSetter() );
+ setters.put("LaunchLug:radius", new DoubleSetter(
+ Reflection.findMethod(LaunchLug.class, "setOuterRadius", double.class)));
+ setters.put("LaunchLug:length", new DoubleSetter(
+ Reflection.findMethod(LaunchLug.class, "setLength", double.class)));
+ setters.put("LaunchLug:thickness", new DoubleSetter(
+ Reflection.findMethod(LaunchLug.class, "setThickness", double.class)));
+
+ // RailButton
+ setters.put("RailButton:instancecount", new IntSetter(
+ Reflection.findMethod( RailButton.class, "setInstanceCount",int.class)));
+ setters.put("RailButton:instanceseparation", new DoubleSetter(
+ Reflection.findMethod( RailButton.class, "setInstanceSeparation", double.class)));
+ setters.put("RailButton:angleoffset", new AnglePositionSetter() );
+ setters.put("RailButton:height", new DoubleSetter(
+ Reflection.findMethod( RailButton.class, "setTotalHeight", double.class)));
+ setters.put("RailButton:outerdiameter", new DoubleSetter(
+ Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class)));
+
// Transition
setters.put("Transition:shape", new EnumSetter(
Reflection.findMethod(Transition.class, "setType", Transition.Shape.class),
@@ -195,8 +205,12 @@ class DocumentConfig {
// FinSet
setters.put("FinSet:fincount", new IntSetter(
Reflection.findMethod(FinSet.class, "setFinCount", int.class)));
+ setters.put("FinSet:instancecount", new IntSetter(
+ Reflection.findMethod(FinSet.class, "setInstanceCount", int.class)));
setters.put("FinSet:rotation", new DoubleSetter(
Reflection.findMethod(FinSet.class, "setBaseRotation", double.class), Math.PI / 180.0));
+ setters.put("FinSet:angleoffset", new AnglePositionSetter() );
+ setters.put("FinSet:radiusoffset", new RadiusPositionSetter() );
setters.put("FinSet:thickness", new DoubleSetter(
Reflection.findMethod(FinSet.class, "setThickness", double.class)));
setters.put("FinSet:crosssection", new EnumSetter(
@@ -214,6 +228,7 @@ class DocumentConfig {
setters.put("FinSet:filletmaterial", new MaterialSetter(
Reflection.findMethod(FinSet.class, "setFilletMaterial", Material.class),
Material.Type.BULK));
+
// TrapezoidFinSet
setters.put("TrapezoidFinSet:rootchord", new DoubleSetter(
Reflection.findMethod(TrapezoidFinSet.class, "setRootChord", double.class)));
@@ -246,17 +261,6 @@ class DocumentConfig {
"auto",
Reflection.findMethod(TubeFinSet.class, "setOuterRadiusAutomatic", boolean.class)));
- // LaunchLug
- setters.put("LaunchLug:radius", new DoubleSetter(
- Reflection.findMethod(LaunchLug.class, "setOuterRadius", double.class)));
- setters.put("LaunchLug:length", new DoubleSetter(
- Reflection.findMethod(LaunchLug.class, "setLength", double.class)));
- setters.put("LaunchLug:thickness", new DoubleSetter(
- Reflection.findMethod(LaunchLug.class, "setThickness", double.class)));
- setters.put("LaunchLug:radialdirection", new DoubleSetter(
- Reflection.findMethod(LaunchLug.class, "setRadialDirection", double.class),
- Math.PI / 180.0));
-
// InternalComponent - nothing
// StructuralComponent
@@ -300,6 +304,10 @@ class DocumentConfig {
Math.PI / 180.0));
// RadiusRingComponent
+ setters.put("RadiusRingComponent:instancecount", new IntSetter(
+ Reflection.findMethod( RadiusRingComponent.class, "setInstanceCount",int.class)));
+ setters.put("RadiusRingComponent:instanceseparation", new DoubleSetter(
+ Reflection.findMethod( RadiusRingComponent.class, "setInstanceSeparation", double.class)));
// Bulkhead
setters.put("RadiusRingComponent:innerradius", new DoubleSetter(
@@ -319,7 +327,6 @@ class DocumentConfig {
"auto",
Reflection.findMethod(CenteringRing.class, "setOuterRadiusAutomatic", boolean.class)));
-
// MassObject
setters.put("MassObject:packedlength", new DoubleSetter(
Reflection.findMethod(MassObject.class, "setLength", double.class)));
@@ -342,6 +349,17 @@ class DocumentConfig {
/* setters.put("Transition:shape", new EnumSetter(
Reflection.findMethod(Transition.class, "setType", Transition.Shape.class),
Transition.Shape.class));*/
+
+ // FuelTank
+ setters.put("FuelTank:packedmass", new DoubleSetter(
+ Reflection.findMethod(FuelTank.class, "setComponentMass", double.class)));
+ setters.put("FuelTank:packedfuelqty", new DoubleSetter(
+ Reflection.findMethod(FuelTank.class, "setFuelQty", double.class)));
+ setters.put("FuelTank:packedburnrate", new DoubleSetter(
+ Reflection.findMethod(FuelTank.class, "setBurnRate", double.class)));
+ setters.put("FuelTank:packedfueltype", new EnumSetter(
+ Reflection.findMethod(FuelTank.class, "setFuelType", FuelTank.FuelType.class),
+ FuelTank.FuelType.class));
// ShockCord
setters.put("ShockCord:cordlength", new DoubleSetter(
@@ -356,14 +374,14 @@ class DocumentConfig {
"auto",
Reflection.findMethod(RecoveryDevice.class, "setCDAutomatic", boolean.class)));
setters.put("RecoveryDevice:deployevent", new EnumSetter(
- Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
+ Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfigurations"),
Reflection.findMethod(DeploymentConfiguration.class, "setDeployEvent", DeployEvent.class),
DeployEvent.class));
setters.put("RecoveryDevice:deployaltitude", new DoubleSetter(
- Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
+ Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfigurations"),
Reflection.findMethod(DeploymentConfiguration.class, "setDeployAltitude", double.class)));
setters.put("RecoveryDevice:deploydelay", new DoubleSetter(
- Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
+ Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfigurations"),
Reflection.findMethod(DeploymentConfiguration.class, "setDeployDelay", double.class)));
setters.put("RecoveryDevice:material", new MaterialSetter(
Reflection.findMethod(RecoveryDevice.class, "setMaterial", Material.class),
@@ -380,6 +398,12 @@ class DocumentConfig {
Reflection.findMethod(Parachute.class, "setLineMaterial", Material.class),
Material.Type.LINE));
+ // PodSet
+ setters.put("PodSet:instancecount", new IntSetter(
+ Reflection.findMethod(PodSet.class, "setInstanceCount",int.class)));
+ setters.put("PodSet:radiusoffset", new RadiusPositionSetter() );
+ setters.put("PodSet:angleoffset", new AnglePositionSetter() );
+
// Streamer
setters.put("Streamer:striplength", new DoubleSetter(
Reflection.findMethod(Streamer.class, "setStripLength", double.class)));
@@ -398,14 +422,15 @@ class DocumentConfig {
setters.put("Rocket:revision", new StringSetter(
Reflection.findMethod(Rocket.class, "setRevision", String.class)));
- // Stage
- setters.put("Stage:separationevent", new EnumSetter(
- Reflection.findMethod(Stage.class, "getStageSeparationConfiguration"),
+ // Axial Stage
+ setters.put("AxialStage:separationevent", new EnumSetter(
+ Reflection.findMethod(AxialStage.class, "getSeparationConfigurations"),
Reflection.findMethod(StageSeparationConfiguration.class, "setSeparationEvent", StageSeparationConfiguration.SeparationEvent.class),
StageSeparationConfiguration.SeparationEvent.class));
- setters.put("Stage:separationdelay", new DoubleSetter(
- Reflection.findMethod(Stage.class, "getStageSeparationConfiguration"),
+ setters.put("AxialStage:separationdelay", new DoubleSetter(
+ Reflection.findMethod(AxialStage.class, "getSeparationConfigurations"),
Reflection.findMethod(StageSeparationConfiguration.class, "setSeparationDelay", double.class)));
+
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java
index 9fdd3e9f36..5d553b57b5 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java
@@ -4,7 +4,7 @@
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurableParameterSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Reflection;
import net.sf.openrocket.util.Reflection.Method;
@@ -94,7 +94,7 @@ public void set(RocketComponent c, String s, HashMap attributes,
if (configGetter == null) {
setMethod.invoke(c, d * multiplier);
} else {
- FlightConfiguration> config = (FlightConfiguration>) configGetter.invoke(c);
+ FlightConfigurableParameterSet> config = (FlightConfigurableParameterSet>) configGetter.invoke(c);
Object obj = config.getDefault();
setMethod.invoke(obj, d * multiplier);
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/EnumSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/EnumSetter.java
index 55ceaac347..3156c1dd2d 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/EnumSetter.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/EnumSetter.java
@@ -4,7 +4,7 @@
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurableParameterSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Reflection;
import net.sf.openrocket.util.Reflection.Method;
@@ -38,7 +38,7 @@ public void set(RocketComponent c, String name, HashMap attribut
if (configurationGetter == null) {
setter.invoke(c, setEnum);
} else {
- FlightConfiguration> config = (FlightConfiguration>) configurationGetter.invoke(c);
+ FlightConfigurableParameterSet> config = (FlightConfigurableParameterSet>) configurationGetter.invoke(c);
Object obj = config.getDefault();
setter.invoke(obj, setEnum);
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java
index 9d99412708..50dd7f10d3 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java
@@ -3,6 +3,8 @@
import java.util.ArrayList;
import java.util.HashMap;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
@@ -10,11 +12,8 @@
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
-import net.sf.openrocket.rocketcomponent.IllegalFinPointException;
import net.sf.openrocket.util.Coordinate;
-import org.xml.sax.SAXException;
-
/**
* A handler that reads the specifications within the freeformfinset's
* elements.
@@ -62,10 +61,7 @@ public void closeElement(String element, HashMap attributes,
@Override
public void endHandler(String element, HashMap attributes,
String content, WarningSet warnings) {
- try {
- finset.setPoints(coordinates.toArray(new Coordinate[0]));
- } catch (IllegalFinPointException e) {
- warnings.add(Warning.fromString("Freeform fin set point definitions illegal, ignoring."));
- }
+ finset.setPoints(coordinates.toArray(new Coordinate[0]));
+
}
}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
index f6e046d190..b0e3fda77b 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
@@ -5,13 +5,13 @@
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.FinSet.TabRelativePosition;
+import net.sf.openrocket.rocketcomponent.position.*;
import net.sf.openrocket.util.Reflection;
class FinTabPositionSetter extends DoubleSetter {
public FinTabPositionSetter() {
- super(Reflection.findMethod(FinSet.class, "setTabShift", double.class));
+ super(Reflection.findMethod(FinSet.class, "setTabOffset", double.class));
}
@Override
@@ -23,23 +23,30 @@ public void set(RocketComponent c, String s, HashMap attributes,
}
String relative = attributes.get("relativeto");
- FinSet.TabRelativePosition position =
- (TabRelativePosition) DocumentConfig.findEnum(relative,
- FinSet.TabRelativePosition.class);
- if (position != null) {
+ if (relative == null) {
+ warnings.add("Required attribute 'relativeto' not found for fin tab position.");
+ } else {
+ // translate from old enum names to current enum names
+ if( relative.contains("front")){
+ relative = "top";
+ }else if( relative.contains("center")){
+ relative = "middle";
+ }else if( relative.contains("end")){
+ relative = "bottom";
+ }
- ((FinSet) c).setTabRelativePosition(position);
+ AxialMethod position = (AxialMethod) DocumentConfig.findEnum(relative, AxialMethod.class);
- } else {
- if (relative == null) {
- warnings.add("Required attribute 'relativeto' not found for fin tab position.");
- } else {
+ if( null == position ){
warnings.add("Illegal attribute value '" + relative + "' encountered.");
+ }else{
+ ((FinSet) c).setTabOffsetMethod(position);
+ super.set(c, s, attributes, warnings);
}
+
}
- super.set(c, s, attributes, warnings);
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java
index ee02dbc079..10d5c6b1aa 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java
@@ -1,7 +1,8 @@
package net.sf.openrocket.file.openrocket.importt;
import java.util.HashMap;
-import java.util.Locale;
+
+import org.xml.sax.SAXException;
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
@@ -9,41 +10,25 @@
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
-import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
-import net.sf.openrocket.rocketcomponent.IgnitionConfiguration.IgnitionEvent;
-
-import org.xml.sax.SAXException;
+import net.sf.openrocket.motor.IgnitionEvent;
class IgnitionConfigurationHandler extends AbstractElementHandler {
- private Double ignitionDelay = null;
- private IgnitionEvent ignitionEvent = null;
+ // TODO: this is pretty hacky and should be fixed eventually
+ public Double ignitionDelay = null;
+ public IgnitionEvent ignitionEvent = null;
public IgnitionConfigurationHandler(DocumentLoadingContext context) {
}
-
@Override
public ElementHandler openElement(String element, HashMap attributes,
WarningSet warnings) {
return PlainTextHandler.INSTANCE;
}
-
- public IgnitionConfiguration getConfiguration(IgnitionConfiguration def) {
- IgnitionConfiguration config = def.clone();
- if (ignitionEvent != null) {
- config.setIgnitionEvent(ignitionEvent);
- }
- if (ignitionDelay != null) {
- config.setIgnitionDelay(ignitionDelay);
- }
- return config;
- }
-
-
@Override
public void closeElement(String element, HashMap attributes,
String content, WarningSet warnings) throws SAXException {
@@ -51,10 +36,10 @@ public void closeElement(String element, HashMap attributes,
content = content.trim();
if (element.equals("ignitionevent")) {
-
- for (IgnitionEvent e : IgnitionEvent.values()) {
- if (e.name().toLowerCase(Locale.ENGLISH).replaceAll("_", "").equals(content)) {
- ignitionEvent = e;
+
+ for (IgnitionEvent ie : IgnitionEvent.values()) {
+ if (ie.equals(content)) {
+ ignitionEvent = ie;
break;
}
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java
index 43d08626d5..5aaa42cc33 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java
@@ -2,16 +2,18 @@
import java.util.HashMap;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
+import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket;
-import org.xml.sax.SAXException;
-
class MotorConfigurationHandler extends AbstractElementHandler {
@SuppressWarnings("unused")
private final DocumentLoadingContext context;
@@ -47,23 +49,20 @@ public void closeElement(String element, HashMap attributes,
public void endHandler(String element, HashMap attributes,
String content, WarningSet warnings) throws SAXException {
- String configid = attributes.remove("configid");
- if (configid == null || configid.equals("")) {
+ FlightConfigurationId fcid = new FlightConfigurationId(attributes.remove("configid"));
+ if (!fcid.isValid()) {
warnings.add(Warning.FILE_INVALID_PARAMETER);
return;
}
- if (!rocket.addMotorConfigurationID(configid)) {
- warnings.add("Duplicate motor configuration ID used.");
- return;
- }
+ rocket.createFlightConfiguration(fcid);
if (name != null && name.trim().length() > 0) {
- rocket.setFlightConfigurationName(configid, name);
+ rocket.getFlightConfiguration(fcid).setName(name);
}
if ("true".equals(attributes.remove("default"))) {
- rocket.getDefaultConfiguration().setFlightConfigurationID(configid);
+ rocket.setSelectedConfiguration( fcid);
}
super.closeElement(element, attributes, content, warnings);
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java
index dccd1fb894..e11247c3eb 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java
@@ -51,7 +51,7 @@ public Motor getMotor(WarningSet warnings) {
public double getDelay(WarningSet warnings) {
if (Double.isNaN(delay)) {
warnings.add(Warning.fromString("Motor delay not specified, assuming no ejection charge."));
- return Motor.PLUGGED;
+ return Motor.PLUGGED_DELAY;
}
return delay;
}
@@ -124,7 +124,7 @@ public void closeElement(String element, HashMap attributes,
// Delay
delay = Double.NaN;
if (content.equals("none")) {
- delay = Motor.PLUGGED;
+ delay = Motor.PLUGGED_DELAY;
} else {
try {
delay = Double.parseDouble(content.trim());
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java
index e723edab11..93b51fd085 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java
@@ -1,7 +1,8 @@
package net.sf.openrocket.file.openrocket.importt;
import java.util.HashMap;
-import java.util.Locale;
+
+import org.xml.sax.SAXException;
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
@@ -9,11 +10,13 @@
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
-import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
-import net.sf.openrocket.rocketcomponent.MotorConfiguration;
+import net.sf.openrocket.motor.IgnitionEvent;
+import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.MotorConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.MotorMount;
-
-import org.xml.sax.SAXException;
+import net.sf.openrocket.rocketcomponent.Rocket;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
class MotorMountHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
@@ -37,7 +40,7 @@ public ElementHandler openElement(String element, HashMap attrib
}
if (element.equals("ignitionconfiguration")) {
- ignitionConfigHandler = new IgnitionConfigurationHandler(context);
+ ignitionConfigHandler = new IgnitionConfigurationHandler( context);
return ignitionConfigHandler;
}
@@ -56,39 +59,47 @@ public ElementHandler openElement(String element, HashMap attrib
@Override
public void closeElement(String element, HashMap attributes,
String content, WarningSet warnings) throws SAXException {
+
+ // DEBUG ONLY
+ // System.err.println("closing MotorMount element: "+ element);
if (element.equals("motor")) {
- String id = attributes.get("configid");
- if (id == null || id.equals("")) {
+ FlightConfigurationId fcid = new FlightConfigurationId(attributes.get("configid"));
+ if (!fcid.isValid()) {
warnings.add(Warning.fromString("Illegal motor specification, ignoring."));
return;
}
+ Motor motor = motorHandler.getMotor(warnings);
+ MotorConfiguration motorConfig = new MotorConfiguration( mount, fcid, mount.getDefaultMotorConfig());
+ motorConfig.setMotor(motor);
+ motorConfig.setEjectionDelay(motorHandler.getDelay(warnings));
- MotorConfiguration config = new MotorConfiguration();
- config.setMotor(motorHandler.getMotor(warnings));
- config.setEjectionDelay(motorHandler.getDelay(warnings));
- mount.getMotorConfiguration().set(id, config);
-
+ mount.setMotorConfig( motorConfig, fcid);
+
+ Rocket rkt = ((RocketComponent)mount).getRocket();
+ rkt.createFlightConfiguration(fcid);
+ rkt.getFlightConfiguration(fcid).addMotor(motorConfig);
return;
}
if (element.equals("ignitionconfiguration")) {
- String id = attributes.get("configid");
- if (id == null || id.equals("")) {
+ FlightConfigurationId fcid = new FlightConfigurationId(attributes.get("configid"));
+ if ( ! fcid.isValid()){
warnings.add(Warning.fromString("Illegal motor specification, ignoring."));
return;
}
- IgnitionConfiguration def = mount.getIgnitionConfiguration().getDefault();
- mount.getIgnitionConfiguration().set(id, ignitionConfigHandler.getConfiguration(def));
+ MotorConfiguration inst = mount.getMotorConfig(fcid);
+ inst.setIgnitionDelay(ignitionConfigHandler.ignitionDelay);
+ inst.setIgnitionEvent(ignitionConfigHandler.ignitionEvent);
return;
}
if (element.equals("ignitionevent")) {
- IgnitionConfiguration.IgnitionEvent event = null;
- for (IgnitionConfiguration.IgnitionEvent e : IgnitionConfiguration.IgnitionEvent.values()) {
- if (e.name().toLowerCase(Locale.ENGLISH).replaceAll("_", "").equals(content)) {
- event = e;
+ IgnitionEvent event = null;
+ for (IgnitionEvent ie : IgnitionEvent.values()) {
+ if (ie.equals(content)) {
+ event = ie;
break;
}
}
@@ -96,7 +107,9 @@ public void closeElement(String element, HashMap attributes,
warnings.add(Warning.fromString("Unknown ignition event type '" + content + "', ignoring."));
return;
}
- mount.getIgnitionConfiguration().getDefault().setIgnitionEvent(event);
+
+ mount.getDefaultMotorConfig().setIgnitionEvent(event);
+
return;
}
@@ -108,7 +121,8 @@ public void closeElement(String element, HashMap attributes,
warnings.add(Warning.fromString("Illegal ignition delay specified, ignoring."));
return;
}
- mount.getIgnitionConfiguration().getDefault().setIgnitionDelay(d);
+
+ mount.getDefaultMotorConfig().setIgnitionDelay(d);
return;
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java
index ccc6329c90..a7a2839c60 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java
@@ -4,6 +4,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument;
@@ -11,8 +15,6 @@
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
-import org.xml.sax.SAXException;
-
/**
* The starting point of the handlers. Accepts a single element and hands
* the contents to be read by a OpenRocketContentsHandler.
@@ -21,6 +23,8 @@ class OpenRocketHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private OpenRocketContentHandler handler = null;
+ private static final Logger log = LoggerFactory.getLogger(OpenRocketHandler.class);
+
public OpenRocketHandler(DocumentLoadingContext context) {
this.context = context;
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java
index 8bfba9ae7f..7662c80ade 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java
@@ -53,7 +53,7 @@ public void loadFromStream(DocumentLoadingContext context, InputStream source) t
throw new RocketLoadException("Malformed XML in input.", e);
}
- doc.getDefaultConfiguration().setAllStages();
+ doc.getSelectedConfiguration().setAllStages();
// Deduce suitable time skip
double timeSkip = StorageOptions.SIMULATION_DATA_NONE;
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java
deleted file mode 100644
index ad29d1e35f..0000000000
--- a/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.sf.openrocket.file.openrocket.importt;
-
-import java.util.HashMap;
-
-import net.sf.openrocket.aerodynamics.Warning;
-import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.rocketcomponent.FinSet;
-import net.sf.openrocket.rocketcomponent.InternalComponent;
-import net.sf.openrocket.rocketcomponent.LaunchLug;
-import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
-import net.sf.openrocket.rocketcomponent.TubeFinSet;
-
-class PositionSetter implements Setter {
-
- @Override
- public void set(RocketComponent c, String value, HashMap attributes,
- WarningSet warnings) {
-
- RocketComponent.Position type = (Position) DocumentConfig.findEnum(attributes.get("type"),
- RocketComponent.Position.class);
- if (type == null) {
- warnings.add(Warning.FILE_INVALID_PARAMETER);
- return;
- }
-
- double pos;
- try {
- pos = Double.parseDouble(value);
- } catch (NumberFormatException e) {
- warnings.add(Warning.FILE_INVALID_PARAMETER);
- return;
- }
-
- if (c instanceof FinSet) {
- ((FinSet) c).setRelativePosition(type);
- c.setPositionValue(pos);
- } else if (c instanceof LaunchLug) {
- ((LaunchLug) c).setRelativePosition(type);
- c.setPositionValue(pos);
- } else if (c instanceof InternalComponent) {
- ((InternalComponent) c).setRelativePosition(type);
- c.setPositionValue(pos);
- } else if (c instanceof TubeFinSet) {
- ((TubeFinSet) c).setRelativePosition(type);
- c.setPositionValue(pos);
- } else {
- warnings.add(Warning.FILE_INVALID_PARAMETER);
- }
-
- }
-}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/RadiusPositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/RadiusPositionSetter.java
new file mode 100644
index 0000000000..bd4f364042
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/RadiusPositionSetter.java
@@ -0,0 +1,39 @@
+package net.sf.openrocket.file.openrocket.importt;
+
+import java.util.HashMap;
+
+import net.sf.openrocket.aerodynamics.WarningSet;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
+import net.sf.openrocket.rocketcomponent.position.RadiusPositionable;
+
+class RadiusPositionSetter implements Setter {
+
+ @Override
+ public void set(RocketComponent c, String value, HashMap attributes,
+ WarningSet warnings) {
+
+ RadiusMethod method = (RadiusMethod) DocumentConfig.findEnum(attributes.get("method"), RadiusMethod.class);
+ if (method == null) {
+ method = RadiusMethod.SURFACE;
+ }
+
+
+ double offset;
+ try {
+ offset = Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ warnings.add(String.format("Warning: invalid value radius position. value=%s class: %s", value, c.getClass().getCanonicalName() ));
+ return;
+ }
+
+ if ( RadiusPositionable.class.isAssignableFrom( c.getClass() ) ) {
+ RadiusPositionable rp = (RadiusPositionable)c;
+ rp.setRadiusMethod(method);
+ rp.setRadiusOffset(offset);
+ } else {
+ warnings.add("Warning: radiusPositionable is not valid for this class: "+c.getClass().getCanonicalName());
+ }
+
+ }
+}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
index 2094b0320d..27b72c8db5 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java
@@ -7,24 +7,26 @@
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.simulation.SimulationOptions;
import net.sf.openrocket.util.GeodeticComputationStrategy;
class SimulationConditionsHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
- private SimulationOptions conditions;
+ public FlightConfigurationId idToSet = FlightConfigurationId.ERROR_FCID;
+ private SimulationOptions options;
private AtmosphereHandler atmosphereHandler;
public SimulationConditionsHandler(Rocket rocket, DocumentLoadingContext context) {
this.context = context;
- conditions = new SimulationOptions(rocket);
+ options = new SimulationOptions();
// Set up default loading settings (which may differ from the new defaults)
- conditions.setGeodeticComputation(GeodeticComputationStrategy.FLAT);
+ options.setGeodeticComputation(GeodeticComputationStrategy.FLAT);
}
public SimulationOptions getConditions() {
- return conditions;
+ return options;
}
@Override
@@ -49,74 +51,70 @@ public void closeElement(String element, HashMap attributes,
if (element.equals("configid")) {
- if (content.equals("")) {
- conditions.setMotorConfigurationID(null);
- } else {
- conditions.setMotorConfigurationID(content);
- }
+ this.idToSet= new FlightConfigurationId(content);
} else if (element.equals("launchrodlength")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch rod length defined, ignoring.");
} else {
- conditions.setLaunchRodLength(d);
+ options.setLaunchRodLength(d);
}
} else if (element.equals("launchrodangle")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch rod angle defined, ignoring.");
} else {
- conditions.setLaunchRodAngle(d * Math.PI / 180);
+ options.setLaunchRodAngle(d * Math.PI / 180);
}
} else if (element.equals("launchroddirection")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch rod direction defined, ignoring.");
} else {
- conditions.setLaunchRodDirection(d * 2.0 * Math.PI / 360);
+ options.setLaunchRodDirection(d * 2.0 * Math.PI / 360);
}
} else if (element.equals("windaverage")) {
if (Double.isNaN(d)) {
warnings.add("Illegal average windspeed defined, ignoring.");
} else {
- conditions.setWindSpeedAverage(d);
+ options.setWindSpeedAverage(d);
}
} else if (element.equals("windturbulence")) {
if (Double.isNaN(d)) {
warnings.add("Illegal wind turbulence intensity defined, ignoring.");
} else {
- conditions.setWindTurbulenceIntensity(d);
+ options.setWindTurbulenceIntensity(d);
}
} else if (element.equals("launchaltitude")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch altitude defined, ignoring.");
} else {
- conditions.setLaunchAltitude(d);
+ options.setLaunchAltitude(d);
}
} else if (element.equals("launchlatitude")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch latitude defined, ignoring.");
} else {
- conditions.setLaunchLatitude(d);
+ options.setLaunchLatitude(d);
}
} else if (element.equals("launchlongitude")) {
if (Double.isNaN(d)) {
warnings.add("Illegal launch longitude.");
} else {
- conditions.setLaunchLongitude(d);
+ options.setLaunchLongitude(d);
}
} else if (element.equals("geodeticmethod")) {
GeodeticComputationStrategy gcs =
(GeodeticComputationStrategy) DocumentConfig.findEnum(content, GeodeticComputationStrategy.class);
if (gcs != null) {
- conditions.setGeodeticComputation(gcs);
+ options.setGeodeticComputation(gcs);
} else {
warnings.add("Unknown geodetic computation method '" + content + "'");
}
} else if (element.equals("atmosphere")) {
- atmosphereHandler.storeSettings(conditions, warnings);
+ atmosphereHandler.storeSettings(options, warnings);
} else if (element.equals("timestep")) {
if (Double.isNaN(d) || d <= 0) {
warnings.add("Illegal time step defined, ignoring.");
} else {
- conditions.setTimeStep(d);
+ options.setTimeStep(d);
}
}
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java
index a1d402ffb6..7834c285e8 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java
@@ -13,6 +13,7 @@
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.simulation.FlightData;
import net.sf.openrocket.simulation.SimulationOptions;
import net.sf.openrocket.simulation.extension.SimulationExtension;
@@ -115,12 +116,14 @@ public void endHandler(String element, HashMap attributes,
status = Simulation.Status.OUTDATED;
}
- SimulationOptions conditions;
+ SimulationOptions options;
+ FlightConfigurationId idToSet= FlightConfigurationId.ERROR_FCID;
if (conditionHandler != null) {
- conditions = conditionHandler.getConditions();
+ options = conditionHandler.getConditions();
+ idToSet = conditionHandler.idToSet;
} else {
warnings.add("Simulation conditions not defined, using defaults.");
- conditions = new SimulationOptions(doc.getRocket());
+ options = new SimulationOptions();
}
if (name == null)
@@ -133,7 +136,8 @@ public void endHandler(String element, HashMap attributes,
data = dataHandler.getFlightData();
Simulation simulation = new Simulation(doc.getRocket(), status, name,
- conditions, extensions, data);
+ options, extensions, data);
+ simulation.setFlightConfigurationId( idToSet );
doc.addSimulation(simulation);
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java
index a349c91df8..f17753b397 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java
@@ -2,25 +2,26 @@
import java.util.HashMap;
+import org.xml.sax.SAXException;
+
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
-import net.sf.openrocket.rocketcomponent.Stage;
+import net.sf.openrocket.rocketcomponent.AxialStage;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
-import org.xml.sax.SAXException;
-
class StageSeparationConfigurationHandler extends AbstractElementHandler {
- private final Stage stage;
+ private final AxialStage stage;
private SeparationEvent event = null;
private double delay = Double.NaN;
- public StageSeparationConfigurationHandler(Stage stage, DocumentLoadingContext context) {
+ public StageSeparationConfigurationHandler(AxialStage stage, DocumentLoadingContext context) {
this.stage = stage;
}
@@ -66,9 +67,11 @@ public void closeElement(String element, HashMap attributes, Str
@Override
public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException {
- String configId = attributes.get("configid");
- StageSeparationConfiguration def = stage.getStageSeparationConfiguration().getDefault();
- stage.getStageSeparationConfiguration().set(configId, getConfiguration(def));
+ FlightConfigurationId fcid = new FlightConfigurationId(attributes.get("configid"));
+ StageSeparationConfiguration sepConfig = stage.getSeparationConfigurations().get(fcid);
+
+ // copy and update to the file-read values
+ stage.getSeparationConfigurations().set(fcid, getConfiguration(sepConfig));
}
}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java
new file mode 100644
index 0000000000..a81cc9ac8a
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java
@@ -0,0 +1,75 @@
+package net.sf.openrocket.file.openrocket.savers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import net.sf.openrocket.rocketcomponent.AxialStage;
+import net.sf.openrocket.rocketcomponent.ParallelStage;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
+
+public class AxialStageSaver extends ComponentAssemblySaver {
+
+ private static final AxialStageSaver instance = new AxialStageSaver();
+
+ public static ArrayList getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
+ ArrayList list = new ArrayList();
+
+ if (c.isAfter()) {
+ // yes, this test is redundant. I'm merely paranoid, and attempting to future-proof it
+ if (c.getClass().equals(AxialStage.class)) {
+ // kept as simply 'stage' for backward compatability
+ list.add("");
+ instance.addParams(c, list);
+ list.add("");
+ }
+ } else {
+ if (c instanceof ParallelStage) {
+ list.add("");
+ instance.addParams(c, list);
+ list.add("");
+ }
+ }
+
+ return list;
+ }
+
+ @Override
+ protected void addParams(RocketComponent c, List elements) {
+ super.addParams(c, elements);
+ AxialStage stage = (AxialStage) c;
+
+ if (stage.getStageNumber() > 0) {
+ // NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
+ elements.addAll(addSeparationConfigParams(stage.getSeparationConfigurations().getDefault(), false));
+
+ // Note - getFlightConfigurationIDs returns at least one element. The first element
+ for (FlightConfigurationId fcid: stage.getSeparationConfigurations().getIds() ){
+ if (fcid == null) {
+ continue;
+ }
+ StageSeparationConfiguration curSepCfg = stage.getSeparationConfigurations().get(fcid);
+
+// if( stage.getSeparationConfigurations().isDefault( curSepCfg )){
+// continue;
+// }
+
+ elements.add("");
+ elements.addAll(addSeparationConfigParams(curSepCfg, true));
+ elements.add("");
+ }
+ }
+ }
+
+ private List addSeparationConfigParams(StageSeparationConfiguration config, boolean indent) {
+ List elements = new ArrayList(2);
+ elements.add((indent ? " " : "") + ""
+ + config.getSeparationEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
+ + "");
+ elements.add((indent ? " " : "") + "" + config.getSeparationDelay() + "");
+ return elements;
+
+ }
+}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java
index 9e9d609d68..db5a1fcd2d 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java
@@ -1,7 +1,31 @@
package net.sf.openrocket.file.openrocket.savers;
-public class ComponentAssemblySaver extends RocketComponentSaver {
+import java.util.ArrayList;
+
+import net.sf.openrocket.rocketcomponent.PodSet;
- // No-op
+public class ComponentAssemblySaver extends RocketComponentSaver {
+
+
+ private static final ComponentAssemblySaver instance = new ComponentAssemblySaver();
+
+ public static ArrayList getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
+ ArrayList list = new ArrayList();
+
+ if (!c.isAfter()) {
+ if (c instanceof PodSet) {
+ list.add("");
+ instance.addParams(c, list);
+ list.add("");
+ }
+// else if (c instanceof ParallelStage) {
+// list.add("");
+// instance.addParams(c, list);
+// list.add("");
+// }
+ }
+
+ return list;
+ }
-}
+}
\ No newline at end of file
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/FinSetSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/FinSetSaver.java
index 30e321f404..c7d5ded184 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/FinSetSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/FinSetSaver.java
@@ -12,8 +12,11 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
super.addParams(c, elements);
net.sf.openrocket.rocketcomponent.FinSet fins = (net.sf.openrocket.rocketcomponent.FinSet) c;
- elements.add("" + fins.getFinCount() + "");
- elements.add("" + (fins.getBaseRotation() * 180.0 / Math.PI) + "");
+
+ // // this information is already saved as 'RingInstanceable' in RocktComponent
+ // elements.add("" + fins.getFinCount() + "");
+ // elements.add("" + (fins.getBaseRotation() * 180.0 / Math.PI) + "");
+
elements.add("" + fins.getThickness() + "");
elements.add("" + fins.getCrossSection().name().toLowerCase(Locale.ENGLISH)
+ "");
@@ -26,8 +29,8 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
elements.add("" + fins.getTabHeight() + "");
elements.add("" + fins.getTabLength() + "");
elements.add("" +
- fins.getTabShift() + "");
+ fins.getTabOffsetMethod().name().toLowerCase(Locale.ENGLISH) + "\">" +
+ fins.getTabOffset() + "");
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/FuelTankSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/FuelTankSaver.java
new file mode 100644
index 0000000000..9e6601706f
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/FuelTankSaver.java
@@ -0,0 +1,40 @@
+package net.sf.openrocket.file.openrocket.savers;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import net.sf.openrocket.rocketcomponent.FuelTank;
+
+public class FuelTankSaver extends MassObjectSaver {
+
+ @Override
+ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c,
+ List elements) {
+ super.addParams(c, elements);
+
+ FuelTank fuel = (FuelTank) c;
+
+ elements.add("" + fuel.getMass() + "");
+ elements.add("" + fuel.getFuelQty() + "");
+ //elements.add("" + fuel.getInitialFuelQty() + "");
+ elements.add("" + fuel.getBurnRate() + "");
+ elements.add("" + fuel.getFuelType().name().toLowerCase(Locale.ENGLISH) + "");
+
+
+ }
+
+ private static final FuelTankSaver instance = new FuelTankSaver();
+
+ public static List getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
+ List list = new ArrayList();
+
+ list.add("");
+ instance.addParams(c, list);
+ list.add("");
+
+ return list;
+ }
+
+}
+
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/LaunchLugSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/LaunchLugSaver.java
index 1598bc412e..62936b2314 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/LaunchLugSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/LaunchLugSaver.java
@@ -1,10 +1,10 @@
package net.sf.openrocket.file.openrocket.savers;
-import net.sf.openrocket.rocketcomponent.LaunchLug;
-
import java.util.ArrayList;
import java.util.List;
+import net.sf.openrocket.rocketcomponent.LaunchLug;
+
public class LaunchLugSaver extends ExternalComponentSaver {
@@ -28,7 +28,7 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
elements.add("" + lug.getOuterRadius() + "");
elements.add("" + lug.getLength() + "");
elements.add("" + lug.getThickness() + "");
- elements.add("" + (lug.getRadialDirection()*180.0/Math.PI) + "");
+ elements.add("" + (lug.getAngularOffset()*180.0/Math.PI)+ "");
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java
new file mode 100644
index 0000000000..74a9c06389
--- /dev/null
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/RailButtonSaver.java
@@ -0,0 +1,34 @@
+package net.sf.openrocket.file.openrocket.savers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.openrocket.rocketcomponent.RailButton;
+
+
+public class RailButtonSaver extends ExternalComponentSaver {
+
+ private static final RailButtonSaver instance = new RailButtonSaver();
+
+ public static List getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
+ List list = new ArrayList();
+
+ list.add("");
+ instance.addParams(c, list);
+ list.add("");
+
+ return list;
+ }
+
+ @Override
+ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, List elements) {
+ super.addParams(c, elements);
+ RailButton rb = (RailButton) c;
+
+ emitDouble( elements, "outerdiameter", rb.getOuterDiameter());
+ emitDouble( elements, "height", rb.getTotalHeight());
+
+ }
+
+
+}
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java
index e4f06442d4..28a8f4d34d 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java
@@ -5,8 +5,9 @@
import java.util.Locale;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
+import net.sf.openrocket.rocketcomponent.FlightConfigurableParameterSet;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
-import net.sf.openrocket.rocketcomponent.Rocket;
public class RecoveryDeviceSaver extends MassObjectSaver {
@@ -24,31 +25,24 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
elements.add(materialParam(dev.getMaterial()));
// NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
- DeploymentConfiguration defaultConfig = dev.getDeploymentConfiguration().getDefault();
- elements.addAll(deploymentConfiguration(defaultConfig, false));
+ FlightConfigurableParameterSet configSet = dev.getDeploymentConfigurations();
+ DeploymentConfiguration defaultConfig = configSet.getDefault();
+ elements.addAll(addDeploymentConfigurationParams(defaultConfig, false));
- Rocket rocket = c.getRocket();
- // Note - getFlightConfigurationIDs returns at least one element. The first element
- // is null and means "default".
- String[] configs = rocket.getFlightConfigurationIDs();
- if (configs.length > 1) {
-
- for (String id : configs) {
- if (id == null) {
- continue;
- }
- if (dev.getDeploymentConfiguration().isDefault(id)) {
- continue;
- }
- DeploymentConfiguration config = dev.getDeploymentConfiguration().get(id);
- elements.add("");
- elements.addAll(deploymentConfiguration(config, true));
+ for (FlightConfigurationId fcid : configSet.getIds()) {
+ if (dev.getDeploymentConfigurations().isDefault(fcid)) {
+ continue;
+ }else{
+ // only print configurations which override the default.
+ DeploymentConfiguration deployConfig = dev.getDeploymentConfigurations().get(fcid);
+ elements.add("");
+ elements.addAll(addDeploymentConfigurationParams(deployConfig, true));
elements.add("");
}
}
}
- private List deploymentConfiguration(DeploymentConfiguration config, boolean indent) {
+ private List addDeploymentConfigurationParams(DeploymentConfiguration config, boolean indent) {
List elements = new ArrayList(3);
elements.add((indent ? " " : "") + "" + config.getDeployEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "");
elements.add((indent ? " " : "") + "" + config.getDeployAltitude() + "");
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java
index 3efe9f228f..32d8539b06 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java
@@ -4,6 +4,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
@@ -11,14 +12,20 @@
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.rocketcomponent.Clusterable;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
-import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
-import net.sf.openrocket.rocketcomponent.MotorConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
+import net.sf.openrocket.rocketcomponent.Instanceable;
+import net.sf.openrocket.rocketcomponent.LineInstanceable;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
+import net.sf.openrocket.rocketcomponent.position.AxialMethod;
+import net.sf.openrocket.rocketcomponent.position.RadiusPositionable;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Color;
@@ -78,15 +85,43 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
}
}
+ if ( c instanceof Instanceable) {
+ int instanceCount = c.getInstanceCount();
+
+ if( c instanceof Clusterable ){
+ ; // no-op. Instance counts are set via named cluster configurations
+ }else if( 1 < instanceCount ) {
+ emitInteger( elements, "instancecount", c.getInstanceCount() );
+ }
+
+ if( c instanceof LineInstanceable ){
+ LineInstanceable line = (LineInstanceable)c;
+ emitDouble( elements, "instanceseparation", line.getInstanceSeparation());
+ }
+ if( c instanceof RadiusPositionable ){
+ final RadiusPositionable radPos = (RadiusPositionable)c;
+ // The type names are currently equivalent to the enum names except for case.
+ final String radiusMethod = radPos.getRadiusMethod().name().toLowerCase(Locale.ENGLISH);
+ final double radiusOffset = radPos.getRadiusOffset();
+ elements.add("" + radiusOffset + "");
+ }
+ if( c instanceof AnglePositionable ) {
+ final AnglePositionable anglePos= (AnglePositionable)c;
+ // The type names are currently equivalent to the enum names except for case.
+ final String angleMethod = anglePos.getAngleMethod().name().toLowerCase(Locale.ENGLISH);
+ final double angleOffset = anglePos.getAngleOffset()*180.0/Math.PI ;
+ elements.add("" + angleOffset + "");
+
+ }
+ }
// Save position unless "AFTER"
- if (c.getRelativePosition() != RocketComponent.Position.AFTER) {
+ if (c.getAxialMethod() != AxialMethod.AFTER) {
// The type names are currently equivalent to the enum names except for case.
- String type = c.getRelativePosition().name().toLowerCase(Locale.ENGLISH);
- elements.add("" + c.getPositionValue() + "");
+ String axialMethod = c.getAxialMethod().name().toLowerCase(Locale.ENGLISH);
+ elements.add("" + c.getAxialOffset() + "");
}
-
// Overrides
boolean overridden = false;
if (c.isMassOverridden()) {
@@ -97,6 +132,10 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
elements.add("" + c.getOverrideCGX() + "");
overridden = true;
}
+ if (c.isCDOverridden()) {
+ elements.add("" + c.getOverrideCD() + "");
+ overridden = true;
+ }
if (overridden) {
elements.add("" + c.getOverrideSubcomponents()
+ "");
@@ -144,26 +183,34 @@ protected final String materialParam(String tag, Material mat) {
protected final List motorMountParams(MotorMount mount) {
if (!mount.isMotorMount())
return Collections.emptyList();
- String[] motorConfigIDs = ((RocketComponent) mount).getRocket().getFlightConfigurationIDs();
+
+ Rocket rkt = ((RocketComponent) mount).getRocket();
+ //FlightConfigurationID[] motorConfigIDs = ((RocketComponent) mount).getRocket().getFlightConfigurationIDs();
+ //ParameterSet configs = ((RocketComponent) mount).getRocket().getConfigurationSet();
+
List elements = new ArrayList();
+ MotorConfiguration defaultInstance = mount.getDefaultMotorConfig();
+
elements.add("");
// NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
elements.add(" "
- + mount.getIgnitionConfiguration().getDefault().getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
+ + defaultInstance.getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
+ "");
- elements.add(" " + mount.getIgnitionConfiguration().getDefault().getIgnitionDelay() + "");
+ elements.add(" " + defaultInstance.getIgnitionDelay() + "");
elements.add(" " + mount.getMotorOverhang() + "");
- for (String id : motorConfigIDs) {
- MotorConfiguration motorConfig = mount.getMotorConfiguration().get(id);
- Motor motor = motorConfig.getMotor();
+ for( FlightConfigurationId fcid : rkt.getIds()){
+
+ MotorConfiguration motorInstance = mount.getMotorConfig(fcid);
// Nothing is stored if no motor loaded
- if (motor == null)
+ if( motorInstance.isEmpty()){
continue;
+ }
+ Motor motor = motorInstance.getMotor();
- elements.add(" ");
+ elements.add(" ");
if (motor.getMotorType() != Motor.Type.UNKNOWN) {
elements.add(" " + motor.getMotorType().name().toLowerCase(Locale.ENGLISH) + "");
}
@@ -178,19 +225,19 @@ protected final List motorMountParams(MotorMount mount) {
elements.add(" " + motor.getLength() + "");
// Motor delay
- if (motorConfig.getEjectionDelay() == Motor.PLUGGED) {
+ if (motorInstance.getEjectionDelay() == Motor.PLUGGED_DELAY) {
elements.add(" none");
} else {
- elements.add(" " + motorConfig.getEjectionDelay() + "");
+ elements.add(" " + motorInstance.getEjectionDelay() + "");
}
elements.add(" ");
- if (!mount.getIgnitionConfiguration().isDefault(id)) {
- IgnitionConfiguration ignition = mount.getIgnitionConfiguration().get(id);
- elements.add(" ");
- elements.add(" " + ignition.getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "");
- elements.add(" " + ignition.getIgnitionDelay() + "");
+ // i.e. if this has overridden parameters....
+ if( ! motorInstance.equals( defaultInstance)){
+ elements.add(" ");
+ elements.add(" " + motorInstance.getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "");
+ elements.add(" " + motorInstance.getIgnitionDelay() + "");
elements.add(" ");
}
@@ -204,9 +251,37 @@ protected final List motorMountParams(MotorMount mount) {
private final static void emitColor(String elementName, List elements, Color color) {
if (color != null) {
elements.add("<" + elementName + " red=\"" + color.getRed() + "\" green=\"" + color.getGreen()
- + "\" blue=\"" + color.getBlue() + "\"/>");
+ + "\" blue=\"" + color.getBlue() + "\" alpha=\"" + color.getAlpha() + "\"/>");
}
}
+ protected static void emitDouble( final List elements, final String enclosingTag, final double value){
+ appendElement( elements, enclosingTag, enclosingTag, Double.toString( value ));
+ }
+
+ protected static void emitInteger( final List elements, final String enclosingTag, final int value){
+ appendElement( elements, enclosingTag, enclosingTag, Integer.toString( value ) );
+ }
+
+ protected static void emitString( final List elements, final String enclosingTag, final String value){
+ appendElement( elements, enclosingTag, enclosingTag, value );
+ }
+
+ protected static String generateOpenTag( final Map attrs, final String enclosingTag ){
+ StringBuffer buf = new StringBuffer();
+ if( null == attrs ) {
+ return enclosingTag;
+ }
+
+ for (Map.Entry entry : attrs.entrySet()) {
+ buf.append(String.format(" %s=\"%s\"", entry.getKey(), entry.getValue() ));
+ }
+ return buf.toString();
+ }
+
+ protected static void appendElement( final List elements, final String openTag, final String closeTag, final String elementValue ){
+ elements.add("<"+openTag+">" + elementValue + ""+closeTag+">");
+ }
+
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java
index 59af2484b5..d2630b6c7c 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java
@@ -4,6 +4,8 @@
import java.util.List;
import java.util.Locale;
+import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.ReferenceType;
import net.sf.openrocket.rocketcomponent.Rocket;
@@ -39,23 +41,26 @@ protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, Li
}
- // Motor configurations
- String defId = rocket.getDefaultConfiguration().getFlightConfigurationID();
- for (String id : rocket.getFlightConfigurationIDs()) {
- if (id == null)
+ // Flight configurations
+ for (FlightConfigurationId fcid : rocket.getIds()) {
+ FlightConfiguration flightConfig = rocket.getFlightConfiguration(fcid);
+ if (fcid == null)
continue;
- String str = "";
- } else {
- str += ">" + net.sf.openrocket.util.TextUtil.escapeXML(rocket.getFlightConfigurationName(id))
+ if (flightConfig.isNameOverridden()){
+ str += ">" + net.sf.openrocket.util.TextUtil.escapeXML(flightConfig.getName())
+ "";
+ } else {
+ str += "/>";
}
+
elements.add(str);
}
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/StageSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/StageSaver.java
deleted file mode 100644
index fb875379f8..0000000000
--- a/core/src/net/sf/openrocket/file/openrocket/savers/StageSaver.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package net.sf.openrocket.file.openrocket.savers;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import net.sf.openrocket.rocketcomponent.Rocket;
-import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.Stage;
-import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
-
-public class StageSaver extends ComponentAssemblySaver {
-
- private static final StageSaver instance = new StageSaver();
-
- public static ArrayList getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
- ArrayList list = new ArrayList();
-
- list.add("");
- instance.addParams(c, list);
- list.add("");
-
- return list;
- }
-
- @Override
- protected void addParams(RocketComponent c, List elements) {
- super.addParams(c, elements);
- Stage stage = (Stage) c;
-
- if (stage.getStageNumber() > 0) {
- // NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
- elements.addAll(separationConfig(stage.getStageSeparationConfiguration().getDefault(), false));
-
- Rocket rocket = stage.getRocket();
- // Note - getFlightConfigurationIDs returns at least one element. The first element
- // is null and means "default".
- String[] configs = rocket.getFlightConfigurationIDs();
- if (configs.length > 1) {
-
- for (String id : configs) {
- if (id == null) {
- continue;
- }
- if (stage.getStageSeparationConfiguration().isDefault(id)) {
- continue;
- }
- StageSeparationConfiguration config = stage.getStageSeparationConfiguration().get(id);
- elements.add("");
- elements.addAll(separationConfig(config, true));
- elements.add("");
- }
- }
- }
- }
-
- private List separationConfig(StageSeparationConfiguration config, boolean indent) {
- List elements = new ArrayList(2);
- elements.add((indent ? " " : "") + "