1 package net.sf.openrocket.simulation.listeners;
4 import net.sf.openrocket.aerodynamics.AerodynamicForces;
5 import net.sf.openrocket.aerodynamics.FlightConditions;
6 import net.sf.openrocket.aerodynamics.Warning;
7 import net.sf.openrocket.logging.LogHelper;
8 import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
9 import net.sf.openrocket.motor.MotorId;
10 import net.sf.openrocket.motor.MotorInstance;
11 import net.sf.openrocket.rocketcomponent.MotorMount;
12 import net.sf.openrocket.rocketcomponent.RecoveryDevice;
13 import net.sf.openrocket.simulation.AccelerationData;
14 import net.sf.openrocket.simulation.FlightEvent;
15 import net.sf.openrocket.simulation.MassData;
16 import net.sf.openrocket.simulation.SimulationStatus;
17 import net.sf.openrocket.simulation.exception.SimulationException;
18 import net.sf.openrocket.startup.Application;
19 import net.sf.openrocket.util.Coordinate;
20 import net.sf.openrocket.util.MathUtil;
23 * Helper methods for firing events to simulation listeners.
25 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
27 public class SimulationListenerHelper {
29 private static final LogHelper log = Application.getLogger();
31 //////// SimulationListener methods ////////
35 * Fire startSimulation event.
37 public static void fireStartSimulation(SimulationStatus status)
38 throws SimulationException {
39 int modID = status.getModID();
41 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
42 l.startSimulation(status);
43 if (modID != status.getModID()) {
45 modID = status.getModID();
52 * Fire endSimulation event.
54 public static void fireEndSimulation(SimulationStatus status, SimulationException exception) {
55 int modID = status.getModID();
57 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
58 l.endSimulation(status, exception);
59 if (modID != status.getModID()) {
61 modID = status.getModID();
72 * @return <code>true</code> to handle step normally, <code>false</code> to skip the step.
74 public static boolean firePreStep(SimulationStatus status)
75 throws SimulationException {
77 int modID = status.getModID();
79 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
80 b = l.preStep(status);
81 if (modID != status.getModID()) {
83 modID = status.getModID();
95 * Fire postStep event.
97 public static void firePostStep(SimulationStatus status)
98 throws SimulationException {
99 int modID = status.getModID();
101 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
103 if (modID != status.getModID()) {
105 modID = status.getModID();
112 //////// SimulationEventListener methods ////////
115 * Fire an add flight event event.
117 * @return <code>true</code> to add the event normally, <code>false</code> to skip adding the event.
119 public static boolean fireAddFlightEvent(SimulationStatus status, FlightEvent event) throws SimulationException {
121 int modID = status.getModID();
123 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
124 if (l instanceof SimulationEventListener) {
125 b = ((SimulationEventListener) l).addFlightEvent(status, event);
126 if (modID != status.getModID()) {
128 modID = status.getModID();
140 * Fire a handle flight event event.
142 * @return <code>true</code> to handle the event normally, <code>false</code> to skip event.
144 public static boolean fireHandleFlightEvent(SimulationStatus status, FlightEvent event) throws SimulationException {
146 int modID = status.getModID();
148 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
149 if (l instanceof SimulationEventListener) {
150 b = ((SimulationEventListener) l).handleFlightEvent(status, event);
151 if (modID != status.getModID()) {
153 modID = status.getModID();
165 * Fire motor ignition event.
167 * @return <code>true</code> to handle the event normally, <code>false</code> to skip event.
169 public static boolean fireMotorIgnition(SimulationStatus status, MotorId motorId, MotorMount mount,
170 MotorInstance instance) throws SimulationException {
172 int modID = status.getModID(); // Contains also motor instance
174 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
175 if (l instanceof SimulationEventListener) {
176 b = ((SimulationEventListener) l).motorIgnition(status, motorId, mount, instance);
177 if (modID != status.getModID()) {
179 modID = status.getModID();
192 * Fire recovery device deployment event.
194 * @return <code>true</code> to handle the event normally, <code>false</code> to skip event.
196 public static boolean fireRecoveryDeviceDeployment(SimulationStatus status, RecoveryDevice device)
197 throws SimulationException {
199 int modID = status.getModID(); // Contains also motor instance
201 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
202 if (l instanceof SimulationEventListener) {
203 b = ((SimulationEventListener) l).recoveryDeviceDeployment(status, device);
204 if (modID != status.getModID()) {
206 modID = status.getModID();
218 //////// SimulationComputationalListener methods ////////
221 * Fire preAtmosphericModel event.
223 * @return <code>null</code> normally, or overriding atmospheric conditions.
225 public static AtmosphericConditions firePreAtmosphericModel(SimulationStatus status)
226 throws SimulationException {
227 AtmosphericConditions conditions;
228 int modID = status.getModID();
230 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
231 if (l instanceof SimulationComputationListener) {
232 conditions = ((SimulationComputationListener) l).preAtmosphericModel(status);
233 if (modID != status.getModID()) {
235 modID = status.getModID();
237 if (conditions != null) {
247 * Fire postAtmosphericModel event.
249 * @return the atmospheric conditions to use.
251 public static AtmosphericConditions firePostAtmosphericModel(SimulationStatus status, AtmosphericConditions conditions)
252 throws SimulationException {
253 AtmosphericConditions c;
254 AtmosphericConditions clone = conditions.clone();
255 int modID = status.getModID();
257 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
258 if (l instanceof SimulationComputationListener) {
259 c = ((SimulationComputationListener) l).postAtmosphericModel(status, clone);
260 if (modID != status.getModID()) {
262 modID = status.getModID();
264 if (c != null && !c.equals(conditions)) {
267 clone = conditions.clone();
277 * Fire preWindModel event.
279 * @return <code>null</code> normally, or overriding wind.
281 public static Coordinate firePreWindModel(SimulationStatus status)
282 throws SimulationException {
284 int modID = status.getModID();
286 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
287 if (l instanceof SimulationComputationListener) {
288 wind = ((SimulationComputationListener) l).preWindModel(status);
289 if (modID != status.getModID()) {
291 modID = status.getModID();
303 * Fire postWindModel event.
305 * @return the wind to use.
307 public static Coordinate firePostWindModel(SimulationStatus status, Coordinate wind) throws SimulationException {
309 int modID = status.getModID();
311 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
312 if (l instanceof SimulationComputationListener) {
313 w = ((SimulationComputationListener) l).postWindModel(status, wind);
314 if (modID != status.getModID()) {
316 modID = status.getModID();
318 if (w != null && !w.equals(wind)) {
330 * Fire preGravityModel event.
332 * @return <code>NaN</code> normally, or overriding gravity.
334 public static double firePreGravityModel(SimulationStatus status)
335 throws SimulationException {
337 int modID = status.getModID();
339 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
340 if (l instanceof SimulationComputationListener) {
341 gravity = ((SimulationComputationListener) l).preGravityModel(status);
342 if (modID != status.getModID()) {
344 modID = status.getModID();
346 if (!Double.isNaN(gravity)) {
356 * Fire postGravityModel event.
358 * @return the gravity to use.
360 public static double firePostGravityModel(SimulationStatus status, double gravity) throws SimulationException {
362 int modID = status.getModID();
364 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
365 if (l instanceof SimulationComputationListener) {
366 g = ((SimulationComputationListener) l).postGravityModel(status, gravity);
367 if (modID != status.getModID()) {
369 modID = status.getModID();
371 if (!Double.isNaN(g) && !MathUtil.equals(g, gravity)) {
384 * Fire preFlightConditions event.
386 * @return <code>null</code> normally, or overriding flight conditions.
388 public static FlightConditions firePreFlightConditions(SimulationStatus status)
389 throws SimulationException {
390 FlightConditions conditions;
391 int modID = status.getModID();
393 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
394 if (l instanceof SimulationComputationListener) {
395 conditions = ((SimulationComputationListener) l).preFlightConditions(status);
396 if (modID != status.getModID()) {
398 modID = status.getModID();
400 if (conditions != null) {
410 * Fire postFlightConditions event.
412 * @return the flight conditions to use: either <code>conditions</code> or a new object
413 * containing the modified conditions.
415 public static FlightConditions firePostFlightConditions(SimulationStatus status, FlightConditions conditions)
416 throws SimulationException {
418 FlightConditions clone = conditions.clone();
419 int modID = status.getModID();
421 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
422 if (l instanceof SimulationComputationListener) {
423 c = ((SimulationComputationListener) l).postFlightConditions(status, clone);
424 if (modID != status.getModID()) {
426 modID = status.getModID();
428 if (c != null && !c.equals(conditions)) {
431 clone = conditions.clone();
442 * Fire preAerodynamicCalculation event.
444 * @return <code>null</code> normally, or overriding aerodynamic forces.
446 public static AerodynamicForces firePreAerodynamicCalculation(SimulationStatus status)
447 throws SimulationException {
448 AerodynamicForces forces;
449 int modID = status.getModID();
451 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
452 if (l instanceof SimulationComputationListener) {
453 forces = ((SimulationComputationListener) l).preAerodynamicCalculation(status);
454 if (modID != status.getModID()) {
456 modID = status.getModID();
458 if (forces != null) {
468 * Fire postAerodynamicCalculation event.
470 * @return the aerodynamic forces to use.
472 public static AerodynamicForces firePostAerodynamicCalculation(SimulationStatus status, AerodynamicForces forces)
473 throws SimulationException {
475 AerodynamicForces clone = forces.clone();
476 int modID = status.getModID();
478 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
479 if (l instanceof SimulationComputationListener) {
480 f = ((SimulationComputationListener) l).postAerodynamicCalculation(status, clone);
481 if (modID != status.getModID()) {
483 modID = status.getModID();
485 if (f != null && !f.equals(forces)) {
488 clone = forces.clone();
500 * Fire preMassCalculation event.
502 * @return <code>null</code> normally, or overriding mass data.
504 public static MassData firePreMassCalculation(SimulationStatus status)
505 throws SimulationException {
507 int modID = status.getModID();
509 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
510 if (l instanceof SimulationComputationListener) {
511 mass = ((SimulationComputationListener) l).preMassCalculation(status);
512 if (modID != status.getModID()) {
514 modID = status.getModID();
526 * Fire postMassCalculation event.
528 * @return the aerodynamic forces to use.
530 public static MassData firePostMassCalculation(SimulationStatus status, MassData mass) throws SimulationException {
532 int modID = status.getModID();
534 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
535 if (l instanceof SimulationComputationListener) {
536 m = ((SimulationComputationListener) l).postMassCalculation(status, mass);
537 if (modID != status.getModID()) {
539 modID = status.getModID();
541 if (m != null && !m.equals(mass)) {
554 * Fire preThrustComputation event.
556 * @return <code>NaN</code> normally, or overriding thrust.
558 public static double firePreThrustCalculation(SimulationStatus status)
559 throws SimulationException {
561 int modID = status.getModID();
563 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
564 if (l instanceof SimulationComputationListener) {
565 thrust = ((SimulationComputationListener) l).preSimpleThrustCalculation(status);
566 if (modID != status.getModID()) {
568 modID = status.getModID();
570 if (!Double.isNaN(thrust)) {
580 * Fire postThrustComputation event.
582 * @return the thrust value to use.
584 public static double firePostThrustCalculation(SimulationStatus status, double thrust) throws SimulationException {
586 int modID = status.getModID();
588 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
589 if (l instanceof SimulationComputationListener) {
590 t = ((SimulationComputationListener) l).postSimpleThrustCalculation(status, thrust);
591 if (modID != status.getModID()) {
593 modID = status.getModID();
595 if (!Double.isNaN(t) && !MathUtil.equals(t, thrust)) {
609 * Fire preMassCalculation event.
611 * @return <code>null</code> normally, or overriding mass data.
613 public static AccelerationData firePreAccelerationCalculation(SimulationStatus status) throws SimulationException {
614 AccelerationData acceleration;
615 int modID = status.getModID();
617 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
618 if (l instanceof SimulationComputationListener) {
619 acceleration = ((SimulationComputationListener) l).preAccelerationCalculation(status);
620 if (modID != status.getModID()) {
622 modID = status.getModID();
624 if (acceleration != null) {
634 * Fire postMassCalculation event.
636 * @return the aerodynamic forces to use.
638 public static AccelerationData firePostAccelerationCalculation(SimulationStatus status,
639 AccelerationData acceleration) throws SimulationException {
641 int modID = status.getModID();
643 for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
644 if (l instanceof SimulationComputationListener) {
645 a = ((SimulationComputationListener) l).postAccelerationCalculation(status, acceleration);
646 if (modID != status.getModID()) {
648 modID = status.getModID();
650 if (a != null && !a.equals(acceleration)) {
662 private static void warn(SimulationStatus status, SimulationListener listener) {
663 if (!listener.isSystemListener()) {
664 log.info("Non-system listener " + listener + " affected the simulation");
665 status.getWarnings().add(Warning.LISTENERS_AFFECTED);