Commit 437bc95e authored by Jean Meurice's avatar Jean Meurice
Browse files

BuildContext, SOCKET port type, ProgramInterface version, SimplePacketType

parent 9d67cb19
Pipeline #381047 failed with stage
in 33 seconds
......@@ -8,7 +8,7 @@
<groupId>montisim</groupId>
<artifactId>commons</artifactId>
<version>2.0.11</version>
<version>2.0.12</version>
<properties>
......
package de.rwth.montisim.commons;
import de.rwth.montisim.commons.boundingbox.*;
import de.rwth.montisim.commons.dynamicinterface.*;
import de.rwth.montisim.commons.simulation.*;
import de.rwth.montisim.commons.utils.json.Json;
public abstract class TypedCommons {
public static void registerTypedCommons() {
Json.registerType(AABB.class);
Json.registerType(OBB.class);
Json.registerType(Sphere.class);
Json.registerType(BasicType.class);
Json.registerType(DynVectorType.class);
Json.registerType(EnumType.class);
Json.registerType(MatrixType.class);
Json.registerType(StructType.class);
Json.registerType(VectorType.class);
Json.registerType(SimplePacketType.class);
Json.registerType(DynamicObject.class);
Json.registerType(StaticObject.class);
}
}
......@@ -9,6 +9,10 @@ import java.util.*;
import de.rwth.montisim.commons.utils.*;
import de.rwth.montisim.commons.utils.json.*;
/**
* The associated object must be of the Java type specified in the 'Type' enum ('c' param).
* For native types, use the 'valueOf()' method to get the associated object, ex: Double.valueOf(2.0).
*/
@Typed(BasicType.TYPE)
public class BasicType extends DataType {
public static final String TYPE = "basic";
......@@ -83,14 +87,14 @@ public class BasicType extends DataType {
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
if (o == null)
return;
Json.toJson(j, o, context);
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
if (base_type.c == null)
return null;
return Json.instantiateFromJson(j, base_type.c, context);
......
......@@ -6,18 +6,13 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.json.*;
/**
* Reflection class for the types of Messages sent in the simulation.
*/
public abstract class DataType {
static {
Json.registerType(BasicType.class);
Json.registerType(DynVectorType.class);
Json.registerType(VectorType.class);
Json.registerType(StructType.class);
}
public abstract int getDataSize(Object o);
......@@ -26,8 +21,8 @@ public abstract class DataType {
@Override
public abstract boolean equals(Object o);
public abstract void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException;
public abstract Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException;
public abstract void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException;
public abstract Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException;
public abstract void toBinary(DataOutputStream os, Object o) throws IOException;
public abstract Object fromBinary(DataInputStream is) throws IOException;
......
......@@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ArrayIterable;
......@@ -66,7 +67,7 @@ public class DynVectorType extends DataType {
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null)
return null;
......@@ -91,7 +92,7 @@ public class DynVectorType extends DataType {
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
......
......@@ -5,12 +5,8 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import de.rwth.montisim.commons.utils.json.Json;
import de.rwth.montisim.commons.utils.json.JsonTraverser;
import de.rwth.montisim.commons.utils.json.JsonWriter;
import de.rwth.montisim.commons.utils.json.SerializationContext;
import de.rwth.montisim.commons.utils.json.SerializationException;
import de.rwth.montisim.commons.utils.json.Typed;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.json.*;
/**
* Represents a named Enum with named variants. The corresponding object type
......@@ -80,12 +76,12 @@ public class EnumType extends DataType {
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
Json.toJson(j, o, context);
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
return Json.instantiateFromJson(j, String.class, context);
}
......
......@@ -6,6 +6,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ArrayIterable;
......@@ -68,7 +69,7 @@ public class MatrixType extends DataType {
//
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null)
return null;
......@@ -108,7 +109,7 @@ public class MatrixType extends DataType {
// Writes in an array: the row count then colum count then a series of row
// arrays
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
......
package de.rwth.montisim.commons.dynamicinterface;
import java.util.HashSet;
import java.util.Set;
public class PortInformation {
public static enum PortDirection {
INPUT,
OUTPUT
OUTPUT,
IO // Both, example: for a socket that can send and receive the same message type.
}
public static enum PortType {
DATA,
SOCKET
}
public String name;
public DataType type;
public PortType port_type = PortType.DATA;
public PortDirection direction;
public boolean allows_multiple_inputs;
public boolean optional;
public DataType data_type;
public boolean allows_multiple_inputs = true;
public boolean optional = false;
public final Set<String> tags = new HashSet<>(); // Tags for routing. Example: 'network' tag -> gets collected by the Gateway component
protected PortInformation() {}
public PortInformation(String name, DataType type, PortDirection dir, boolean multipleInputsAllowed){
this.name = name;
this.type = type;
this.direction = dir;
this.allows_multiple_inputs = multipleInputsAllowed;
this.optional = false;
}
public PortInformation(String name, DataType type, PortDirection dir, boolean multipleInputsAllowed, boolean optional){
protected PortInformation(String name, PortType port_type, DataType data_type, PortDirection dir, boolean multipleInputsAllowed, boolean optional){
this.name = name;
this.type = type;
this.port_type = port_type;
this.data_type = data_type;
this.direction = dir;
this.allows_multiple_inputs = multipleInputsAllowed;
this.optional = optional;
}
public static PortInformation newInputDataPort(String name, DataType dataType, boolean multipleInputsAllowed, boolean optional) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.INPUT, multipleInputsAllowed, optional);
}
public static PortInformation newOptionalInputDataPort(String name, DataType dataType, boolean multipleInputsAllowed) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.INPUT, multipleInputsAllowed, true);
}
public static PortInformation newRequiredInputDataPort(String name, DataType dataType, boolean multipleInputsAllowed) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.INPUT, multipleInputsAllowed, false);
}
public static PortInformation newOutputDataPort(String name, DataType dataType, boolean optional) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.OUTPUT, true, optional);
}
public static PortInformation newOptionalOutputDataPort(String name, DataType dataType) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.OUTPUT, true, true);
}
public static PortInformation newRequiredOutputDataPort(String name, DataType dataType) {
return new PortInformation(name, PortType.DATA, dataType, PortDirection.OUTPUT, true, false);
}
public static PortInformation newSocketPort(String name, DataType dataType, boolean in, boolean out) {
if (!in && !out) throw new IllegalArgumentException("newSocketPort() with neither 'in' or 'out'");
PortDirection pdir = in ? out ? PortDirection.IO : PortDirection.INPUT : PortDirection.OUTPUT;
return new PortInformation(name, PortType.SOCKET, dataType, pdir, true, true);
}
public PortInformation addTag(String tag) {
this.tags.add(tag);
return this;
}
public boolean isInput() {
return direction == PortDirection.INPUT || direction == PortDirection.IO;
}
public boolean isOutput() {
return direction == PortDirection.OUTPUT || direction == PortDirection.IO;
}
}
\ No newline at end of file
......@@ -3,10 +3,13 @@ package de.rwth.montisim.commons.dynamicinterface;
import java.util.Vector;
import de.rwth.montisim.commons.dynamicinterface.PortInformation.PortDirection;
import de.rwth.montisim.commons.dynamicinterface.PortInformation.PortType;
public class ProgramInterface {
public static final String CURRENT_VERSION = "2.0";
public String name;
public String version;
// The version should correspond to 'CURRENT_VERSION': allows to detect programs using an old version of the interface.
public String version;
public Vector<PortInformation> ports = new Vector<>();
@Override
......@@ -14,10 +17,14 @@ public class ProgramInterface {
String res = "ProgramInterface of "+name+ " (v" + version+"):\n";
for (PortInformation p : ports) {
res += '\t';
if (p.direction == PortDirection.INPUT) res += "I ";
else res += "O ";
res += p.name + ": "+p.type.toString()+"\n";
if (p.direction == PortDirection.INPUT) res += (p.port_type == PortType.SOCKET) ? "sock_in" : "I ";
else res += (p.port_type == PortType.SOCKET) ? "sock_out" : "O ";
res += p.name + ": "+p.data_type.toString()+"\n";
}
return res;
}
public boolean isVersionValid() {
return version.equals(CURRENT_VERSION);
}
}
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.Json;
import de.rwth.montisim.commons.utils.json.JsonTraverser;
import de.rwth.montisim.commons.utils.json.JsonWriter;
import de.rwth.montisim.commons.utils.json.SerializationException;
import de.rwth.montisim.commons.utils.json.Typed;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ValueType;
/**
* The associated Java object must be an Object array with two entries:
* - The Target/Sender IP (depending wether before or after the message passed the Network). (String)
* - The Payload: Associated object with 'payloadType'.
*/
@Typed(SimplePacketType.TYPE)
public class SimplePacketType extends DataType {
public static final String TYPE = "simple_packet";
public static final int HEADER_SIZE = 16; // TODO
private DataType payloadType;
public SimplePacketType(DataType payloadType) {
this.payloadType = payloadType;
}
private SimplePacketType() {
}
@Override
public int getDataSize(Object o) {
return HEADER_SIZE + payloadType.getDataSize(o);
}
@Override
public int hashCode() {
final int prime = 17;
int result = 7;
result = prime * result + ((payloadType == null) ? 0 : payloadType.hashCode());
return result;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
SimplePacketType a = ((SimplePacketType) o);
return this.payloadType.equals(a.payloadType);
}
@Override
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
Object packet[] = (Object[]) o;
j.startArray();
Json.toJson(j, packet[0], context);
payloadType.toJson(j, packet[1], context);
j.endArray();
}
@Override
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
Object res[] = new Object[2];
Iterator<ValueType> it = j.streamArray().iterator();
if (!it.hasNext()) throw new ParsingException("Missing 'Address' entry in SimplePacket.");
it.next();
res[0] = Json.instantiateFromJson(j, String.class, context);
if (!it.hasNext()) throw new ParsingException("Missing 'Payload' entry in SimplePacket.");
it.next();
res[1] = payloadType.fromJson(j, context);
if (it.hasNext()) throw new ParsingException("Unexpected entry in SimplePacket.");
return res;
}
@Override
public void toBinary(DataOutputStream os, Object o) throws IOException {
Object packet[] = (Object[]) o;
String addr = (String)packet[0];
os.writeShort(addr.length());
os.write(addr.getBytes());
payloadType.toBinary(os, packet[1]);
}
@Override
public Object fromBinary(DataInputStream is) throws IOException {
Object res[] = new Object[2];
short addrSize = is.readShort();
res[0] = new String(is.readNBytes(addrSize));
res[1] = payloadType.fromBinary(is);
return res;
}
@Override
public List<String> toString(Object o) {
Object packet[] = (Object[]) o;
ArrayList<String> res = new ArrayList<>();
res.add("SimplePacket: addr="+((String) packet[0])+" payload=");
res.addAll(payloadType.toString(packet[1]));
return res;
}
@Override
public Class<?> getArrayType() {
return Object[].class;
}
}
......@@ -6,13 +6,14 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ArrayIterable;
import de.rwth.montisim.commons.utils.json.JsonTraverser.Entry;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ObjectIterable;
/**
* Represents a named Struct with named and typed field. The corresponding
* Represents a named Struct with named and typed field. The corresponding Java
* object type must be an array of objects, in declaration order of the struct
* fields. Each object in the array must respect the data format for the field
* type. The serialization format for struct types is a JSON array with the
......@@ -121,7 +122,7 @@ public class StructType extends DataType implements CustomJson {
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
Object arr[] = (Object[]) o;
if (arr.length != field_types.size())
throw new IllegalArgumentException("Struct data-object has wrong number of entries.");
......@@ -133,7 +134,7 @@ public class StructType extends DataType implements CustomJson {
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
Object arr[] = new Object[field_types.size()];
ArrayIterable it = j.streamArray();
int i = 0;
......@@ -148,7 +149,7 @@ public class StructType extends DataType implements CustomJson {
}
@Override
public void write(JsonWriter w, SerializationContext context) throws SerializationException {
public void write(JsonWriter w, BuildContext context) throws SerializationException {
w.startObject();
w.write("type", "struct");
w.write("name", name);
......@@ -165,7 +166,7 @@ public class StructType extends DataType implements CustomJson {
}
@Override
public void read(JsonTraverser t, ObjectIterable it, SerializationContext context) throws SerializationException {
public void read(JsonTraverser t, ObjectIterable it, BuildContext context) throws SerializationException {
field_names.clear();
field_types.clear();
for (Entry e : it) {
......
......@@ -6,6 +6,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import de.rwth.montisim.commons.utils.BuildContext;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ValueType;
......@@ -69,7 +70,7 @@ public class VectorType extends DataType {
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
public Object fromJson(JsonTraverser j, BuildContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null)
return null;
......@@ -90,7 +91,7 @@ public class VectorType extends DataType {
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
public void toJson(JsonWriter j, Object o, BuildContext context) throws SerializationException {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
......
......@@ -13,9 +13,12 @@ import java.util.List;
public abstract class DiscreteEvent {
protected EventTarget target;
protected Instant time;
/// Might be set if the another event invalidated this one -> is then filtered out
public transient boolean invalid;
public DiscreteEvent(EventTarget target, Instant time){
this.target = target;
this.time = time;
this.invalid = false;
}
protected DiscreteEvent(){
}
......
......@@ -7,11 +7,13 @@ import java.util.PriorityQueue;
import de.rwth.montisim.commons.eventsimulation.exceptions.*;
import de.rwth.montisim.commons.simulation.TimeUpdate;
import de.rwth.montisim.commons.simulation.Updatable;
import de.rwth.montisim.commons.utils.BuildObject;
/**
* Abstract class for a discrete event simulation based on scheduled events.
*/
public class DiscreteEventSimulator implements Updatable {
public class DiscreteEventSimulator implements Updatable, BuildObject {
public static final String CONTEXT_KEY = "event_simulator";
/** Comparator for events. Sorts in ascending order of event time. */
private static final DiscreteEvent.DiscreteEventComparator listComparator = new DiscreteEvent.DiscreteEventComparator();
......@@ -44,7 +46,8 @@ public class DiscreteEventSimulator implements Updatable {
//loop until eventList is empty or next event is in future (not isAfter)
while(!eventList.isEmpty() && !eventList.peek().getEventTime().isAfter(newTime.newTime)){
cur = eventList.poll();
cur.target.process(cur);
if (!cur.invalid)
cur.target.process(cur);
this.simulationTime = cur.getEventTime();
}
this.simulationTime = newTime.newTime;
......@@ -68,4 +71,9 @@ public class DiscreteEventSimulator implements Updatable {
return "DiscreteEventSimulator{" + "simTime=" + simulationTime + ", events=" + eventList+ '}';
}
@Override
public String getKey() {
return CONTEXT_KEY;
}
}
......@@ -4,6 +4,7 @@ package de.rwth.montisim.commons.map;
import de.rwth.montisim.commons.utils.Vec2;
public interface Pathfinding {
public static final String CONTEXT_KEY = "pathfinding";
public Path findShortestPath(Vec2 startCoords, Vec2 targetCoords) throws Exception;
}
\ No newline at end of file
......@@ -2,7 +2,10 @@ package de.rwth.montisim.commons.physicalvalue;
import java.util.HashMap;
public class PhysicalValueRegistry {
import de.rwth.montisim.commons.utils.BuildObject;
public class PhysicalValueRegistry implements BuildObject {
public static final String CONTEXT_KEY = "physical_values";
HashMap<String, PhysicalValue> physicalValues = new HashMap<>();
/** Should only be for RESOLVING the physical values, not repeated access. */
......@@ -16,4 +19,9 @@ public class PhysicalValueRegistry {
if (physicalValues.containsKey(value.name)) throw new IllegalArgumentException("Double register for PhysicalValue: "+value.name);
physicalValues.put(value.name, value);
}