Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 3d22ac80 authored by Jakob Schöttl's avatar Jakob Schöttl
Browse files

Merge branch 'attributescloneable' into develop

This branch makes attributes being Cloneable.
For attributes, the default shallow clone implementation is used.
This is good as long as attributes do not have mutable sub-objects.
Note that VShape objects are not and must not be mutable.

ScenarioElements implement a clone method. Implementations use a
constructor and pass cloned attributes. ScenarioElements are not
Cloneable because they do not user super.clone() which makes a shallow
copy.
parents b523ea4c 4f85fecf
......@@ -9,7 +9,6 @@ import javax.swing.undo.UndoableEditSupport;
import org.vadere.gui.topographycreator.model.AgentWrapper;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VPoint;
......@@ -24,7 +23,7 @@ public class ActionInsertCopiedElement extends TopographyAction {
private static final long serialVersionUID = 5049099647921341318L;
private final UndoableEditSupport undoSupport;
public ActionInsertCopiedElement(final String name, final IDrawPanelModel model,
public ActionInsertCopiedElement(final String name, final IDrawPanelModel<?> model,
final UndoableEditSupport undoSupport) {
super(name, model);
this.undoSupport = undoSupport;
......@@ -32,7 +31,7 @@ public class ActionInsertCopiedElement extends TopographyAction {
@Override
public void actionPerformed(ActionEvent e) {
IDrawPanelModel model = getScenarioPanelModel();
IDrawPanelModel<?> model = getScenarioPanelModel();
ScenarioElement elementToCopy = model.getCopiedElement();
if (elementToCopy == null) {
......@@ -45,7 +44,7 @@ public class ActionInsertCopiedElement extends TopographyAction {
VPoint elementPos = getElementPosition(elementToCopy);
VPoint diff = model.getMousePosition().subtract(elementPos);
VShape newShape = model.translate(diff);
VShape newShape = model.translateElement(elementToCopy, diff);
if (elementToCopy instanceof AgentWrapper) {
VPoint position = new VPoint(newShape.getBounds2D().getCenterX(), newShape.getBounds2D().getCenterY());
......
......@@ -15,19 +15,19 @@ import org.vadere.gui.topographycreator.model.IDrawPanelModel;
public abstract class TopographyAction extends AbstractAction {
private static final long serialVersionUID = 7643236418545161283L;
private final IDrawPanelModel panelModel;
private final IDrawPanelModel<?> panelModel;
public TopographyAction(final String name, final ImageIcon icon, final IDrawPanelModel panelModel) {
public TopographyAction(final String name, final ImageIcon icon, final IDrawPanelModel<?> panelModel) {
super(name, icon);
this.panelModel = panelModel;
}
public TopographyAction(final String name, final IDrawPanelModel panelModel) {
public TopographyAction(final String name, final IDrawPanelModel<?> panelModel) {
super(name);
this.panelModel = panelModel;
}
protected IDrawPanelModel getScenarioPanelModel() {
protected IDrawPanelModel<?> getScenarioPanelModel() {
return panelModel;
}
}
......@@ -20,68 +20,60 @@ import org.vadere.util.geometry.shapes.VShape;
*
*
*/
public final class AgentWrapper implements ScenarioElement {
/** we only need the radius from the attributes. */
private final AttributesAgent attributes;
public final class AgentWrapper extends ScenarioElement {
/** the wrapped store object. */
private Agent store;
/**
* the shape of this Pedestrian (VCircle). For refection, this attribute has to be changeable
* (not final)
*/
// private VShape shape;
/** The wrapped store object. */
private Agent agent;
AgentWrapper(final VPoint position) {
this.attributes = new AttributesAgent();
this.store = new Pedestrian(this.attributes, new Random()); // use a Pedestrian as default
this.store.setPosition(position);
this.store.setTargets(new LinkedList<Integer>());
// this.shape = new VCircle(store.position, attributes.getRadius());
}
public AgentWrapper(final Agent store) {
this.attributes = store.getAttributes();
this.store = store.clone();
// this.shape = new VCircle(store.position, attributes.getRadius());
// use a Pedestrian as default
// TODO this default does not make much sense
this.agent = new Pedestrian(new AttributesAgent(), new Random());
this.agent.setPosition(position);
this.agent.setTargets(new LinkedList<Integer>());
}
private AgentWrapper(final AgentWrapper wrapper) {
this.attributes = wrapper.attributes;
this.store = wrapper.store.clone();
public AgentWrapper(final Agent agent) {
this.agent = (Agent) agent.clone();
}
public Agent getAgentInitialStore() {
return store;
return agent;
}
public void setAgentInitialStore(final Agent store) {
this.store = store;
this.agent = store;
}
@Override
public void setShape(VShape newShape) {
agent.setShape(newShape);
}
@Override
public VShape getShape() {
return store.getShape();
return agent.getShape();
}
@Override
public int getId() {
return attributes.getId();
return agent.getId();
}
@Override
public ScenarioElementType getType() {
// TODO bug - this is a agent wrapper, not necessarily an pedestrian wrapper
return ScenarioElementType.PEDESTRIAN;
}
@Override
public AgentWrapper clone() {
return new AgentWrapper(this);
public Attributes getAttributes() {
return agent.getAttributes();
}
@Override
public Attributes getAttributes() {
return attributes;
public AgentWrapper clone() {
return new AgentWrapper((Agent) agent.clone());
}
}
......@@ -4,7 +4,6 @@ import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ComponentListener;
import java.util.Observer;
import org.vadere.gui.components.control.IMode;
......@@ -21,6 +20,7 @@ import org.vadere.util.geometry.shapes.VShape;
public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<T>, Iterable<ScenarioElement> {
@Override
void notifyObservers();
/**
......@@ -67,17 +67,20 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
*
* @return true if the user is selecting a topography element, otherwise false.
*/
@Override
boolean isSelectionVisible();
/**
* After this call the selction shape will be painted.
*/
@Override
void showSelection();
/**
* After this call the selction shape will no longer be painted.
*/
@Override
void hideSelection();
/**
......@@ -93,14 +96,17 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
void resetScenario();
@Override
ScenarioElement getSelectedElement();
Color getCursorColor();
void setCursorColor(Color red);
@Override
void setMouseSelectionMode(IMode selectionMode);
@Override
IMode getMouseSelectionMode();
Cursor getCursor();
......@@ -128,6 +134,7 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
* @param position
* @return
*/
@Override
ScenarioElement setSelectedElement(VPoint position);
boolean removeElement(ScenarioElement element);
......@@ -142,10 +149,12 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
void setTopography(Topography topography);
@Override
void notifyObservers(final Object string);
int getBoundId();
@Override
void setSelectedElement(ScenarioElement selectedElement);
VShape translate(Point vector);
......@@ -165,4 +174,6 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
void setCopiedElement(ScenarioElement copiedElement);
VShape translate(VPoint vector);
VShape translateElement(ScenarioElement elementToCopy, VPoint diff);
}
......@@ -25,7 +25,6 @@ import org.vadere.util.geometry.shapes.VShape;
/**
* The data of the DrawPanel. Its holds the whole data of one scenario.
*
*
*/
public class TopographyCreatorModel extends DefaultModel implements IDrawPanelModel {
......@@ -221,13 +220,6 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
return font;
}
/*
* @Override
* public double getFinishTime() {
* return topographyBuilder.getAttributes().getFinishTime();
* }
*/
@Override
public void setTopographyBound(final VRectangle scenarioBound) {
try {
......@@ -329,18 +321,20 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
@Override
public VShape translate(final Point vector) {
// double factor = Math.max(10,1/getGridResulution());
VPoint worldVector = new VPoint(vector.x / getScaleFactor(), -vector.y / getScaleFactor());
return translate(worldVector);
}
@Override
public VShape translate(final VPoint vector) {
// double factor = Math.max(10,1/getGridResulution());
return getSelectedElement().getShape().translatePrecise(alignToGrid(vector));
return translateElement(getSelectedElement(), vector);
}
// can return null!
@Override
public VShape translateElement(ScenarioElement element, VPoint vector) {
// double factor = Math.max(10,1/getGridResulution()); // ?? related to scaleTopography?
return element.getShape().translatePrecise(alignToGrid(vector));
}
@Override
public int getBoundId() {
......@@ -435,9 +429,9 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
return topographyBuilder.build();
}
// privte helper methods
private VPoint alignToGrid(final VPoint point) {
double factor = Math.max(10, 1 / getGridResolution());
return new VPoint(Math.round(point.x * factor) / factor, Math.round(point.y * factor) / factor);
}
}
......@@ -39,7 +39,7 @@ public class TestTrajectory extends TestCase {
new Pedestrian(new AttributesAgent(-1), new Random()));
steps.forEach(step -> pedestriansByStep.put(step,
pedestrians.stream().map(ped -> ped.clone())
pedestrians.stream().map(ped -> (Agent) ped.clone())
.peek(ped -> ped.setPosition(
ped.getPosition().add(new VPoint(step.getStepNumber(), step.getStepNumber()))))
.collect(Collectors.toList())));
......
......@@ -317,5 +317,10 @@ public class PedestrianOSM extends Pedestrian {
public double getMinStepLength() {
return minStepLength;
}
@Override
public PedestrianOSM clone() {
throw new RuntimeException("clone is not supported for PedestrianOSM; it seems hard to implement.");
}
}
......@@ -13,4 +13,10 @@ public class TargetQueue extends Target {
public boolean isMovingTarget() {
return true;
}
@Override
public TargetQueue clone() {
throw new RuntimeException("clone is not supported for TargetQueue; it seems hard to implement.");
}
}
......@@ -16,7 +16,19 @@ package org.vadere.state.attributes;
* VPoint,...).
*
*/
public abstract class Attributes extends DefaultSealable {
public abstract class Attributes extends DefaultSealable implements Cloneable {
/** Used for default ID values of some scenario elements. */
protected static final int ID_NOT_SET = -1;
public Attributes() {}
@Override
public Attributes clone() {
try {
return (Attributes) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("This should never happen because the base class is Cloneable.", e);
}
}
}
......@@ -19,6 +19,10 @@ public class AttributesObstacle extends Attributes {
this.shape = shape;
}
public void setShape(VShape shape) {
this.shape = shape;
}
public VShape getShape() {
return shape;
}
......
......@@ -123,6 +123,10 @@ public class AttributesSource extends Attributes {
return id;
}
public void setShape(VShape shape) {
this.shape = shape;
}
public VShape getShape() {
return shape;
}
......
......@@ -42,6 +42,10 @@ public class AttributesStairs extends Attributes {
}
}
public void setShape(VShape shape) {
this.shape = shape;
}
public VShape getShape() {
return shape;
}
......
......@@ -99,6 +99,10 @@ public class AttributesTarget extends Attributes {
return id;
}
public void setShape(VShape shape) {
this.shape = shape;
}
public VShape getShape() {
return shape;
}
......
......@@ -14,7 +14,7 @@ import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.math.TruncatedNormalDistribution;
public abstract class Agent implements DynamicElement {
public abstract class Agent extends DynamicElement {
/**
* Source where the agent was spawned. The {@link SourceController} should
......@@ -65,9 +65,9 @@ public abstract class Agent implements DynamicElement {
this.setTargets(new LinkedList<>(other.targetIds));
this.setNextTargetListIndex(other.nextTargetListIndex);
this.setPosition(other.position);
this.setVelocity(other.velocity);
this.setFreeFlowSpeed(other.freeFlowSpeed);
this.position = other.position;
this.velocity = other.velocity;
this.freeFlowSpeed = other.freeFlowSpeed;
}
public LinkedList<Integer> getTargets() {
......@@ -98,6 +98,11 @@ public abstract class Agent implements DynamicElement {
public VPoint getPosition() {
return position;
}
@Override
public void setShape(VShape newShape) {
position = newShape.getCentroid();
}
@Override
public VShape getShape() {
......@@ -113,9 +118,6 @@ public abstract class Agent implements DynamicElement {
return attributes.getId();
}
@Override
public abstract Agent clone();
/**
* Converts a Iterable of Agent to a List of VPoint positions.
*
......
package org.vadere.state.scenario;
import java.util.LinkedList;
import java.util.Random;
import org.vadere.state.attributes.scenario.AttributesCar;
......@@ -23,18 +22,6 @@ public class Car extends Agent implements Comparable<Car> {
// this.targetIds = new LinkedList<>();
}
/**
* Constructor for cloning
*
* @param other: Car to clone
*/
private Car(Car other) {
this(other.attributesCar, null); // TODO car cannot be cloned because it cannot provide a random
setPosition(other.getPosition());
setVelocity(other.getVelocity());
setTargets(new LinkedList<>(other.getTargets()));
}
@Override
public int compareTo(Car o) {
Double thisPos = new Double(getPosition().getX());
......@@ -71,11 +58,6 @@ public class Car extends Agent implements Comparable<Car> {
return ScenarioElementType.CAR;
}
@Override
public Car clone() {
return new Car(this);
}
@Override
public AttributesCar getAttributes() {
return this.attributesCar;
......@@ -86,4 +68,12 @@ public class Car extends Agent implements Comparable<Car> {
return attributesCar.getId();
}
@Override
public Car clone() {
throw new RuntimeException("clone is not supported for Car; it seems hard to implement.");
// return new Car(attributesCar, new Random());
// TODO get random from super class instead of creating a new one
// TODO attributesAgent in super class must be copied as well
}
}
......@@ -2,5 +2,5 @@ package org.vadere.state.scenario;
import org.vadere.util.geometry.PointPositioned;
public interface DynamicElement extends ScenarioElement, PointPositioned {
public abstract class DynamicElement extends ScenarioElement implements PointPositioned {
}
......@@ -5,7 +5,7 @@ import org.vadere.state.attributes.scenario.AttributesObstacle;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VShape;
public class Obstacle implements ScenarioElement {
public class Obstacle extends ScenarioElement {
private final AttributesObstacle attributes;
......@@ -15,13 +15,10 @@ public class Obstacle implements ScenarioElement {
this.attributes = attributes;
}
/**
* Returns a copy of this obstacle with the same attributes.
*/
@Override
public Obstacle clone() {
return new Obstacle(attributes);
public void setShape(VShape newShape) {
attributes.setShape(newShape);
}
@Override
......@@ -73,4 +70,9 @@ public class Obstacle implements ScenarioElement {
public Attributes getAttributes() {
return attributes;
}
@Override
public Obstacle clone() {
return new Obstacle((AttributesObstacle) attributes.clone());
}
}
......@@ -60,11 +60,6 @@ public class Pedestrian extends Agent {
}
}
@Override
public Pedestrian clone() {
return new Pedestrian(this);
}
public <T extends ModelPedestrian> T getModelPedestrian(Class<? extends T> modelType) {
return (T) modelPedestrianMap.get(modelType);
}
......@@ -117,4 +112,10 @@ public class Pedestrian extends Agent {
public void setLikelyInjured(boolean likelyInjured) {
this.isLikelyInjured = likelyInjured;
}
@Override
public Pedestrian clone() {
return new Pedestrian(this);
}
}
......@@ -4,19 +4,25 @@ import org.vadere.state.attributes.Attributes;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VShape;
public interface ScenarioElement extends Cloneable {
public abstract class ScenarioElement {
VShape getShape();
public abstract VShape getShape();
default void setShape(VShape newShape) {
public void setShape(VShape newShape) {
throw new UnsupportedOperationException("This concrete scenario element does not support setting the shape.");
}
int getId();
public abstract int getId();
ScenarioElementType getType();
public abstract ScenarioElementType getType();
ScenarioElement clone();
/**
* Redeclare the clone method as public to enable copy & paste of scenario
* elements in scenario editor.
* Subclasses must implement this method using a copy constructor.
*/
@Override
public abstract ScenarioElement clone();
Attributes getAttributes();
public abstract Attributes getAttributes();
}
......@@ -4,7 +4,7 @@ import org.vadere.state.attributes.scenario.AttributesSource;
import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VShape;
public class Source implements ScenarioElement {