package net.sf.openrocket.simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
/**
* A class that defines an event during the flight of a rocket.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class FlightEvent implements Comparable<FlightEvent> {
private static final Translator trans = Application.getTranslator();
/**
* The type of the flight event.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public enum Type {
/**
* Rocket launch.
*/
LAUNCH(trans.get("FlightEvent.Type.LAUNCH")),
/**
* Ignition of a motor. Source is the motor mount the motor of which has ignited,
* and the data is the MotorId of the motor instance.
*/
IGNITION(trans.get("FlightEvent.Type.IGNITION")),
/**
* When the motor has lifted off the ground.
*/
LIFTOFF(trans.get("FlightEvent.Type.LIFTOFF")),
/**
* Launch rod has been cleared.
*/
LAUNCHROD(trans.get("FlightEvent.Type.LAUNCHROD")),
/**
* Burnout of a motor. Source is the motor mount the motor of which has burnt out,
* and the data is the MotorId of the motor instance.
*/
BURNOUT(trans.get("FlightEvent.Type.BURNOUT")),
/**
* Ejection charge of a motor fired. Source is the motor mount the motor of
* which has exploded its ejection charge, and data is the MotorId of the motor instance.
*/
EJECTION_CHARGE(trans.get("FlightEvent.Type.EJECTION_CHARGE")),
/**
* Separation of a stage. Source is the stage which is being separated from the upper stages.
*/
STAGE_SEPARATION(trans.get("FlightEvent.Type.STAGE_SEPARATION")),
/**
* Apogee has been reached.
*/
APOGEE(trans.get("FlightEvent.Type.APOGEE")),
/**
* Opening of a recovery device. Source is the RecoveryComponent which has opened.
*/
RECOVERY_DEVICE_DEPLOYMENT(trans.get("FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT")),
/**
* Ground has been hit after flight.
*/
GROUND_HIT(trans.get("FlightEvent.Type.GROUND_HIT")),
/**
* End of simulation. Placing this to the queue will end the simulation.
*/
SIMULATION_END(trans.get("FlightEvent.Type.SIMULATION_END")),
/**
* A change in altitude has occurred. Data is a <code>Pair<Double,Double></code>
* which contains the old and new altitudes.
*/
ALTITUDE(trans.get("FlightEvent.Type.ALTITUDE")),
/**
* The rocket begins to tumble.
*/
TUMBLE(trans.get("FlightEvent.Type.TUMBLE")),
/**
* Simulation aborted
*/
EXCEPTION(trans.get("FlightEvent.Type.EXCEPTION"));
private final String name;
private Type(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
private final Type type;
private final double time;
private final RocketComponent source;
private final Object data;
public FlightEvent(Type type, double time) {
this(type, time, null);
}
public FlightEvent(Type type, double time, RocketComponent source) {
this(type, time, source, null);
}
public FlightEvent(Type type, double time, RocketComponent source, Object data) {
this.type = type;
this.time = time;
this.source = source;
this.data = data;
}
public Type getType() {
return type;
}
public double getTime() {
return time;
}
public RocketComponent getSource() {
return source;
}
public Object getData() {
return data;
}
/**
* Return a new FlightEvent with the same information as the current event
* but with <code>null</code> source. This is used to avoid memory leakage by
* retaining references to obsolete components.
*
* @return a new FlightEvent with same type, time and data.
*/
public FlightEvent resetSourceAndData() {
return new FlightEvent(type, time, null, null);
}
/**
* Compares this event to another event depending on the event time. Secondary
* sorting is performed based on the event type ordinal.
*/
@Override
public int compareTo(FlightEvent o) {
if (this.time < o.time)
return -1;
if (this.time > o.time)
return 1;
return this.type.ordinal() - o.type.ordinal();
}
@Override
public String toString() {
return "FlightEvent[type=" + type.name() + ",time=" + time + ",source=" + source + "]";
}
}