[Bugfix] Fixed Display (and other) bugs

FlightConfiguration.clone() now correctly clones internal data
    -> caused mysterious disapearing-rocket-display bug
    -> added FlightConfiguration.instanceNumber for debugging
Refined stage-set-active methods to fine tune event firings
Improved output of various debug methods.
Fixed various warnings
This commit is contained in:
Daniel_M_Williams 2015-12-12 11:00:17 -05:00
parent 0308d8d0c6
commit fc3e19fbcd
10 changed files with 103 additions and 90 deletions

View File

@ -71,12 +71,11 @@ class MotorMountHandler extends AbstractElementHandler {
warnings.add(Warning.fromString("Illegal motor specification, ignoring."));
return;
}
Motor motor = motorHandler.getMotor(warnings);
MotorInstance motorInstance = motor.getNewInstance();
RocketComponent rc = (RocketComponent)mount;
motorInstance.setID( new MotorInstanceId(rc.getID(), 1));
RocketComponent mountComponent = (RocketComponent)mount;
motorInstance.setID( new MotorInstanceId(mountComponent.getID(), 1));
motorInstance.setEjectionDelay(motorHandler.getDelay(warnings));
mount.setMotorInstance(fcid, motorInstance);

View File

@ -256,14 +256,14 @@ public class ThrustCurveMotorInstance extends MotorInstance {
sb.append(String.format("%s Ignite: %s at %+f\n",prefix, this.ignitionEvent.name, this.ignitionDelay));
//sb.append(String.format("%s Eject at: %+f\n",prefix, this.ejectionDelay));
sb.append(String.format("%s L:%f W:%f @:%f mm\n",prefix, motor.getLength(), motor.getDiameter(), this.position.multiply(1000).x ));
sb.append(String.format("%s currentTimem: %f\n", prefix, this.prevTime));
sb.append(String.format("%s currentTime: %f\n", prefix, this.prevTime));
sb.append("\n");
return sb.toString();
}
@Override
public String toString(){
return this.id.toString();
return this.motor.getDesignation() + this.id.toShortKey();
}
}

View File

@ -13,6 +13,7 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.MotorInstanceId;
import net.sf.openrocket.util.ArrayList;
@ -39,9 +40,13 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
protected final Rocket rocket;
protected final FlightConfigurationID fcid;
protected static int instanceCount=0;
public final int instanceNumber;
private List<EventListener> listenerList = new ArrayList<EventListener>();
protected class StageFlags {
protected class StageFlags implements Cloneable {
public boolean active = true;
public int prev = -1;
public AxialStage stage = null;
@ -51,6 +56,16 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
this.prev = _prev;
this.active = _active;
}
public int getKey(){
return this.stage.getStageNumber();
}
@Override
public StageFlags clone(){
return new StageFlags( this.stage, this.prev, true);
}
}
/* Cached data */
@ -81,6 +96,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
this.rocket = rocket;
this.isNamed = false;
this.configurationName = "<WARN: attempt to access unset configurationName. WARN!> ";
instanceNumber = FlightConfiguration.instanceCount;
++FlightConfiguration.instanceCount;
updateStages();
updateMotors();
@ -93,18 +110,24 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
public void clearAllStages() {
this.setAllStages(false);
this.setAllStages(false, true);
}
public void setAllStages() {
this.setAllStages(true);
this.setAllStages(true, true);
}
public void setAllStages(final boolean _value) {
public void setAllStages(final boolean _active) {
this.setAllStages(_active, true);
}
private void setAllStages(final boolean _active, final boolean fireEvent) {
for (StageFlags cur : stages.values()) {
cur.active = _value;
cur.active = _active;
}
if( fireEvent ){
fireChangeEvent();
}
fireChangeEvent();
}
/**
@ -113,7 +136,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
* @param stageNumber stage number to inactivate
*/
public void clearStage(final int stageNumber) {
setStageActive( stageNumber, false);
setStageActive( stageNumber, false, true);
}
/**
@ -122,9 +145,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
* @param stageNumber stage number to activate
*/
public void setOnlyStage(final int stageNumber) {
setAllStages(false);
setStageActive(stageNumber, true);
fireChangeEvent();
setAllStages(false, false);
setStageActive(stageNumber, true, true);
}
/**
@ -133,10 +155,16 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
* @param stageNumber stage number to flag
* @param _active inactive (<code>false</code>) or active (<code>true</code>)
*/
public void setStageActive(final int stageNumber, final boolean _active) {
public void setStageActive(final int stageNumber, final boolean _active ) {
this.setStageActive(stageNumber, _active, true );
}
private void setStageActive(final int stageNumber, final boolean _active, final boolean fireEvent) {
if ((0 <= stageNumber) && (stages.containsKey(stageNumber))) {
stages.get(stageNumber).active = _active;
fireChangeEvent();
if( fireEvent ){
fireChangeEvent();
}
return;
}
log.error("error: attempt to retrieve via a bad stage number: " + stageNumber);
@ -158,10 +186,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
* Check whether the stage specified by the index is active.
*/
public boolean isStageActive(int stageNumber) {
if (stageNumber >= this.rocket.getStageCount()) {
return false;
}
if( ! stages.containsKey(stageNumber)){
throw new IllegalArgumentException(" Configuration does not contain stage number: "+stageNumber);
}
@ -200,7 +224,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return activeStages;
}
public int getActiveStageCount() {
int activeCount = 0;
for (StageFlags cur : this.stages.values()) {
@ -296,7 +320,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
updateMotors();
}
private void updateStages() {
public void updateStages() {
if (this.rocket.getStageCount() == this.stages.size()) {
// no changes needed
return;
@ -341,10 +365,10 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
// DEBUG / DEVEL
public String toStageListDetail() {
StringBuilder buf = new StringBuilder();
buf.append(String.format("\nDumping stage config: \n"));
buf.append(String.format("\nDumping %d stages for config: %s: (#: %d)\n", this.stages.size(), this.getName(), this.instanceNumber));
for (StageFlags flags : this.stages.values()) {
AxialStage curStage = flags.stage;
buf.append(String.format(" [%2d]: %s: %24s\n", curStage.getStageNumber(), curStage.getName(), (flags.active?" on": "off")));
buf.append(String.format(" [%2d]: %-24s: %4s\n", curStage.getStageNumber(), curStage.getName(), (flags.active?" on": "off")));
}
buf.append("\n\n");
return buf.toString();
@ -353,28 +377,28 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
// DEBUG / DEVEL
public String toMotorDetail(){
StringBuilder buff = new StringBuilder();
buff.append(String.format("\nDumping %2d Motors for configuration %s: \n", this.motors.size(), this));
buff.append(String.format("\nDumping %2d Motors for configuration %s: (#: %s)\n", this.motors.size(), this, this.instanceNumber));
final int intanceCount = motors.size();
int motorInstanceNumber=0;
for( MotorInstance curMotor : this.motors.values() ){
if( curMotor.isEmpty() ){
buff.append( String.format( " ..[%8s] <empty> \n", curMotor.getID().toShortKey()));
buff.append( String.format( " ..[%2d/%2d][%8s] <empty> \n", motorInstanceNumber+1, intanceCount, curMotor.getID().toShortKey()));
}else{
buff.append( String.format( " ..[%8s] (%s) %10s (in: %s)\n",
curMotor.getID().toShortKey(),
(curMotor.isActive()? " on": "off"),
curMotor.getMotor().getDesignation(),
((RocketComponent)curMotor.getMount()).toDebugName() ));
buff.append( String.format( " ..[%2d/%2d](%6s) %-10s (in: %s)(id: %8s)\n",
motorInstanceNumber+1, intanceCount,
(curMotor.isActive()? "active": "inactv"),curMotor.getMotor().getDesignation(),
((RocketComponent)curMotor.getMount()).getName(), curMotor.getID().toShortKey() ));
}
++motorInstanceNumber;
}
return buff.toString();
}
public String getMotorsOneline(){
StringBuilder buff = new StringBuilder("[");
boolean first = true;
int activeMotorCount = 0;
for ( RocketComponent comp : getActiveComponents() ){
if (( comp instanceof MotorMount )&&( ((MotorMount)comp).isMotorMount())){
MotorMount mount = (MotorMount)comp;
@ -388,15 +412,17 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if( ! inst.isEmpty()){
buff.append( inst.getMotor().getDesignation());
++activeMotorCount;
}
}
}
if( 0 == activeMotorCount ){
buff.append(" n/a ");
}
buff.append("]");
return buff.toString();
}
@Override
public String toString() {
return this.getName();
@ -516,24 +542,22 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
Coordinate[] instanceLocations= compMount.getLocations();
sourceInstance.reset();
int instanceNumber = 1;
int motorInstanceNumber = 1;
//final int instanceCount = instanceLocations.length;
for ( Coordinate curMountLocation : instanceLocations ){
MotorInstance cloneInstance = sourceInstance.clone();
cloneInstance.setID( new MotorInstanceId( compMount.getName(), instanceNumber) );
cloneInstance.setID( new MotorInstanceId( compMount.getName(), motorInstanceNumber) );
// motor location w/in mount: parent.refpoint -> motor.refpoint
Coordinate curMotorOffset = cloneInstance.getOffset();
cloneInstance.setPosition( curMountLocation.add(curMotorOffset) );
this.motors.put( cloneInstance.getID(), cloneInstance);
instanceNumber ++;
motorInstanceNumber ++;
}
}
}
//System.err.println("returning "+toReturn.size()+" active motor instances for this configuration: "+this.fcid.getShortKey());
//System.err.println(this.rocket.getConfigurationSet().toDebug());
}
/////////////// Helper methods ///////////////
@ -597,9 +621,11 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
@Override
public FlightConfiguration clone() {
FlightConfiguration clone = new FlightConfiguration( this.getRocket(), this.fcid );
clone.setName(this.fcid.toShortKey()+" - clone");
clone.setName("clone - "+this.fcid.toShortKey());
clone.listenerList = new ArrayList<EventListener>();
clone.stages.putAll( (Map<Integer, StageFlags>) this.stages);
for( StageFlags flags : this.stages.values()){
clone.stages.put( flags.stage.getStageNumber(), flags.clone());
}
for( MotorInstance mi : this.motors.values()){
clone.motors.put( mi.getID(), mi.clone());
}
@ -607,7 +633,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
clone.modID = this.modID;
clone.boundsModID = -1;
clone.refLengthModID = -1;
rocket.addComponentChangeListener(clone);
return clone;
}
@ -623,9 +648,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
}
public void setName( final String newName) {
if( null == newName ){
this.isNamed = false;
}else if( "".equals(newName)){
if(( null == newName ) ||( "".equals(newName))){
this.isNamed= false;
return;
}else if( ! this.getFlightConfigurationID().isValid()){
return;
@ -635,5 +659,4 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
this.isNamed = true;
this.configurationName = newName;
}
}

View File

@ -415,20 +415,15 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
FlightConfigurationID curId = this.getRocket().getDefaultConfiguration().getFlightConfigurationID();
final int intanceCount = this.getInstanceCount();
MotorInstance curInstance = this.motors.get(curId);
//if( curInstance.isEmpty() ){
{
if( curInstance.isEmpty() ){
// print just the tube locations
buffer.append(prefix+" [X] This Instance doesn't have any motors... showing mount tubes only\n");
for (int instanceNumber = 0; instanceNumber < intanceCount; instanceNumber++) {
Coordinate tubeRelativePosition = relCoords[instanceNumber];
Coordinate tubeAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [%2d/%2d]; %28s; %28s;\n", prefix, instanceNumber+1, intanceCount,
tubeRelativePosition, tubeAbsolutePosition));
}
}
if( curInstance.isEmpty() ){
buffer.append(prefix+" [X] This Instance doesn't have any motors... showing mount tubes only\n");
}else{
// curInstance has a motor ...
Motor curMotor = curInstance.getMotor();

View File

@ -107,7 +107,6 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
@Override
public void setPositionValue(double value) {
System.err.println(" positioning "+getName()+" to: "+value);
super.setPositionValue(value);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}

View File

@ -54,13 +54,14 @@ public class ParameterSet<E extends FlightConfigurableParameter<E>> implements F
* @param component the rocket component on which events are fired when the parameter values are changed
* @param eventType the event type that will be fired on changes
*/
public ParameterSet(ParameterSet<E> flightConfiguration, RocketComponent component, int eventType) {
public ParameterSet(ParameterSet<E> configSet, RocketComponent component, int eventType) {
this.component = component;
this.eventType = eventType;
this.defaultValue= flightConfiguration.getDefault().clone();
for (FlightConfigurationID key : flightConfiguration.map.keySet()) {
this.map.put(key, flightConfiguration.map.get(key).clone());
this.defaultValue= configSet.getDefault().clone();
for (FlightConfigurationID key : configSet.map.keySet()) {
E cloneConfig = configSet.map.get(key).clone();
this.map.put(key, cloneConfig);
}
}

View File

@ -989,6 +989,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @deprecated name is ambiguous in three-dimensional space: value may refer to any of the three dimensions. Please use 'setAxialOffset' instead.
* @param value the position value of the component.
*/
@Deprecated
public void setPositionValue(double value) {
// if (MathUtil.equals(this.position.x, value))
// return;
@ -1097,6 +1098,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @deprecated kept around as example code. instead use getLocations
* @return
*/
@Deprecated
private Coordinate getAbsoluteVector() {
if (null == this.parent) {
// == improperly initialized components OR the root Rocket instance
@ -2127,7 +2129,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
}
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
buffer.append(String.format("%-42s; %5.3f; %24s; %24s;\n", prefix+" "+this.getName(),
buffer.append(String.format("%-40s; %5.3f; %24s; %24s;\n", prefix+" "+this.getName(),
this.getLength(), this.getOffset(), this.getLocations()[0]));
}
@ -2136,7 +2138,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
Iterator<RocketComponent> iterator = this.children.iterator();
while (iterator.hasNext()) {
iterator.next().dumpTreeHelper(buffer, prefix + " ");
iterator.next().dumpTreeHelper(buffer, prefix + "....");
}
}
}

View File

@ -146,6 +146,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
}
}
rocket.setFlightConfiguration(newId, newConfig);
rocket.addComponentChangeListener( newConfig);
// Create a new simulation for this configuration.
createSimulationForNewConfiguration();

View File

@ -34,6 +34,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.IgnitionEvent;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.Chars;
@ -169,7 +170,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
configurationTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
MotorConfigurationPanel.this.updateButtonState();
updateButtonState();
int selectedColumn = table.getSelectedColumn();
if (e.getClickCount() == 2) {
if (selectedColumn > 0) {
@ -200,7 +201,6 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
}
}
private void selectMotor() {
MotorMount curMount = getSelectedComponent();
FlightConfigurationID fcid= getSelectedConfigurationId();
@ -208,26 +208,21 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
return;
}
//MotorInstance curInstance = curMount.getMotorInstance( fcid );
// curInstance may be empty here...
//String mountName = ((RocketComponent)curMount).getName();
//System.err.println("?? Selecting motor "+curInstance+" for mount: "+mountName+" for config: "+fcid.toShortKey());
motorChooserDialog.setMotorMountAndConfig( fcid, curMount );
motorChooserDialog.setVisible(true);
Motor mtr = motorChooserDialog.getSelectedMotor();
double d = motorChooserDialog.getSelectedDelay();
// DEBUG
//System.err.println("Just selected motor for config: "+fcid.toShortKey());
if (mtr != null) {
// DEBUG
//System.err.println(" >> new motor: "+mtr.getDesignation()+" delay: "+d);
MotorInstance curInstance = mtr.getNewInstance();
//System.err.println(" >> new instance: "+curInstance.toString());
curInstance.setEjectionDelay(d);
curInstance.setIgnitionEvent( IgnitionEvent.AUTOMATIC);
curMount.setMotorInstance( fcid, curInstance);
// DEBUG
//System.err.println(" set?: "+curMount.getMotorInstance(fcid).toString());
}
fireTableDataChanged();

View File

@ -18,6 +18,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.gui.figureelements.FigureElement;
import net.sf.openrocket.gui.rocketfigure.RocketComponentShape;
import net.sf.openrocket.gui.util.ColorConversion;
@ -30,6 +33,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.simulation.BasicEventSimulationEngine;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -46,7 +50,9 @@ import net.sf.openrocket.util.Transformation;
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class RocketFigure extends AbstractScaleFigure {
private static final long serialVersionUID = 1L;
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";
private static final String ROCKET_FIGURE_SUFFIX = "Shapes";
@ -228,7 +234,7 @@ public class RocketFigure extends AbstractScaleFigure {
// Update figure shapes if necessary
if (figureShapes == null)
updateFigure();
double tx, ty;
// Calculate translation for figure centering
@ -277,10 +283,9 @@ public class RocketFigure extends AbstractScaleFigure {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int shapeCount = figureShapes.size();
// Draw all shapes
for (int i = 0; i < figureShapes.size(); i++) {
for (int i = 0; i < shapeCount; i++) {
RocketComponentShape rcs = figureShapes.get(i);
RocketComponent c = rcs.getComponent();
boolean selected = false;
@ -321,7 +326,6 @@ public class RocketFigure extends AbstractScaleFigure {
RenderingHints.VALUE_STROKE_NORMALIZE);
}
g2.draw(rcs.shape);
}
g2.setStroke(new BasicStroke((float) (NORMAL_WIDTH * EXTRA_SCALE / scale),
@ -332,9 +336,8 @@ public class RocketFigure extends AbstractScaleFigure {
// Draw motors
Color fillColor = ((SwingPreferences)Application.getPreferences()).getMotorFillColor();
Color borderColor = ((SwingPreferences)Application.getPreferences()).getMotorBorderColor();
//MotorInstanceConfiguration mic = new MotorInstanceConfiguration(configuration);
FlightConfiguration config = rocket.getDefaultConfiguration();
FlightConfiguration config = rocket.getDefaultConfiguration();
for( MotorInstance curInstance : config.getActiveMotors()){
MotorMount mount = curInstance.getMount();
Motor motor = curInstance.getMotor();
@ -372,7 +375,6 @@ public class RocketFigure extends AbstractScaleFigure {
}
// Draw relative extras
for (FigureElement e : relativeExtra) {
e.paint(g2, scale / EXTRA_SCALE);
@ -421,17 +423,13 @@ public class RocketFigure extends AbstractScaleFigure {
// facade for the recursive function below
private void getShapes(ArrayList<RocketComponentShape> allShapes, FlightConfiguration configuration){
for( AxialStage stage : configuration.getActiveStages()){
// for debug...
//int stageNumber = stage.getStageNumber();
//String activeString = ( configuration.isStageActive(stageNumber) ? "active" : "inactive");
getShapeTree( allShapes, stage, Coordinate.ZERO);
}
}
// NOTE: Recursive function
private void getShapeTree(
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
ArrayList<RocketComponentShape> allShapes, // output parameter
final RocketComponent comp,
final Coordinate parentLocation){