Properly fire changes after wind model change
This commit is contained in:
parent
b9d2ebd16b
commit
4a3b9efe76
@ -1,15 +1,22 @@
|
||||
package info.openrocket.core.models.wind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import info.openrocket.core.util.ChangeSource;
|
||||
import info.openrocket.core.util.Coordinate;
|
||||
import info.openrocket.core.util.ModID;
|
||||
import info.openrocket.core.util.StateChangeListener;
|
||||
|
||||
public class MultiLevelPinkNoiseWindModel implements WindModel {
|
||||
private List<LevelWindModel> levels;
|
||||
|
||||
private final List<StateChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
public MultiLevelPinkNoiseWindModel() {
|
||||
this.levels = new ArrayList<>();
|
||||
}
|
||||
@ -21,23 +28,28 @@ public class MultiLevelPinkNoiseWindModel implements WindModel {
|
||||
pinkNoiseModel.setDirection(direction);
|
||||
|
||||
LevelWindModel newLevel = new LevelWindModel(altitude, pinkNoiseModel);
|
||||
newLevel.addChangeListener(e -> fireChangeEvent());
|
||||
int index = Collections.binarySearch(levels, newLevel, Comparator.comparingDouble(l -> l.altitude));
|
||||
if (index >= 0) {
|
||||
throw new IllegalArgumentException("Wind level already exists for altitude: " + altitude);
|
||||
}
|
||||
levels.add(-index - 1, newLevel);
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public void removeWindLevel(double altitude) {
|
||||
levels.removeIf(level -> level.altitude == altitude);
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public void removeWindLevelIdx(int index) {
|
||||
levels.remove(index);
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public void clearLevels() {
|
||||
levels.clear();
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public List<LevelWindModel> getLevels() {
|
||||
@ -127,10 +139,12 @@ public class MultiLevelPinkNoiseWindModel implements WindModel {
|
||||
return levels.hashCode();
|
||||
}
|
||||
|
||||
public static class LevelWindModel implements Cloneable {
|
||||
public static class LevelWindModel implements Cloneable, ChangeSource {
|
||||
protected double altitude;
|
||||
protected PinkNoiseWindModel model;
|
||||
|
||||
private final List<StateChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
LevelWindModel(double altitude, PinkNoiseWindModel model) {
|
||||
this.altitude = altitude;
|
||||
this.model = model;
|
||||
@ -142,6 +156,7 @@ public class MultiLevelPinkNoiseWindModel implements WindModel {
|
||||
|
||||
public void setAltitude(double altitude) {
|
||||
this.altitude = altitude;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public double getSpeed() {
|
||||
@ -194,5 +209,49 @@ public class MultiLevelPinkNoiseWindModel implements WindModel {
|
||||
LevelWindModel that = (LevelWindModel) obj;
|
||||
return Double.compare(that.altitude, altitude) == 0 && model.equals(that.model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(StateChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
model.addChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(StateChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
model.removeChangeListener(listener);
|
||||
}
|
||||
|
||||
public void fireChangeEvent() {
|
||||
EventObject event = new EventObject(this);
|
||||
// Copy the list before iterating to prevent concurrent modification exceptions.
|
||||
EventListener[] list = listeners.toArray(new EventListener[0]);
|
||||
for (EventListener l : list) {
|
||||
if (l instanceof StateChangeListener) {
|
||||
((StateChangeListener) l).stateChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(StateChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(StateChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void fireChangeEvent() {
|
||||
EventObject event = new EventObject(this);
|
||||
// Copy the list before iterating to prevent concurrent modification exceptions.
|
||||
EventListener[] list = listeners.toArray(new EventListener[0]);
|
||||
for (EventListener l : list) {
|
||||
if (l instanceof StateChangeListener) {
|
||||
((StateChangeListener) l).stateChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,16 @@
|
||||
package info.openrocket.core.models.wind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import info.openrocket.core.util.Coordinate;
|
||||
import info.openrocket.core.util.MathUtil;
|
||||
import info.openrocket.core.util.ModID;
|
||||
import info.openrocket.core.util.PinkNoise;
|
||||
import info.openrocket.core.util.StateChangeListener;
|
||||
|
||||
/**
|
||||
* A wind simulator that generates wind speed as pink noise from a specified
|
||||
@ -46,6 +51,8 @@ public class PinkNoiseWindModel implements WindModel {
|
||||
private double time1;
|
||||
private double value1, value2;
|
||||
|
||||
private final List<StateChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct a new wind simulation with a specific seed value.
|
||||
*
|
||||
@ -222,4 +229,24 @@ public class PinkNoiseWindModel implements WindModel {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(StateChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(StateChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void fireChangeEvent() {
|
||||
EventObject event = new EventObject(this);
|
||||
// Copy the list before iterating to prevent concurrent modification exceptions.
|
||||
EventListener[] list = listeners.toArray(new EventListener[0]);
|
||||
for (EventListener l : list) {
|
||||
if (l instanceof StateChangeListener) {
|
||||
((StateChangeListener) l).stateChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,38 +3,9 @@ package info.openrocket.core.models.wind;
|
||||
import info.openrocket.core.util.ChangeSource;
|
||||
import info.openrocket.core.util.Coordinate;
|
||||
import info.openrocket.core.util.Monitorable;
|
||||
import info.openrocket.core.util.StateChangeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
public interface WindModel extends Monitorable, Cloneable, ChangeSource {
|
||||
List<StateChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
Coordinate getWindVelocity(double time, double altitude);
|
||||
|
||||
WindModel clone();
|
||||
|
||||
@Override
|
||||
default void addChangeListener(StateChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void removeChangeListener(StateChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
default void fireChangeEvent() {
|
||||
EventObject event = new EventObject(this);
|
||||
// Copy the list before iterating to prevent concurrent modification exceptions.
|
||||
EventListener[] list = listeners.toArray(new EventListener[0]);
|
||||
for (EventListener l : list) {
|
||||
if (l instanceof StateChangeListener) {
|
||||
((StateChangeListener) l).stateChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,9 @@ public class SimulationOptions implements ChangeSource, Cloneable, SimulationOpt
|
||||
|
||||
public SimulationOptions() {
|
||||
averageWindModel = new PinkNoiseWindModel(randomSeed);
|
||||
averageWindModel.addChangeListener(e -> fireChangeEvent());
|
||||
multiLevelPinkNoiseWindModel = new MultiLevelPinkNoiseWindModel();
|
||||
multiLevelPinkNoiseWindModel.addChangeListener(e -> fireChangeEvent());
|
||||
}
|
||||
|
||||
public double getLaunchRodLength() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user