Commit 64065fc1 authored by Jean Meurice's avatar Jean Meurice
Browse files

DataType+ProgramInterface+DiscreteEventSim update

parent ff3d4c42
Pipeline #336462 passed with stage
in 31 seconds
......@@ -8,7 +8,7 @@
<groupId>montisim</groupId>
<artifactId>commons</artifactId>
<version>2.0.4</version>
<version>2.0.5</version>
<properties>
......
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.lang.reflect.InvocationTargetException;
import de.rwth.montisim.commons.utils.json.Json;
import de.rwth.montisim.commons.utils.json.JsonTraverser;
import de.rwth.montisim.commons.utils.json.SerializationContext;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ValueType;
@Typed("array")
public class ArrayType extends DataType {
public static enum Dimensionality {
ARRAY, DYNAMIC
}
public DataType baseType;
public Dimensionality dimension;
/** Number of elems for "ARRAY", max size for "DYNAMIC". */
public int sizeOrMaxSize;
public DataType base_type;
public int size;
public ArrayType(DataType baseType, Dimensionality dim, int sizeOrMaxSize) {
// super(DataType.Type.ARRAY, baseType.getDataSize() * sizeOrMaxSize); //Must
// give dataSize manually since the default super() calls getDataSize() which is
// invalid before setting "baseType" & "sizeOrMaxSize".
super(DataType.Type.ARRAY);
this.baseType = baseType;
this.dimension = dim;
this.sizeOrMaxSize = sizeOrMaxSize;
public ArrayType(DataType base_type, int size) {
this.base_type = base_type;
this.size = size;
}
private ArrayType() {}
@Override
public int getDataSize() {
return baseType.getDataSize() * sizeOrMaxSize;
public int getDataSize(Object o) {
// TODO optimize size calls
int size = 0;
Object arr[] = (Object[]) o;
for (Object oi : arr) size += base_type.getDataSize(oi);
return size;
}
@Override
public String toString() {
if (dimension == Dimensionality.ARRAY)
return "[" + baseType.toString() + "; " + sizeOrMaxSize + "]";
else
return "<" + baseType.toString() + "; " + sizeOrMaxSize + ">";
return "[" + base_type.toString() + "; " + size + "]";
//return "<" + base_type.toString() + "; " + size + ">";
}
// Implement hashCode & equals to be able to perform hashmap lookup by type &
......@@ -46,9 +39,8 @@ public class ArrayType extends DataType {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((baseType == null) ? 0 : baseType.hashCode());
result = prime * result + ((dimension == null) ? 0 : dimension.hashCode());
result = prime * result + Integer.valueOf(sizeOrMaxSize).hashCode();
result = prime * result + ((base_type == null) ? 0 : base_type.hashCode());
result = prime * result + Integer.valueOf(size).hashCode();
return result;
}
......@@ -61,14 +53,50 @@ public class ArrayType extends DataType {
if (this.getClass() != o.getClass())
return false;
ArrayType a = ((ArrayType) o);
return this.baseType.equals(a.baseType) && this.dimension.equals(a.dimension)
&& this.sizeOrMaxSize == a.sizeOrMaxSize;
return this.base_type.equals(a.base_type) && this.size == a.size;
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
if (baseType.type.arrayC == null) return null;
return Json.instantiateFromJson(j, baseType.type.arrayC, context);
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null) return null;
if (array_c != Object[].class)
return Json.instantiateFromJson(j, array_c, context);
Object o[] = new Object[size];
int i = 0;
for (ValueType t : j.streamArray()){
if (i >= size) throw new ParsingException("Too much entries in Array serialization.");
o[i] = base_type.fromJson(j, context);
i++;
}
if (i < size) throw new ParsingException("Missing entries in Array serialization.");
return o;
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
if (array_c == null) return;
if (array_c != Object[].class){
Json.toJson(j, o, context);
return;
}
Object arr[] = (Object[]) o;
j.startArray();
if (arr.length != size) throw new IllegalArgumentException("Array length does not match its ArrayType length");
for (Object oi : arr){
base_type.toJson(j, oi, context);
}
j.endArray();
}
@Override
public Class<?> getArrayType() {
return Object[].class;
}
}
\ No newline at end of file
package de.rwth.montisim.commons.dynamicinterface;
import de.rwth.montisim.commons.utils.*;
import de.rwth.montisim.commons.utils.json.*;
@Typed(BasicType.TYPE)
public class BasicType extends DataType {
public static final String TYPE = "basic";
public static final BasicType DOUBLE = new BasicType(Type.DOUBLE);
public static final BasicType FLOAT = new BasicType(Type.FLOAT);
public static final BasicType INT = new BasicType(Type.INT);
public static final BasicType BOOLEAN = new BasicType(Type.BOOLEAN);
public static final BasicType BYTE = new BasicType(Type.BYTE);
public static final BasicType EMPTY = new BasicType(Type.EMPTY);
public static final BasicType VEC2 = new BasicType(Type.VEC2);
public static final BasicType VEC3 = new BasicType(Type.VEC3);
public BasicType(Type basic_type) {
this.base_type = basic_type;
}
private BasicType(){}
public Type base_type;
public static enum Type {
@JsonEntry("double")
DOUBLE(Double.class, double[].class, 8),
@JsonEntry("float")
FLOAT(Float.class, float[].class, 4),
@JsonEntry("int")
INT(Integer.class, int[].class, 4),
@JsonEntry("byte")
BYTE(Byte.class, byte[].class, 1),
@JsonEntry("boolean")
BOOLEAN(Boolean.class, boolean[].class, 1),
@JsonEntry("void")
EMPTY(null, null, 0),
@JsonEntry("vec2")
VEC2(Vec2.class, Object[].class, 16),
@JsonEntry("vec3")
VEC3(Vec3.class, Object[].class, 24);
Type(Class<?> c, Class<?> array_c, int size) {
this.c = c;
this.array_c = array_c;
this.size = size;
}
public final Class<?> c;
public final Class<?> array_c;
public final int size;
}
@Override
public int getDataSize(Object o) {
return base_type.size;
}
@Override
public int hashCode() {
return base_type.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
return this.base_type == ((BasicType) o).base_type;
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
if (o == null)
return;
Json.toJson(j, o, context);
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
if (base_type.c == null) return null;
return Json.instantiateFromJson(j, base_type.c, context);
}
@Override
public Class<?> getArrayType() {
return base_type.array_c;
}
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.lang.reflect.InvocationTargetException;
import de.rwth.montisim.commons.utils.*;
import de.rwth.montisim.commons.utils.json.Json;
import de.rwth.montisim.commons.utils.json.JsonEntry;
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.*;
/**
* Reflection class for the types of Messages sent in the simulation.
*/
public class DataType {
public static final DataType DOUBLE = new DataType(Type.DOUBLE);
public static final DataType FLOAT = new DataType(Type.FLOAT);
public static final DataType INT = new DataType(Type.INT);
public static final DataType BOOLEAN = new DataType(Type.BOOLEAN);
public static final DataType BYTE = new DataType(Type.BYTE);
public static final DataType EMPTY = new DataType(Type.EMPTY);
public static final DataType VEC2 = new DataType(Type.VEC2);
public static final DataType VEC3 = new DataType(Type.VEC3);
public static enum Type {
// @JsonEntry
DOUBLE(Double.class, double[].class, "double", 8),
FLOAT(Float.class, float[].class, "float", 4),
INT(Integer.class, int[].class, "int", 4),
BYTE(Byte.class, byte[].class, "byte", 1),
BOOLEAN(Boolean.class, boolean[].class, "boolean", 1),
EMPTY(null, null, "void", 0),
VEC2(Vec2.class, Vec2[].class, "Vec2", 16),
VEC3(Vec3.class, Vec3[].class, "Vec3", 24),
STRUCT(null, null, "struct", -1),
ARRAY(null, null, "array", -1);
Type(Class<?> c, Class<?> arrayC, String name, int size) {
this.c = c;
this.arrayC = arrayC;
this.name = name;
this.size = size;
public abstract class DataType {
static {
try {
Json.registerType(BasicType.class);
Json.registerType(VectorType.class);
Json.registerType(ArrayType.class);
Json.registerType(StructType.class);
} catch (SerializationException e) {
e.printStackTrace();
System.exit(-1);
}
public final Class<?> c;
public final Class<?> arrayC;
public final String name;
public final int size;
}
@Override
public String toString() {
return type.name;
}
public int getDataSize() {
return type.size;
}
public Type type;
/// The virtual message size in bytes
// public int dataSize;
public DataType(Type type) {
this.type = type;
// this.dataSize = getDataSize();
}
// protected DataType(Type type, int dataSize){
// this.type = type;
// this.dataSize = dataSize;
// }
public abstract int getDataSize(Object o);
@Override
public int hashCode() {
return type.hashCode();
}
public abstract int hashCode();
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
return this.type == ((DataType) o).type;
}
public abstract boolean equals(Object o);
public void toJson(JsonWriter j, Object o, SerializationContext context) throws IllegalArgumentException, IllegalAccessException {
if (o == null)
return;
Json.toJson(j, o, context);
}
public abstract void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException;
public abstract Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException;
public Object fromJson(JsonTraverser j, SerializationContext context) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
if (type.c == null) return null;
return Json.instantiateFromJson(j, type.c, context);
}
public abstract Class<?> getArrayType();
}
\ No newline at end of file
package de.rwth.montisim.commons.dynamicinterface;
public class PortInformation {
public static enum PortDirection {
INPUT,
OUTPUT
}
public String name;
public DataType type;
public PortDirection direction;
public boolean allows_multiple_inputs;
public boolean optional;
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){
this.name = name;
this.type = type;
this.direction = dir;
this.allows_multiple_inputs = multipleInputsAllowed;
this.optional = optional;
}
}
\ No newline at end of file
package de.rwth.montisim.commons.dynamicinterface;
import java.util.Vector;
public class ProgramInterface {
public String name;
public String version;
public Vector<PortInformation> ports = new Vector<>();
}
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.util.HashMap;
import java.util.Vector;
// TODO use a vector and index based entries
public class StructType extends DataType {
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;
@Typed("struct")
public class StructType extends DataType implements CustomJson {
public String name;
public HashMap<String, DataType> components;
public StructType(String name){
super(DataType.Type.STRUCT);
public Vector<String> fieldNames = new Vector<>();
public Vector<DataType> fieldTypes = new Vector<>();
public StructType(String name) {
this.name = name;
components = new HashMap<>();
}
/**
private StructType() {
}
/**
* Adds a field to the struct type.
*/
public void addComponent(String fieldName, DataType fieldType){
components.put(fieldName, fieldType);
*/
public void addField(String fieldName, DataType fieldType) {
fieldNames.add(fieldName);
fieldTypes.add(fieldType);
}
@Override
public String toString(){
public String toString() {
String res = name + "{ ";
boolean first = true;
for (HashMap.Entry<String, DataType> entry : components.entrySet()) {
if (first){
for (int i = 0; i < fieldNames.size(); ++i) {
if (first) {
first = false;
} else {
res += ", ";
}
res += entry.getKey() + ": " + entry.getValue();
}
res += fieldNames.elementAt(i) + ": " + fieldTypes.elementAt(i);
}
res += "}";
return res;
}
// Implement hashCode & equals to be able to perform hashmap lookup by type & type comparison
// Implement hashCode & equals to be able to perform hashmap lookup by type &
// type comparison
@Override
public int hashCode() {
final int prime = 31;
int result = name.hashCode();
for (HashMap.Entry<String, DataType> entry : components.entrySet()) {
result = prime * result + entry.getKey().hashCode();
result = prime * result + entry.getValue().hashCode();
}
for (int i = 0; i < fieldNames.size(); ++i) {
result = prime * result + fieldNames.elementAt(i).hashCode();
result = prime * result + fieldTypes.elementAt(i).hashCode();
}
return result;
}
@Override
public boolean equals(Object o){
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
StructType s = ((StructType)o);
if (!this.name.equals(s.name)) return false;
if (this.components.size() != s.components.size()) return false;
for (HashMap.Entry<String, DataType> entry : components.entrySet()) {
DataType t = s.components.get(entry.getKey());
if (t == null) return false;
if (!t.equals(entry.getValue())) return false;
}
StructType s = ((StructType) o);
if (!this.name.equals(s.name))
return false;
if (this.fieldNames.size() != s.fieldNames.size())
return false;
for (int i = 0; i < fieldNames.size(); ++i) {
if (!fieldNames.elementAt(i).equals(s.fieldNames.elementAt(i)))
return false;
if (!fieldTypes.elementAt(i).equals(s.fieldTypes.elementAt(i)))
return false;
}
return true;
}
@Override
public int getDataSize(Object o) {
Object arr[] = (Object[]) o;
if (arr.length != fieldTypes.size())
throw new IllegalArgumentException("Struct data-object has wrong number of entries.");
int size = 0;
for (int i = 0; i < fieldTypes.size(); ++i) {
size += fieldTypes.elementAt(i).getDataSize(arr[i]);
}
return size;
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
Object arr[] = (Object[]) o;
if (arr.length != fieldTypes.size())
throw new IllegalArgumentException("Struct data-object has wrong number of entries.");
j.startArray();
for (int i = 0; i < fieldTypes.size(); ++i) {
fieldTypes.elementAt(i).toJson(j, arr[i], context);
}
j.endArray();
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
Object arr[] = new Object[fieldTypes.size()];
ArrayIterable it = j.streamArray();
int i = 0;
for (DataType t : fieldTypes) {
if (!it.iterator().hasNext())
throw new IllegalArgumentException("Struct data-object serialization missing entries.");
it.iterator().next();
arr[i] = t.fromJson(j, context);
++i;
}
return arr;
}
@Override
public void write(JsonWriter w, SerializationContext context) throws SerializationException {
w.startObject();
w.write("type", "struct");
w.write("name", name);