[Bugfix] Various small tweaks, Improved Configuration Naming

- events from a rocket start out disabled, and are turned on by the RocketLoader
- FlightConfgurations will once again describe their contained motors, if not explicitly named otherwise
- Refined ComponentChangeEvent type enum
- Added other miscellaneous debugging statements and methods
This commit is contained in:
Daniel_M_Williams 2015-12-01 14:38:48 -05:00
parent c826062be3
commit c65fb80dbf
23 changed files with 264 additions and 170 deletions

View File

@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -93,15 +94,9 @@ public abstract class AbstractAerodynamicCalculator implements AerodynamicCalcul
protected final void checkCache(FlightConfiguration configuration) {
if (rocketAeroModID != configuration.getRocket().getAerodynamicModID() ||
rocketTreeModID != configuration.getRocket().getTreeModID()) {
// // vvvv DEVEL vvvv
// log.debug("Voiding the aerodynamic cache");
// System.err.println(" >> Voiding Aero Cache... because modIDs changed...");
// StackTraceElement[] els = Thread.currentThread().getStackTrace();
// final int depth=12;
// for(int i=1; i< depth; i++){
// System.err.println(" "+els[i]);
// }
// // ^^^^ DEVEL ^^^^
// vvvv DEVEL vvvv
log.error("Voiding the aerodynamic cache because modIDs changed...", new BugException(" unsure why modID has changed..."));
// ^^^^ DEVEL ^^^^
rocketAeroModID = configuration.getRocket().getAerodynamicModID();
rocketTreeModID = configuration.getRocket().getTreeModID();

View File

@ -219,7 +219,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
RocketComponentCalc calcObj = calcMap.get(component);
// vvvv DEBUG vvvv
if (null == calcObj ){
throw new NullPointerException(" Component does not have a calcMap!! : "+component.getName() +"=="+component.getID()+" |calcMap|="+calcMap.size());
throw new NullPointerException(" Missing mapping: |calcMap|="+calcMap.size()+" for:"+component.toDebugName());
}
// ^^^^ DEBUG ^^^^
calcObj.calculateNonaxialForces(conditions, forces, warnings);

View File

@ -277,11 +277,10 @@ public class Simulation implements ChangeSource, Cloneable {
FlightConfiguration config = rocket.getFlightConfiguration(options.getConfigID());
List<MotorInstance> motorList = config.getActiveMotors();
//Make sure this simulation has motors.
if (0 == motorList.size()){
status = Status.CANT_RUN;
log.warn(" Unable to simulate: no motors loaded.");
}
return status;

View File

@ -92,6 +92,7 @@ public class GeneralRocketLoader {
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);

View File

@ -15,13 +15,11 @@ import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
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.ParallelStage;
import net.sf.openrocket.rocketcomponent.ParameterSet;
import net.sf.openrocket.rocketcomponent.RingInstanceable;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
@ -171,8 +169,10 @@ public class RocketComponentSaver {
if (!mount.isMotorMount())
return Collections.emptyList();
Rocket rkt = ((RocketComponent) mount).getRocket();
//FlightConfigurationID[] motorConfigIDs = ((RocketComponent) mount).getRocket().getFlightConfigurationIDs();
ParameterSet<FlightConfiguration> configs = ((RocketComponent) mount).getRocket().getConfigurationSet();
//ParameterSet<FlightConfiguration> configs = ((RocketComponent) mount).getRocket().getConfigurationSet();
List<String> elements = new ArrayList<String>();
MotorInstance defaultInstance = mount.getDefaultMotorInstance();
@ -186,8 +186,7 @@ public class RocketComponentSaver {
elements.add(" <ignitiondelay>" + defaultInstance.getIgnitionDelay() + "</ignitiondelay>");
elements.add(" <overhang>" + mount.getMotorOverhang() + "</overhang>");
for (FlightConfiguration curConfig : configs) {
FlightConfigurationID fcid = curConfig.getFlightConfigurationID();
for( FlightConfigurationID fcid : rkt.getSortedConfigurationIDs()){
MotorInstance motorInstance = mount.getMotorInstance(fcid);
// Nothing is stored if no motor loaded

View File

@ -49,7 +49,7 @@ public class MotorInstance implements FlightConfigurableParameter<MotorInstance>
modID++;
}
public MotorInstanceId getMotorID() {
public MotorInstanceId getID() {
return this.id;
}

View File

@ -8,6 +8,7 @@ import java.util.Set;
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.ArrayList;
@ -15,7 +16,7 @@ import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Monitorable;
/**
* A configuration of motor instances identified by a string id. Each motor instance has
* A configuration of motor instances identified by a MotorInstanceId. Each motor instance has
* an individual position, ingition time etc.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
@ -36,8 +37,6 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
*/
public MotorInstanceConfiguration( final FlightConfiguration _configuration) {
this.config = _configuration;
// final FlightConfigurationID fcid = configuration.getFlightConfigurationID();
update();
}
@ -78,7 +77,10 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
* @throws IllegalArgumentException if a motor with the specified ID already exists.
*/
public void addMotor(MotorInstance motor) {
MotorInstanceId id = motor.getMotorID();
if( motor.isEmpty() ){
throw new IllegalArgumentException("MotorInstance is empty.");
}
MotorInstanceId id = motor.getID();
if (this.motors.containsKey(id)) {
throw new IllegalArgumentException("MotorInstanceConfiguration already " +
"contains a motor with id " + id);
@ -139,7 +141,7 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
public MotorInstanceConfiguration clone() {
MotorInstanceConfiguration clone = new MotorInstanceConfiguration();
for (MotorInstance motor : this.motors.values()) {
clone.motors.put(motor.getMotorID(), motor.clone());
clone.motors.put(motor.getID(), motor.clone());
}
clone.modID = this.modID;
return clone;
@ -168,16 +170,19 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
public void update() {
this.motors.clear();
FlightConfigurationID fcid = this.config.getFlightConfigurationID();
for ( RocketComponent comp : this.config.getActiveComponents() ){
if ( comp instanceof MotorMount ){
MotorMount mount = (MotorMount)comp;
MotorInstance inst = mount.getMotorInstance(this.config.getFlightConfigurationID());
MotorInstance inst = mount.getMotorInstance( fcid);
if( inst.isEmpty()){
continue;
}
// this merely accounts for instancing of this component:
// this merely accounts for instancing of *this* component:
// int instancCount = comp.getInstanceCount();
// we account for instances this way because it counts *all* the instancing between here
// and the rocket root.
// this includes *all* the instancing between here and the rocket root.
Coordinate[] instanceLocations= comp.getLocations();
// System.err.println(String.format(",,,,,,,, : %s (%s)",
@ -190,7 +195,7 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
// motor location w/in mount: parent.refpoint -> motor.refpoint
Coordinate curMotorOffset = curInstance.getOffset();
curInstance.setPosition( curMountLocation.add(curMotorOffset) );
this.motors.put( curInstance.getMotorID(), curInstance);
this.motors.put( curInstance.getID(), curInstance);
// vvvv DEVEL vvvv
// System.err.println(String.format(",,,,,,,,[ %2d]: %s. (%s)",
@ -205,4 +210,32 @@ public class MotorInstanceConfiguration implements Cloneable, Iterable<MotorInst
//System.err.println(this.rocket.getConfigurationSet().toDebug());
}
@Override
public String toString(){
StringBuilder buff = new StringBuilder("[");
boolean first = true;
for( MotorInstance motor : this.motors.values() ){
if( first ){
first = false;
}else{
buff.append(", ");
}
buff.append(motor.getMotor().getDesignation());
}
buff.append("]");
return buff.toString();
}
public String toDebugString(){
StringBuilder buff = new StringBuilder();
for( MotorInstance motor : this.motors.values() ){
final String idString = motor.getID().toShortKey();
final String activeString = motor.isActive()? " on": "off";
final String nameString = motor.getMotor().getDesignation();
buff.append( String.format(" ..[%8s][%s] %10s", idString, activeString, nameString));
}
return buff.toString();
}
}

View File

@ -12,18 +12,13 @@ public final class MotorInstanceId {
private final String componentId;
private final int number;
private final static String COMPONENT_ERROR_TEXT = "Error Motor Id";
private final static int ERROR_NUMBER = -1;
public final static MotorInstanceId ERROR_ID = new MotorInstanceId();
private final static String ERROR_COMPONENT_TEXT = "Error Motor Id";
private final static int ERROR_NUMBER = 1;
public final static MotorInstanceId ERROR_ID = new MotorInstanceId(ERROR_COMPONENT_TEXT, ERROR_NUMBER);
private final static String EMPTY_COMPONENT_TEXT = "Empty Motor Id";
private final static int EMPTY_NUMBER = 1;
public final static MotorInstanceId EMPTY_ID = new MotorInstanceId(EMPTY_COMPONENT_TEXT, EMPTY_NUMBER);
public MotorInstanceId() {
this.componentId = COMPONENT_ERROR_TEXT;
this.number = ERROR_NUMBER;
}
/**
* Sole constructor.
*
@ -73,6 +68,17 @@ public final class MotorInstanceId {
return componentId.hashCode() + (number << 12);
}
public String toShortKey(){
if( this == ERROR_ID){
return "ERROR_ID";
}else if( this == EMPTY_ID){
return "EMPTY_ID";
}else{
final String result = toString();
return result.substring(0, Math.min(8, result.length()));
}
}
@Override
public String toString(){
if( this == ERROR_ID){

View File

@ -9,12 +9,11 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
* FlightConfigurationSet for motors.
* This is used for motors, where the default value is always no motor.
*/
public class MotorConfigurationSet extends ParameterSet<MotorInstance> {
public class MotorSet extends ParameterSet<MotorInstance> {
public static final int DEFAULT_MOTOR_EVENT_TYPE = ComponentChangeEvent.MOTOR_CHANGE | ComponentChangeEvent.EVENT_CHANGE;
public static final int DEFAULT_EVENT_TYPE = ComponentChangeEvent.MOTOR_CHANGE | ComponentChangeEvent.EVENT_CHANGE;
public MotorConfigurationSet(RocketComponent component, MotorInstance _value) {
super(component, DEFAULT_EVENT_TYPE, _value);
public MotorSet(RocketComponent component ) {
super(component, DEFAULT_MOTOR_EVENT_TYPE, MotorInstance.EMPTY_INSTANCE);
}
/**
@ -24,11 +23,10 @@ public class MotorConfigurationSet extends ParameterSet<MotorInstance> {
* @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 MotorConfigurationSet(ParameterSet<MotorInstance> flightConfiguration, RocketComponent component, int eventType) {
super(flightConfiguration, component, eventType);
public MotorSet(ParameterSet<MotorInstance> flightConfiguration, RocketComponent component) {
super(flightConfiguration, component, DEFAULT_MOTOR_EVENT_TYPE);
}
@Override
public void setDefault( MotorInstance value) {
throw new UnsupportedOperationException("Cannot change default value of motor configuration");
@ -37,13 +35,13 @@ public class MotorConfigurationSet extends ParameterSet<MotorInstance> {
@Override
public String toDebug(){
StringBuilder buffer = new StringBuilder();
buffer.append("====== Dumping MotorConfigurationSet for mount '"+this.component.getName()+"' of type: "+this.component.getClass().getSimpleName()+" ======\n");
buffer.append("====== Dumping MotorConfigurationSet for mount '"+this.component.toDebugName()+" ======\n");
buffer.append(" >> motorSet ("+this.size()+ " motors)\n");
MotorInstance emptyInstance = this.getDefault();
buffer.append(" >> (["+emptyInstance.toString()+"]= @ "+ emptyInstance.getIgnitionEvent().name +" +"+emptyInstance.getIgnitionDelay()+"sec )\n");
for( FlightConfigurationID loopFCID : this.map.keySet()){
String shortKey = loopFCID.getShortKey();
String shortKey = loopFCID.toShortKey();
MotorInstance curInstance = this.map.get(loopFCID);
String designation;
@ -63,22 +61,4 @@ public class MotorConfigurationSet extends ParameterSet<MotorInstance> {
}
// public void printDebug(FlightConfigurationID curFCID){
// if( this.map.containsKey(curFCID)){
// // no-op
// }else{
// String shortKey = curFCID.toShortKey();
// MotorInstance curInstance= this.get(curFCID);
//
// String designation;
// if( MotorInstance.EMPTY_INSTANCE == curInstance){
// designation = "EMPTY_INSTANCE";
// }else{
// designation = curInstance.getMotor().getDesignation(curInstance.getEjectionDelay());
// }
// System.err.println(" Queried FCID:");
// System.err.println(" >> ["+shortKey+"]= "+designation);
// }
// }
}

View File

@ -6,8 +6,9 @@ import java.util.Iterator;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfigurationSet;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.MotorInstanceId;
import net.sf.openrocket.motor.MotorSet;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
@ -31,7 +32,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
private double overhang = 0;
private boolean isActingMount = false;
private MotorConfigurationSet motors;
private MotorSet motors;
public BodyTube() {
this(8 * DEFAULT_RADIUS, DEFAULT_RADIUS);
@ -43,7 +44,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
super();
this.outerRadius = Math.max(radius, 0);
this.length = Math.max(length, 0);
this.motors = new MotorConfigurationSet(this, MotorInstance.EMPTY_INSTANCE);
motors = new MotorSet(this);
}
public BodyTube(double length, double radius, boolean filled) {
@ -382,10 +383,14 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
}else if( !this.equals( newMotorInstance.getMount())){
throw new BugException(" attempt to add a MotorInstance to a second mount, when it's already owned by another mount!");
}
newMotorInstance.setID(new MotorInstanceId( this.getID(), 1));
this.motors.set(fcid,newMotorInstance);
}
this.isActingMount=true;
// this is done automatically in the motorSet
//fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE);
}
@ -463,7 +468,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
protected RocketComponent copyWithOriginalID() {
BodyTube copy = (BodyTube) super.copyWithOriginalID();
copy.motors = new MotorConfigurationSet(motors, this, MotorConfigurationSet.DEFAULT_EVENT_TYPE);
copy.motors = new MotorSet( this.motors, copy );
return copy;
}
}

View File

@ -6,22 +6,22 @@ public class ComponentChangeEvent extends EventObject {
private static final long serialVersionUID = 1L;
public enum TYPE {
ERROR(0),
NON_FUNCTIONAL(1),
MASS(2),
AERODYNAMIC(4),
AERO_MASS ( AERODYNAMIC.value | MASS.value ), // 6
TREE( 8),
UNDO( 16),
MOTOR( 32),
EVENT( 64),
TEXTURE ( 128),
ALL(0xFFFFFFFF);
ERROR(-1, "Error"),
NON_FUNCTIONAL(1, "nonFunctional"),
MASS(2, "Mass"),
AERODYNAMIC(4, "Aerodynamic"),
TREE( 8, "TREE"),
UNDO( 16, "UNDO"),
MOTOR( 32, "Motor"),
EVENT( 64, "Event"),
TEXTURE ( 128, "Texture");
protected int value;
protected String name;
private TYPE( final int _val){
private TYPE( final int _val, final String _name){
this.value = _val;
this.name = _name;
}
public boolean matches( final int testValue ){
@ -37,8 +37,10 @@ public class ComponentChangeEvent extends EventObject {
/** A change that affects the aerodynamic properties of the rocket */
public static final int AERODYNAMIC_CHANGE = TYPE.AERODYNAMIC.value;
/** A change that affects the mass and aerodynamic properties of the rocket */
public static final int AEROMASS_CHANGE = TYPE.AERO_MASS.value; // Mass & Aerodynamic
public static final int AEROMASS_CHANGE = (TYPE.MASS.value | TYPE.AERODYNAMIC.value );
public static final int BOTH_CHANGE = AEROMASS_CHANGE; // syntactic sugar / backward compatibility
/** when a flight configuration fires an event, it is of this type */
public static final int CONFIG_CHANGE = (TYPE.MASS.value | TYPE.AERODYNAMIC.value | TYPE.TREE.value | TYPE.MOTOR.value | TYPE.EVENT.value);
/** A change that affects the rocket tree structure */
public static final int TREE_CHANGE = TYPE.TREE.value;
@ -51,11 +53,10 @@ public class ComponentChangeEvent extends EventObject {
/** A change to the 3D texture assigned to a component*/
public static final int TEXTURE_CHANGE = TYPE.TEXTURE.value;
// A bit-field that contains all possible change types.
// Will output as -1. for an explanation, see "twos-complement" representation of signed integers
public static final int ALL_CHANGE = TYPE.ALL.value;
//// A bit-field that contains all possible change types.
//// Will output as -1. for an explanation, see "twos-complement" representation of signed integers
//public static final int ALL_CHANGE = 0xFFFFFFFF;
private final int type;
@ -73,6 +74,15 @@ public class ComponentChangeEvent extends EventObject {
this.type = type.value;
}
public static TYPE getTypeEnum( final int typeNumber ){
for( TYPE ccet : ComponentChangeEvent.TYPE.values() ){
if( ccet.value == typeNumber ){
return ccet;
}
}
throw new IllegalArgumentException(" type number "+typeNumber+" is not a valid Type enum...");
}
/**
* Return the source component of this event as specified in the constructor.
@ -90,9 +100,13 @@ public class ComponentChangeEvent extends EventObject {
public boolean isEventChange() {
return TYPE.EVENT.matches( this.type);
}
public boolean isFunctionalChange() {
return ! (TYPE.NON_FUNCTIONAL.matches( this.type));
return ! this.isNonFunctionalChange();
}
public boolean isNonFunctionalChange() {
return (TYPE.NON_FUNCTIONAL.matches( this.type));
}
public boolean isMassChange() {
@ -113,7 +127,7 @@ public class ComponentChangeEvent extends EventObject {
public boolean isMotorChange() {
return TYPE.MASS.matches(this.type);
return TYPE.MOTOR.matches(this.type);
}
public int getType() {
@ -124,7 +138,7 @@ public class ComponentChangeEvent extends EventObject {
public String toString() {
String s = "";
if (isFunctionalChange())
if (isNonFunctionalChange())
s += ",nonfunc";
if (isMassChange())
s += ",mass";

View File

@ -161,6 +161,11 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if (stageNumber >= this.rocket.getStageCount()) {
return false;
}
// DEVEL
if( ! stages.containsKey(stageNumber)){
throw new IllegalArgumentException(" Configuration does not contain stage number: "+stageNumber);
}
return stages.get(stageNumber).active;
}
@ -328,23 +333,21 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if( isNamed ){
return configurationName;
}else{
return fcid.getFullKey();
if( this.hasMotors()){
return fcid.toShortKey()+" - "+this.motors.toString();
}else{
return fcid.getFullKeyText();
}
}
}
public String toShort() {
return this.fcid.getShortKey();
return this.fcid.toShortKey();
}
// DEBUG / DEVEL
public String toDebug() {
StringBuilder buf = new StringBuilder();
buf.append(String.format("["));
for (StageFlags flags : this.stages.values()) {
buf.append(String.format(" %d", (flags.active ? 1 : 0)));
}
buf.append("]\n");
return buf.toString();
return toMotorDetail();
}
// DEBUG / DEVEL
@ -353,26 +356,44 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
buf.append(String.format("\nDumping stage config: \n"));
for (StageFlags flags : this.stages.values()) {
AxialStage curStage = flags.stage;
buf.append(String.format(" [%d]: %24s: %b\n", curStage.getStageNumber(), curStage.getName(), flags.active));
buf.append(String.format(" [%2d]: %s: %24s\n", curStage.getStageNumber(), curStage.getName(), (flags.active?" on": "off")));
}
buf.append("\n\n");
return buf.toString();
}
// DEBUG / DEVEL
public String toMotorDetail(){
StringBuilder buff = new StringBuilder();
buff.append(String.format("\nDumping %2d Motors for configuration %s: \n", this.motors.getMotorCount(), this.fcid.toShortKey()));
for( MotorInstance curMotor : this.getAllMotors()){
if( curMotor.isEmpty() ){
buff.append( String.format( " ..[%8s] <empty> \n", 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() ));
}
}
return buff.toString();
}
@Override
public String toString() {
if( this.isNamed){
return configurationName + "["+fcid.getShortKey()+"]";
return configurationName + "["+fcid.toShortKey()+"]";
}else{
return fcid.getFullKey();
return this.getName();
}
}
@Override
public void componentChanged(ComponentChangeEvent e) {
public void componentChanged(ComponentChangeEvent cce) {
// update according to incoming events
updateStageMap();
this.motors.update();
}

View File

@ -45,11 +45,11 @@ public final class FlightConfigurationID implements Comparable<FlightConfigurati
return this.key.equals(otherFCID.key);
}
public String getShortKey(){
public String toShortKey(){
return this.key.toString().substring(0,8);
}
public String getFullKey(){
public String getFullKeyText(){
return this.key.toString();
}

View File

@ -9,8 +9,9 @@ import org.slf4j.LoggerFactory;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfigurationSet;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.MotorInstanceId;
import net.sf.openrocket.motor.MotorSet;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
@ -34,7 +35,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
private double overhang = 0;
private boolean isActingMount;
private MotorConfigurationSet motors;
private MotorSet motors;
/**
* Main constructor.
@ -45,7 +46,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
this.setInnerRadius(0.018 / 2);
this.setLength(0.070);
this.motors = new MotorConfigurationSet(this, MotorInstance.EMPTY_INSTANCE);
motors = new MotorSet(this);
}
@ -124,9 +125,14 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
* @param cluster The cluster configuration.
*/
@Override
public void setClusterConfiguration(ClusterConfiguration cluster) {
this.cluster = cluster;
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
public void setClusterConfiguration( final ClusterConfiguration cluster) {
if( cluster == this.cluster){
// no change
return;
}else{
this.cluster = cluster;
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
}
/**
@ -283,10 +289,14 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
}else if( !this.equals( newMotorInstance.getMount())){
throw new BugException(" attempt to add a MotorInstance to a second mount, when it's already owned by another mount!");
}
newMotorInstance.setID(new MotorInstanceId( this.getID(), 1));
this.motors.set(fcid, newMotorInstance);
}
this.isActingMount = true;
// this is done automatically in the motorSet
//fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE);
}
@Override
@ -305,7 +315,6 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
if (this.isActingMount == _active)
return;
this.isActingMount = _active;
fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE);
}
@Override
@ -356,7 +365,15 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
@Override
protected RocketComponent copyWithOriginalID() {
InnerTube copy = (InnerTube) super.copyWithOriginalID();
copy.motors = new MotorConfigurationSet(motors, copy, ComponentChangeEvent.MOTOR_CHANGE);
if( copy == this ){
new IllegalArgumentException(" copyWithOriginalID should return a different instance! ");
}
if( copy.motors == this.motors ){
new IllegalArgumentException(" copyWithOriginalID should produce different motorSet instances! ");
}
copy.motors = new MotorSet( this.motors, copy );
return copy;
}

View File

@ -143,17 +143,12 @@ public class ParameterSet<E extends FlightConfigurableParameter<E>> implements F
@Override
public void set(FlightConfigurationID fcid, E nextValue) {
if (null == fcid) {
throw new NullPointerException("id is null");
}else if( !fcid.isValid()){
throw new IllegalStateException(" Attempt to reset the default value on with an invalid key: "+fcid.toString());
}
if ( nextValue == null) {
// null value means to delete this fcid
E previousValue = map.remove(fcid);
E previousValue = this.map.remove(fcid);
removeListener(previousValue);
}else{
E previousValue = map.put(fcid, nextValue);
E previousValue = this.map.put(fcid, nextValue);
removeListener(previousValue);
addListener(nextValue);
}
@ -223,7 +218,7 @@ public class ParameterSet<E extends FlightConfigurableParameter<E>> implements F
buf.append(String.format(" >> [%s]= %s\n", "*DEFAULT*", this.getDefault().toString() ));
}else{
for( FlightConfigurationID loopFCID : this.getSortedConfigurationIDs()){
String shortKey = loopFCID.getShortKey();
String shortKey = loopFCID.toShortKey();
E inst = this.map.get(loopFCID);
if( this.isDefault(inst)){

View File

@ -56,6 +56,7 @@ public class Rocket extends RocketComponent {
private int treeModID;
private int functionalModID;
private boolean eventsEnabled=false;
private ReferenceType refType = ReferenceType.MAXIMUM; // Set in constructor
private double customReferenceLength = DEFAULT_REFERENCE_LENGTH;
@ -84,7 +85,7 @@ public class Rocket extends RocketComponent {
functionalModID = modID;
FlightConfiguration defaultConfiguration = new FlightConfiguration( null, this);
this.configSet = new FlightConfigurationSet(this, ComponentChangeEvent.ALL_CHANGE, defaultConfiguration);
this.configSet = new FlightConfigurationSet(this, ComponentChangeEvent.CONFIG_CHANGE, defaultConfiguration);
}
public String getDesigner() {
@ -282,7 +283,7 @@ public class Rocket extends RocketComponent {
public Rocket copyWithOriginalID() {
Rocket copy = (Rocket) super.copyWithOriginalID();
copy.configSet = new FlightConfigurationSet(
this.configSet, copy, ComponentChangeEvent.ALL_CHANGE);
this.configSet, copy, ComponentChangeEvent.CONFIG_CHANGE);
copy.resetListeners();
return copy;
@ -319,8 +320,7 @@ public class Rocket extends RocketComponent {
this.refType = r.refType;
this.customReferenceLength = r.customReferenceLength;
this.configSet = new FlightConfigurationSet(
r.configSet, this, ComponentChangeEvent.ALL_CHANGE);
this.configSet = new FlightConfigurationSet( r.configSet, this, ComponentChangeEvent.CONFIG_CHANGE);
this.perfectFinish = r.perfectFinish;
this.checkComponentStructure();
@ -373,38 +373,54 @@ public class Rocket extends RocketComponent {
}
@Override
protected void fireComponentChangeEvent(ComponentChangeEvent e) {
protected void fireComponentChangeEvent(ComponentChangeEvent cce) {
if( ! this.eventsEnabled ){
return;
}
mutex.lock("fireComponentChangeEvent");
try {
checkState();
// Update modification ID's only for normal (not undo/redo) events
if (!e.isUndoChange()) {
if (!cce.isUndoChange()) {
modID = UniqueID.next();
if (e.isMassChange())
if (cce.isMassChange())
massModID = modID;
if (e.isAerodynamicChange())
if (cce.isAerodynamicChange())
aeroModID = modID;
if (e.isTreeChange())
if (cce.isTreeChange())
treeModID = modID;
if (e.getType() != ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
if (cce.isFunctionalChange())
functionalModID = modID;
}
// Update modification ID's only for normal (not undo/redo) events
{ // vvvv DEVEL vvvv
String changeString;
if (cce.isUndoChange()) {
changeString = "an 'undo' change from: "+cce.getSource().getName()+" as:"+cce.toString();
}else{
changeString = "a normal change from: "+cce.getSource().getName()+" as:"+cce.toString();
}
log.error("Processing a rocket change: "+changeString, new IllegalArgumentException());
} // ^^^^ DEVEL ^^^^
// Check whether frozen
if (freezeList != null) {
log.debug("Rocket is in frozen state, adding event " + e + " info freeze list");
freezeList.add(e);
log.debug("Rocket is in frozen state, adding event " + cce + " info freeze list");
freezeList.add(cce);
return;
}
if( -1 == e.getType()){
if( -1 == cce.getType()){
log.debug(">>fireComponentChangeEvent()>> . . .");
}
// Notify all components first
Iterator<RocketComponent> iterator = this.iterator(true);
while (iterator.hasNext()) {
iterator.next().componentChanged(e);
iterator.next().componentChanged(cce);
}
// Notify all listeners
@ -412,9 +428,9 @@ public class Rocket extends RocketComponent {
EventListener[] list = listenerList.toArray(new EventListener[0]);
for (EventListener l : list) {
if (l instanceof ComponentChangeListener) {
((ComponentChangeListener) l).componentChanged(e);
((ComponentChangeListener) l).componentChanged(cce);
} else if (l instanceof StateChangeListener) {
((StateChangeListener) l).stateChanged(e);
((StateChangeListener) l).stateChanged(cce);
}
}
} finally {
@ -504,17 +520,14 @@ public class Rocket extends RocketComponent {
public FlightConfiguration createFlightConfiguration( final FlightConfigurationID fcid) {
checkState();
FlightConfiguration nextConfig = null;
if( configSet.containsKey(fcid)){
nextConfig = this.configSet.get(fcid);
return this.configSet.get(fcid);
}else{
nextConfig = new FlightConfiguration(fcid, this);
FlightConfiguration nextConfig = new FlightConfiguration(fcid, this);
this.configSet.set(fcid, nextConfig);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
return nextConfig;
}
this.setFlightConfiguration( fcid, nextConfig );
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
return nextConfig;
}
public int getConfigurationCount(){
@ -689,5 +702,26 @@ public class Rocket extends RocketComponent {
public boolean isCompatible(Class<? extends RocketComponent> type) {
return (AxialStage.class.equals(type));
}
/**
* STUB. would enable the monitoring, relay and production of events in this rocket instance.
*/
public void enableEvents() {
this.enableEvents(true);
}
/**
* STUB. would enable the monitoring, relay and production of events in this rocket instance.
*/
public void enableEvents( final boolean _enable ) {
if( this.eventsEnabled && _enable){
return;
}else if( _enable ){
this.eventsEnabled = true;
this.fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
}else{
this.eventsEnabled = false;
}
}
}

View File

@ -415,7 +415,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// Add copied children to the structure without firing events.
for (RocketComponent child : this.children) {
RocketComponent childCopy = child.copyWithOriginalID();
// Don't use add method since it fires events
// Don't use addChild(...) method since it fires events
clone.children.add(childCopy);
childCopy.parent = clone;
}
@ -2111,6 +2111,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
}
}
public String toDebugName(){
return this.getName()+"<"+this.getClass().getSimpleName()+">("+this.getID().substring(0,8)+")";
}
// multi-line output
protected StringBuilder toDebugDetail() {
StringBuilder buf = new StringBuilder();

View File

@ -198,7 +198,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// Check for burnt out motors
for( MotorInstance motor : status.getConfiguration().getAllMotors()){
MotorInstanceId motorId = motor.getMotorID();
MotorInstanceId motorId = motor.getID();
if (!motor.isActive() && status.addBurntOutMotor(motorId)) {
addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, status.getSimulationTime(),
(RocketComponent) motor.getMount(), motorId));
@ -309,7 +309,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// Check for motor ignition events, add ignition events to queue
for (MotorInstance motor : status.getFlightConfiguration().getActiveMotors() ){
MotorInstanceId mid = motor.getMotorID();
MotorInstanceId mid = motor.getID();
IgnitionEvent ignitionEvent = motor.getIgnitionEvent();
MotorMount mount = motor.getMount();
RocketComponent component = (RocketComponent) mount;

View File

@ -17,7 +17,6 @@ import net.sf.openrocket.models.atmosphere.ExtendedISAModel;
import net.sf.openrocket.models.gravity.GravityModel;
import net.sf.openrocket.models.gravity.WGSGravityModel;
import net.sf.openrocket.models.wind.PinkNoiseWindModel;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.startup.Application;
@ -53,7 +52,6 @@ public class SimulationOptions implements ChangeSource, Cloneable {
private final Rocket rocket;
private FlightConfigurationID configID = null;
private FlightConfiguration config = null;
/*
* NOTE: When adding/modifying parameters, they must also be added to the
@ -137,7 +135,6 @@ public class SimulationOptions implements ChangeSource, Cloneable {
if (MathUtil.equals(this.launchRodLength, launchRodLength))
return;
this.launchRodLength = launchRodLength;
fireChangeEvent();
}

View File

@ -30,11 +30,8 @@ public class StageSelector extends JPanel implements StateChangeListener {
super(new MigLayout("gap 0!"));
this.configuration = configuration;
JToggleButton button = new JToggleButton(new StageAction(0));
this.add(button);
buttons.add(button);
updateButtons();
configuration.addChangeListener(this);
}

View File

@ -171,7 +171,6 @@ public class BasicFrame extends JFrame implements PropertyChangeListener {
this.document = document;
this.rocket = document.getRocket();
this.rocket.getDefaultConfiguration().setAllStages();
// Create the component tree selection model that will be used
componentSelectionModel = new DefaultTreeSelectionModel();

View File

@ -27,7 +27,6 @@ import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfiguration
import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.ThrustCurveMotorInstance;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.IgnitionEvent;
import net.sf.openrocket.rocketcomponent.MotorMount;
@ -210,20 +209,22 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
motorChooserDialog.setMotorMountAndConfig( fcid, curMount );
motorChooserDialog.setVisible(true);
Motor m = motorChooserDialog.getSelectedMotor();
Motor mtr = motorChooserDialog.getSelectedMotor();
double d = motorChooserDialog.getSelectedDelay();
//System.err.println("Just selected motor: "+m+" for config: "+fcid);
if (m != null) {
// DEBUG
//System.err.println("Just selected motor for config: "+fcid.toShortKey());
if (mtr != null) {
// DEBUG
//System.err.println(" >> new motor: "+m.getDesignation()+" delay: "+d);
//System.err.println(" >> new motor: "+mtr.getDesignation()+" delay: "+d);
ThrustCurveMotorInstance curInstance = (ThrustCurveMotorInstance) m.getNewInstance();
MotorInstance curInstance = mtr.getNewInstance();
//System.err.println(" >> new instance: "+curInstance.toString());
curInstance.setEjectionDelay(d);
curMount.setMotorInstance( fcid, curInstance);
// DEBUG
//System.err.println(" set?: "+curMount.getMotorInstance(fcid).getMotor().getDesignation());
//System.err.println(" set?: "+curMount.getMotorInstance(fcid).toString());
}
fireTableDataChanged();
@ -304,7 +305,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
MotorMount mount = curMotorInstance.getMount();
Motor motor = curMotorInstance.getMotor();
if( null == mount){
throw new NullPointerException("Motor has a null mount... this should never happen: "+curMotorInstance.getMotorID());
throw new NullPointerException("Motor has a null mount... this should never happen: "+curMotorInstance.getID());
}
String str = motor.getDesignation(curMotorInstance.getEjectionDelay());

View File

@ -15,6 +15,9 @@ import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.arch.SystemInfo;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.material.Material;
@ -29,9 +32,6 @@ import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.BuildProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
private static final Logger log = LoggerFactory.getLogger(SwingPreferences.class);
@ -429,9 +429,6 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
SimulationOptions cond = s.getOptions();
cond.setTimeStep(RK4SimulationStepper.RECOMMENDED_TIME_STEP * 2);
cond.setWindSpeedAverage(1.0);
cond.setWindSpeedDeviation(0.1);
cond.setLaunchRodLength(5);
return s;
}