[Refine] Refining Configuration Fixes

- Rocket.getSelectedConfiguration will now create a new
  configuration if only the default config exists
  -- added additional unit tests for this behavior in: FLightConfigurationTest
- added test for saving ver 1.08 files to OpenRocketSaverTest
- Converted : "private static final long serialVersionUID ..." declarations to:
  "@SuppressWarnings("serial")"
- cleaned up some other random errors:
  -- tightened excessive permission modifiers -- public ->
  -- change some methods from 'public' to '/*package-local*/'
This commit is contained in:
Daniel_M_Williams 2016-04-10 13:08:47 -04:00
parent 5b687b5bcc
commit d7faf0d273
10 changed files with 129 additions and 100 deletions

View File

@ -29,18 +29,19 @@ import net.sf.openrocket.util.Monitorable;
public class FlightConfiguration implements FlightConfigurableParameter<FlightConfiguration>, Monitorable {
private static final Logger log = LoggerFactory.getLogger(FlightConfiguration.class);
public final static String DEFAULT_CONFIGURATION_NAME = "Default Configuration".intern();
public final static String NO_MOTORS_TEXT = "[No Motors Defined]".intern();
protected String configurationName=null;
private final static String NO_MOTORS_NAME = "[No Motors Defined]";
private final static String DEFAULT_CONFIGURATION_NAME = NO_MOTORS_NAME;
private String configurationName=null;
protected final Rocket rocket;
protected final FlightConfigurationId fcid;
protected static int instanceCount=0;
private static int instanceCount=0;
// made public for testing.... there is probably a better way
public final int instanceNumber;
protected class StageFlags implements Cloneable {
private class StageFlags implements Cloneable {
public boolean active = true;
public int prev = -1;
public AxialStage stage = null;
@ -59,7 +60,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
public StageFlags clone(){
return new StageFlags( this.stage, this.prev, true);
}
}
/* Cached data */
@ -175,16 +175,14 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
public Collection<RocketComponent> getActiveComponents() {
Queue<RocketComponent> toProcess = new ArrayDeque<RocketComponent>(this.getActiveStages());
ArrayList<RocketComponent> toReturn = new ArrayList<RocketComponent>();
ArrayList<RocketComponent> toReturn = new ArrayList<>();
while (!toProcess.isEmpty()) {
RocketComponent comp = toProcess.poll();
toReturn.add(comp);
for (RocketComponent child : comp.getChildren()) {
if (child instanceof AxialStage) {
continue;
} else {
if (!(child instanceof AxialStage)) {
toProcess.offer(child);
}
}
@ -194,7 +192,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
}
public List<AxialStage> getActiveStages() {
List<AxialStage> activeStages = new ArrayList<AxialStage>();
List<AxialStage> activeStages = new ArrayList<>();
for (StageFlags flags : this.stages.values()) {
if (flags.active) {
@ -215,9 +213,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return activeCount;
}
/**
* Retrieve the bottom-most active stage.
* @return
/**
* @return the compoment for the bottom-most center, active stage.
*/
public AxialStage getBottomStage() {
AxialStage bottomStage = null;
@ -271,7 +268,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
updateMotors();
}
protected void updateStages() {
private void updateStages() {
if (this.rocket.getStageCount() == this.stages.size()) {
// no changes needed
return;
@ -322,17 +319,14 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
}
}
if( 0 == activeMotorCount ){
return NO_MOTORS_TEXT;
return DEFAULT_CONFIGURATION_NAME;
}
buff.append("]");
return buff.toString();
}
@Override
public String toString() {
return this.getName();
}
public String toString() { return this.getName(); }
/**
* Add a motor instance to this configuration.
@ -344,12 +338,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if( motorConfig.isEmpty() ){
throw new IllegalArgumentException("MotorInstance is empty.");
}
MotorConfigurationId id = motorConfig.getID();
if (this.motors.containsKey(id)) {
throw new IllegalArgumentException("FlightConfiguration already " +
"contains a motor with id " + id);
}
this.motors.put(id, motorConfig);
this.motors.put( motorConfig.getID(), motorConfig);
modID++;
}
@ -381,7 +371,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return activeMotors;
}
protected void updateMotors() {
private void updateMotors() {
this.motors.clear();
Iterator<RocketComponent> iter = rocket.iterator(false);
@ -471,15 +461,22 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/
@Override
public FlightConfiguration clone() {
// Note the motors and stages are updated in the constructor call.
FlightConfiguration clone = new FlightConfiguration( this.getRocket(), this.fcid );
clone.setName("clone[#"+clone.instanceNumber+"]"+clone.fcid.toShortKey());
// log.error(">> Why am I being cloned!?", new IllegalStateException(this.toDebug()+" >to> "+clone.toDebug()));
// DO NOT UPDATE this.stages or this.motors;
// these are are updated correctly on their own.
// Note the stages are updated in the constructor call.
FlightConfiguration clone = new FlightConfiguration( this.rocket, this.fcid );
clone.setName("clone[#"+clone.instanceNumber+"]"+clone.fcid.toShortKey());
//FlightConfigurationId cloneId = clone.getFlightConfigurationID();
System.err.println(" cloning from: "+this.toDebug());
System.err.println(" cloning to: "+clone.toDebug());
// // clone motor instances.
// for( MotorConfiguration motor : motors.values() ){
// MotorConfiguration cloneMotor = new MotorConfiguration( motor, cloneId);
// clone.addMotor( cloneMotor);
// cloneMotor.getMount().setMotorConfig(cloneMotor, cloneId);
// }
clone.cachedBounds = this.cachedBounds.clone();
clone.modID = this.modID;
clone.boundsModID = -1;

View File

@ -34,14 +34,12 @@ public class Rocket extends RocketComponent {
private static final Logger log = LoggerFactory.getLogger(Rocket.class);
private static final Translator trans = Application.getTranslator();
public static final String DEFAULT_NAME = "[{motors}]";
public static final double DEFAULT_REFERENCE_LENGTH = 0.01;
protected static final double DEFAULT_REFERENCE_LENGTH = 0.01;
/**
* List of component change listeners.
*/
private List<EventListener> listenerList = new ArrayList<EventListener>();
private List<EventListener> listenerList = new ArrayList<>();
/**
* When freezeList != null, events are not dispatched but stored in the list.
@ -69,7 +67,7 @@ public class Rocket extends RocketComponent {
// Flight configuration list
private FlightConfiguration selectedConfiguration;
private FlightConfigurableParameterSet<FlightConfiguration> configSet;
private HashMap<Integer, AxialStage> stageMap = new HashMap<Integer, AxialStage>();
private HashMap<Integer, AxialStage> stageMap = new HashMap<>();
// Does the rocket have a perfect finish (a notable amount of laminar flow)
private boolean perfectFinish = false;
@ -84,12 +82,11 @@ public class Rocket extends RocketComponent {
aeroModID = modID;
treeModID = modID;
functionalModID = modID;
// must be after the hashmaps :P
configSet = new FlightConfigurableParameterSet<FlightConfiguration>( new FlightConfiguration(this, FlightConfigurationId.DEFAULT_VALUE_FCID) );
this.selectedConfiguration = configSet.getDefault();
FlightConfiguration defaultConfig = new FlightConfiguration(this, FlightConfigurationId.DEFAULT_VALUE_FCID);
configSet = new FlightConfigurableParameterSet<>( defaultConfig );
this.selectedConfiguration = defaultConfig;
}
public String getDesigner() {
@ -211,7 +208,7 @@ public class Rocket extends RocketComponent {
*
* @Return a reference to the topmost stage
*/
public AxialStage getBottomCoreStage(){
/*package-local*/ AxialStage getBottomCoreStage(){
// get last stage that's a direct child of the rocket.
return (AxialStage) children.get( children.size()-1 );
}
@ -223,8 +220,8 @@ public class Rocket extends RocketComponent {
}
return guess;
}
public void trackStage(final AxialStage newStage) {
/*package-local*/ void trackStage(final AxialStage newStage) {
int stageNumber = newStage.getStageNumber();
AxialStage value = stageMap.get(stageNumber);
@ -236,8 +233,8 @@ public class Rocket extends RocketComponent {
this.stageMap.put(stageNumber, newStage);
}
}
public void forgetStage(final AxialStage oldStage) {
/*package-local*/ void forgetStage(final AxialStage oldStage) {
this.stageMap.remove(oldStage.getStageNumber());
}
@ -569,7 +566,10 @@ public class Rocket extends RocketComponent {
*/
public FlightConfiguration getSelectedConfiguration() {
checkState();
return this.selectedConfiguration;
if( this.selectedConfiguration == this.configSet.getDefault() ){
selectedConfiguration = createFlightConfiguration(null);
}
return selectedConfiguration;
}
public int getConfigurationCount(){
@ -650,28 +650,29 @@ public class Rocket extends RocketComponent {
}
return false;
}
/**
* Return a flight configuration. If the supplied id does not have a specific instance, the default is returned.
*
* @param fcid the flight configuration id
* @return FlightConfiguration instance
*/
public FlightConfiguration createFlightConfiguration(final FlightConfigurationId fcid) {
public FlightConfiguration createFlightConfiguration( final FlightConfigurationId fcid) {
checkState();
if( null == fcid ){
return configSet.getDefault();
if( null == fcid ){
// fall-through to the default case...
// creating a FlightConfiguration( null ) just allocates a fresh new FCID
}else if( fcid.hasError() ){
return configSet.getDefault();
}else if( configSet.containsId(fcid)){
return this.getFlightConfiguration(fcid);
}else{
FlightConfiguration nextConfig = new FlightConfiguration(this, fcid);
this.configSet.set(fcid, nextConfig);
fireComponentChangeEvent(ComponentChangeEvent.TREE_CHANGE);
return nextConfig;
}
FlightConfiguration nextConfig = new FlightConfiguration(this, fcid);
this.configSet.set(nextConfig.getFlightConfigurationID(), nextConfig);
fireComponentChangeEvent(ComponentChangeEvent.TREE_CHANGE);
return nextConfig;
}
@ -697,7 +698,7 @@ public class Rocket extends RocketComponent {
}
public FlightConfigurationId getId( final int configIndex) {
List<FlightConfigurationId> idList = this.getIds();
List<FlightConfigurationId> idList = configSet.getIds();
return idList.get(configIndex);
}

View File

@ -101,14 +101,13 @@ public class TestRockets {
// Motor.Type type, double[] delays, double diameter, double length,
// double[] time, double[] thrust,
// Coordinate[] cg, String digest);
ThrustCurveMotor mtr = new ThrustCurveMotor(
Manufacturer.getManufacturer("Estes"),"A8", " SU Black Powder",
return new ThrustCurveMotor(
Manufacturer.getManufacturer("Estes"),"A8", " SU Black Powder",
Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070,
new double[] { 0, 1, 2 }, new double[] { 0, 9, 0 },
new Coordinate[] {
new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)},
new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)},
"digest A8 test");
return mtr;
}
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
@ -117,14 +116,13 @@ public class TestRockets {
// Motor.Type type, double[] delays, double diameter, double length,
// double[] time, double[] thrust,
// Coordinate[] cg, String digest);
ThrustCurveMotor mtr = new ThrustCurveMotor(
return new ThrustCurveMotor(
Manufacturer.getManufacturer("Estes"),"B4", " SU Black Powder",
Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070,
new double[] { 0, 1, 2 }, new double[] { 0, 11.4, 0 },
new Coordinate[] {
new Coordinate(0.035, 0, 0, 0.0195),new Coordinate(.035, 0, 0, 0.0155),new Coordinate(.035, 0, 0, 0.013)},
"digest B4 test");
return mtr;
}
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
@ -133,26 +131,24 @@ public class TestRockets {
// Motor.Type type, double[] delays, double diameter, double length,
// double[] time, double[] thrust,
// Coordinate[] cg, String digest);
ThrustCurveMotor mtr = new ThrustCurveMotor(
return new ThrustCurveMotor(
Manufacturer.getManufacturer("Estes"),"C6", " SU Black Powder",
Motor.Type.SINGLE, new double[] {0,3,5,7}, 0.018, 0.070,
new double[] { 0, 1, 2 }, new double[] { 0, 6, 0 },
new Coordinate[] {
new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.012)},
"digest C6 test");
return mtr;
}
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_D21_18mm(){
ThrustCurveMotor mtr = new ThrustCurveMotor(
return new ThrustCurveMotor(
Manufacturer.getManufacturer("AeroTech"),"D21", "Desc",
Motor.Type.SINGLE, new double[] {}, 0.018, 0.07,
new double[] { 0, 1, 2 }, new double[] { 0, 32, 0 },
new Coordinate[] {
new Coordinate(.035, 0, 0, 0.025),new Coordinate(.035, 0, 0, .020),new Coordinate(.035, 0, 0, 0.0154)},
"digest D21 test");
return mtr;
}
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
@ -161,14 +157,13 @@ public class TestRockets {
// Motor.Type type, double[] delays, double diameter, double length,
// double[] time, double[] thrust,
// Coordinate[] cg, String digest);
ThrustCurveMotor mtr = new ThrustCurveMotor(
return new ThrustCurveMotor(
Manufacturer.getManufacturer("AeroTech"),"M1350", "Desc",
Motor.Type.SINGLE, new double[] {}, 0.075, 0.622,
new double[] { 0, 1, 2 }, new double[] { 0, 1357, 0 },
new Coordinate[] {
new Coordinate(.311, 0, 0, 4.808),new Coordinate(.311, 0, 0, 3.389),new Coordinate(.311, 0, 0, 1.970)},
"digest M1350 test");
return mtr;
}
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
@ -177,14 +172,13 @@ public class TestRockets {
// Motor.Type type, double[] delays, double diameter, double length,
// double[] time, double[] thrust,
// Coordinate[] cg, String digest);
ThrustCurveMotor mtr = new ThrustCurveMotor(
return new ThrustCurveMotor(
Manufacturer.getManufacturer("AeroTech"),"G77", "Desc",
Motor.Type.SINGLE, new double[] {4,7,10},0.029, 0.124,
new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 },
new Coordinate[] {
new Coordinate(.062, 0, 0, 0.123),new Coordinate(.062, 0, 0, .0935),new Coordinate(.062, 0, 0, 0.064)},
"digest G77 test");
return mtr;
}
//
@ -1029,7 +1023,10 @@ public class TestRockets {
public static Rocket makeFalcon9Heavy() {
Rocket rocket = new Rocket();
rocket.setName("Falcon9H Scale Rocket");
FlightConfiguration selConfig = rocket.getSelectedConfiguration();
FlightConfiguration selConfig = rocket.createFlightConfiguration(null);
rocket.setSelectedConfiguration(selConfig);
FlightConfigurationId selFCID = selConfig.getFlightConfigurationID();
// ====== Payload Stage ======

View File

@ -131,6 +131,7 @@ public class OpenRocketSaverTest {
rocketDocs.add(TestRockets.makeTestRocket_v106_withRecoveryDeviceDeploymentConfig());
rocketDocs.add(TestRockets.makeTestRocket_v106_withStageSeparationConfig());
rocketDocs.add(TestRockets.makeTestRocket_v107_withSimulationExtension(SIMULATION_EXTENSION_SCRIPT));
rocketDocs.add(TestRockets.makeTestRocket_v108_withBoosters());
rocketDocs.add(TestRockets.makeTestRocket_for_estimateFileSize());
StorageOptions options = new StorageOptions();

View File

@ -142,12 +142,43 @@ public class FlightConfigurationTest extends BaseTestCase {
config.setAllStages();
}
/**
* Single stage rocket specific configuration tests
*/
@Test
public void testConfigurationSwitching() {
@Test
public void testCreateConfigurationNullId() {
/* Setup */
Rocket rkt = TestRockets.makeEstesAlphaIII();
// PRE-CONDITION:
// test that all configurations correctly loaded:
int expectedConfigCount = 5;
int actualConfigCount = rkt.getConfigurationCount();
assertThat("number of loaded configuration counts doesn't actually match.", actualConfigCount, equalTo(expectedConfigCount));
// create with
rkt.createFlightConfiguration(null);
expectedConfigCount = 6;
actualConfigCount = rkt.getConfigurationCount();
assertThat("createFlightConfiguration with null: doesn't actually work.", actualConfigCount, equalTo(expectedConfigCount));
}
@Test
public void testGetNullSelectedConfiguration(){
Rocket rkt = new Rocket();
// PRE-CONDITION:
// test that all configurations correctly loaded:
int expectedConfigCount = 0;
int actualConfigCount = rkt.getConfigurationCount();
assertThat("number of loaded configuration counts doesn't actually match.", actualConfigCount, equalTo(expectedConfigCount));
rkt.getSelectedConfiguration();
expectedConfigCount = 1;
actualConfigCount = rkt.getConfigurationCount();
assertThat("createFlightConfiguration with null: doesn't actually work.", actualConfigCount, equalTo(expectedConfigCount));
}
@Test
public void testConfigurationSpecific() {
/* Setup */
Rocket rkt = TestRockets.makeEstesAlphaIII();
@ -156,14 +187,21 @@ public class FlightConfigurationTest extends BaseTestCase {
int expectedMotorCount = 5;
int actualMotorCount = smmt.getMotorCount();
assertThat("number of motor configurations doesn't match.", actualMotorCount, equalTo(expectedMotorCount));
// test that all configurations correctly loaded:
int expectedConfigCount = 5;
int actualConfigCount = rkt.getConfigurationCount();
assertThat("number of loaded configuration counts doesn't actually match.", actualConfigCount, equalTo(expectedConfigCount));
}
actualConfigCount = rkt.getIds().size();
assertThat("number of configuration array ids doesn't actually match.",
actualConfigCount, equalTo(expectedConfigCount));
int expectedConfigArraySize = 6;
int actualConfigArraySize = rkt.toConfigArray().length;
assertThat("Size of configuration arrays doesn't actually match.",
actualConfigArraySize, equalTo(expectedConfigArraySize));
}
/**
* Multi stage rocket specific configuration tests

View File

@ -39,7 +39,6 @@ public class RocketTest extends BaseTestCase {
FlightConfigurationId fcid5 = config5.getId();
assertThat("fcids should match: ", config2.getId(), equalTo(fcid5));
assertThat("Configurations should bef different match: "+config2.toDebug()+"=?="+config5.toDebug(), config2.instanceNumber, not( config5.instanceNumber));
}

View File

@ -47,7 +47,7 @@ public class ParameterSetModel<T extends FlightConfigurableParameter<T>> impleme
@Override
public int getSize() {
this.idList = this.sourceSet.getSortedConfigurationIDs();
this.idList = this.sourceSet.getIds();
return this.idList.size();
}
@ -109,7 +109,7 @@ public class ParameterSetModel<T extends FlightConfigurableParameter<T>> impleme
return;
}
fireListDataEvent();
this.idList = this.sourceSet.getSortedConfigurationIDs();
this.idList = this.sourceSet.getIds();
}
}

View File

@ -34,8 +34,8 @@ import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.Chars;
@SuppressWarnings("serial")
public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount> {
private static final long serialVersionUID = -5046535300435793744L;
private static final String NONE = trans.get("edtmotorconfdlg.tbl.None");
@ -60,7 +60,6 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
subpanel.add(label, "wrap");
MotorMountConfigurationPanel mountConfigPanel = new MotorMountConfigurationPanel(this,rocket) {
private static final long serialVersionUID = -238261338962282816L;
@Override
public void onDataChanged() {
@ -138,8 +137,6 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
protected JTable initializeTable() {
//// Motor selection table.
configurationTableModel = new FlightConfigurableTableModel<MotorMount>(MotorMount.class,rocket) {
private static final long serialVersionUID = -1210899988369000567L;
@Override
protected boolean includeComponent(MotorMount component) {
return component.isMotorMount();
@ -270,7 +267,6 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
private class MotorTableCellRenderer extends FlightConfigurablePanel<MotorMount>.FlightConfigurableCellRenderer {
private static final long serialVersionUID = -7462331042920067984L;
@Override
protected JLabel format( MotorMount mount, FlightConfigurationId configId, JLabel l ) {

View File

@ -49,9 +49,9 @@ import net.sf.openrocket.util.Transformation;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
@SuppressWarnings("serial")
public class RocketFigure extends AbstractScaleFigure {
private static final long serialVersionUID = 45884403769043138L;
private static final Logger log = LoggerFactory.getLogger(BasicEventSimulationEngine.class);
private static final String ROCKET_FIGURE_PACKAGE = "net.sf.openrocket.gui.rocketfigure";

View File

@ -81,8 +81,8 @@ import net.sf.openrocket.util.StateChangeListener;
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
* @author Bill Kuker <bkuker@billkuker.com>
*/
@SuppressWarnings("serial")
public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource {
private static final long serialVersionUID = 1L;
private static final Translator trans = Application.getTranslator();