Commit 4a0d12d2 authored by Jean Meurice's avatar Jean Meurice
Browse files

Merge branch 'ComponentRework' into 'master'

Automated Json Serialization

See merge request !10
parents 391e23d6 87d69cdf
Pipeline #307413 passed with stage
in 49 seconds
......@@ -8,7 +8,7 @@
<groupId>montisim</groupId>
<artifactId>commons</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
<properties>
......
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.boundingbox;
import de.rwth.montisim.commons.utils.JsonTraverser;
import de.rwth.montisim.commons.utils.JsonTraverser.ObjectIterable;
import de.rwth.montisim.commons.utils.JsonWriter;
import de.rwth.montisim.commons.utils.json.Typed;
@Typed("aabb")
public class AABB implements BoundingBox {
public static final String TYPE_NAME = "aabb";
// public static final String TYPE_NAME = "aabb";
@Override
public void toJson(JsonWriter j) {
// TODO Auto-generated method stub
// @Override
// public void toJson(JsonWriter j) {
// // TODO Auto-generated method stub
}
// }
@Override
public void fromJson(JsonTraverser j) {
// TODO Auto-generated method stub
// @Override
// public void fromJson(JsonTraverser j) {
// // TODO Auto-generated method stub
}
// }
@Override
public void fromJson(JsonTraverser j, ObjectIterable it) {
// TODO Auto-generated method stub
// @Override
// public void fromJson(JsonTraverser j, ObjectIterable it) {
// // TODO Auto-generated method stub
}
// }
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.boundingbox;
import de.rwth.montisim.commons.utils.JsonSerializable;
import de.rwth.montisim.commons.utils.JsonTraverser;
import de.rwth.montisim.commons.utils.Pair;
import de.rwth.montisim.commons.utils.JsonTraverser.ObjectIterable;
public interface BoundingBox {
// void fromJson(JsonTraverser j, ObjectIterable it);
public interface BoundingBox extends JsonSerializable {
void fromJson(JsonTraverser j, ObjectIterable it);
// public static BoundingBox buildFromJson(JsonTraverser j){
// Pair<String, ObjectIterable> p = j.getStructureType();
// BoundingBox bbox = getBoundingBoxFromType(p.getKey());
// bbox.fromJson(j, p.getValue());
// return bbox;
// }
public static BoundingBox buildFromJson(JsonTraverser j){
Pair<String, ObjectIterable> p = j.getStructureType();
BoundingBox bbox = getBoundingBoxFromType(p.getKey());
bbox.fromJson(j, p.getValue());
return bbox;
}
public static BoundingBox getBoundingBoxFromType(String type){
if (type.equals(OBB.TYPE_NAME)){
return new OBB();
} else if (type.equals(AABB.TYPE_NAME)){
return new AABB();
} else if (type.equals(Sphere.TYPE_NAME)){
return new Sphere();
} else throw new IllegalArgumentException("Unknown BoundingBox type: "+type);
}
// public static BoundingBox getBoundingBoxFromType(String type){
// if (type.equals(OBB.TYPE_NAME)){
// return new OBB();
// } else if (type.equals(AABB.TYPE_NAME)){
// return new AABB();
// } else if (type.equals(Sphere.TYPE_NAME)){
// return new Sphere();
// } else throw new IllegalArgumentException("Unknown BoundingBox type: "+type);
// }
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.boundingbox;
import de.rwth.montisim.commons.utils.JsonTraverser;
import de.rwth.montisim.commons.utils.JsonWriter;
import de.rwth.montisim.commons.utils.Mat3;
import de.rwth.montisim.commons.utils.Vec3;
import de.rwth.montisim.commons.utils.JsonTraverser.Entry;
import de.rwth.montisim.commons.utils.JsonTraverser.ObjectIterable;
import de.rwth.montisim.commons.utils.json.Typed;
//@JsonSubtype("obb") or @JsonTyped("obb") ?
//@JsonObject
@Typed("obb")
public class OBB implements BoundingBox {
public static final String TYPE_NAME = "obb";
//public static final String TYPE_NAME = "obb";
public Vec3 offset = new Vec3(); // Offset from center of mass
public Vec3 half_extent = new Vec3();
public Mat3 axes = new Mat3();
@Override
public void toJson(JsonWriter j) {
j.startObject();
j.write("type", TYPE_NAME);
j.writeKey("offset");
offset.toJson(j);
j.writeKey("half_extent");
half_extent.toJson(j);
j.writeKey("axes");
axes.toJson(j);
j.endObject();
}
// @Override
// public void toJson(JsonWriter j) {
// j.startObject();
// j.write("type", TYPE_NAME);
// j.writeKey("offset");
// offset.toJson(j);
// j.writeKey("half_extent");
// half_extent.toJson(j);
// j.writeKey("axes");
// axes.toJson(j);
// j.endObject();
// }
@Override
public void fromJson(JsonTraverser j) {
fromJson(j, j.streamObject());
}
// @Override
// public void fromJson(JsonTraverser j) {
// fromJson(j, j.streamObject());
// }
@Override
public void fromJson(JsonTraverser j, ObjectIterable it) {
boolean a = false, b = false, c = false;
for (Entry e : it) {
if (e.key.equals("offset")) {
offset.fromJson(j);
a = true;
} else if (e.key.equals("half_extent")) {
half_extent.fromJson(j);
b = true;
} else if (e.key.equals("axes")) {
axes.fromJson(j);
c = true;
} else
j.unexpected(e);
}
if (!a)
j.expected("offset");
if (!b)
j.expected("half_extent");
if (!c)
j.expected("axes");
}
// @Override
// public void fromJson(JsonTraverser j, ObjectIterable it) {
// boolean a = false, b = false, c = false;
// for (Entry e : it) {
// if (e.key.equals("offset")) {
// offset.fromJson(j);
// a = true;
// } else if (e.key.equals("half_extent")) {
// half_extent.fromJson(j);
// b = true;
// } else if (e.key.equals("axes")) {
// axes.fromJson(j);
// c = true;
// } else
// j.unexpected(e);
// }
// if (!a)
// j.expected("offset");
// if (!b)
// j.expected("half_extent");
// if (!c)
// j.expected("axes");
// }
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.boundingbox;
import de.rwth.montisim.commons.utils.JsonTraverser;
import de.rwth.montisim.commons.utils.JsonTraverser.ObjectIterable;
import de.rwth.montisim.commons.utils.JsonWriter;
import de.rwth.montisim.commons.utils.json.Typed;
@Typed("sphere")
public class Sphere implements BoundingBox {
public static final String TYPE_NAME = "sphere";
@Override
public void toJson(JsonWriter j) {
// TODO Auto-generated method stub
}
@Override
public void fromJson(JsonTraverser j) {
// TODO Auto-generated method stub
}
@Override
public void fromJson(JsonTraverser j, ObjectIterable it) {
// TODO Auto-generated method stub
}
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.util.Vector;
import de.rwth.montisim.commons.utils.JsonTraverser;
import de.rwth.montisim.commons.utils.JsonWriter;
import de.rwth.montisim.commons.utils.Vec2;
import de.rwth.montisim.commons.utils.Vec3;
import de.rwth.montisim.commons.utils.JsonTraverser.ValueType;
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;
public class ArrayType extends DataType {
public static enum Dimensionality {
ARRAY,
DYNAMIC
ARRAY, DYNAMIC
}
public DataType baseType;
public Dimensionality dimension;
/** Number of elems for "ARRAY", max size for "DYNAMIC". */
public int sizeOrMaxSize;
public int sizeOrMaxSize;
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".
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;
......@@ -28,17 +27,20 @@ public class ArrayType extends DataType {
}
@Override
public int getDataSize(){
public int getDataSize() {
return baseType.getDataSize() * sizeOrMaxSize;
}
@Override
public String toString(){
if (dimension == Dimensionality.ARRAY) return "["+baseType.toString()+"; "+sizeOrMaxSize+"]";
else return "<"+baseType.toString()+"; "+sizeOrMaxSize+">";
public String toString() {
if (dimension == Dimensionality.ARRAY)
return "[" + baseType.toString() + "; " + sizeOrMaxSize + "]";
else
return "<" + baseType.toString() + "; " + sizeOrMaxSize + ">";
}
// 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() {
......@@ -51,118 +53,22 @@ public class ArrayType extends DataType {
}
@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;
ArrayType a = ((ArrayType)o);
return this.baseType.equals(a.baseType) && this.dimension.equals(a.dimension) && this.sizeOrMaxSize == a.sizeOrMaxSize;
}
@Override
public void toJson(JsonWriter j, Object o){
j.startArray();
if (baseType.type == Type.DOUBLE) {
double[] a = (double[])o;
for (double d : a) j.writeValue(d);
} else if (baseType.type == Type.FLOAT) {
float[] a = (float[])o;
for (double f : a) j.writeValue(f);
} else if (baseType.type == Type.INT) {
int[] a = (int[])o;
for (int i : a) j.writeValue(i);
} else if (baseType.type == Type.BYTE) {
byte[] a = (byte[])o;
for (byte b : a) j.writeValue(b);
} else if (baseType.type == Type.BOOLEAN) {
boolean[] a = (boolean[])o;
for (boolean b : a) j.writeValue(b);
} else if (baseType.type == Type.EMPTY) {
} else if (baseType.type == Type.VEC2) {
Vec2[] a = (Vec2[])o;
for (Vec2 v : a) v.toJson(j);
} else if (baseType.type == Type.VEC3) {
Vec3[] a = (Vec3[])o;
for (Vec3 v : a) v.toJson(j);
} else throw new IllegalArgumentException("Missing array type implementation (type: "+type+")");
j.endArray();
ArrayType a = ((ArrayType) o);
return this.baseType.equals(a.baseType) && this.dimension.equals(a.dimension)
&& this.sizeOrMaxSize == a.sizeOrMaxSize;
}
@Override
public Object fromJson(JsonTraverser j){
if (baseType.type == Type.DOUBLE) {
Vector<Double> v = new Vector<>();
for (ValueType t : j.streamArray()){
v.add(j.getDouble());
}
double[] a = new double[v.size()];
int i = 0;
for (double d : v) a[i++] = d;
return a;
} else if (baseType.type == Type.FLOAT) {
Vector<Float> v = new Vector<>();
for (ValueType t : j.streamArray()){
v.add((float)j.getDouble());
}
float[] a = new float[v.size()];
int i = 0;
for (float f : v) a[i++] = f;
return a;
} else if (baseType.type == Type.INT) {
Vector<Integer> v = new Vector<>();
for (ValueType t : j.streamArray()){
v.add((int)j.getLong());
}
int[] a = new int[v.size()];
int i = 0;
for (int f : v) a[i++] = f;
return a;
} else if (baseType.type == Type.BYTE) {
Vector<Byte> v = new Vector<>();
for (ValueType t : j.streamArray()){
v.add((byte)j.getLong());
}
byte[] a = new byte[v.size()];
int i = 0;
for (byte b : v) a[i++] = b;
return a;
} else if (baseType.type == Type.BOOLEAN) {
Vector<Boolean> v = new Vector<>();
for (ValueType t : j.streamArray()){
v.add(j.getBoolean());
}
boolean[] a = new boolean[v.size()];
int i = 0;
for (boolean b : v) a[i++] = b;
return a;
} else if (baseType.type == Type.EMPTY) {
return null;
} else if (baseType.type == Type.VEC2) {
Vector<Vec2> v = new Vector<>();
for (ValueType t : j.streamArray()){
Vec2 vec = new Vec2();
vec.fromJson(j);
v.add(vec);
}
Vec2[] a = new Vec2[v.size()];
int i = 0;
for (Vec2 b : v) a[i++] = b;
return a;
} else if (baseType.type == Type.VEC3) {
Vector<Vec3> v = new Vector<>();
for (ValueType t : j.streamArray()){
Vec3 vec = new Vec3();
vec.fromJson(j);
v.add(vec);
}
Vec3[] a = new Vec3[v.size()];
int i = 0;
for (Vec3 b : v) a[i++] = b;
return a;
} else throw new IllegalArgumentException("Missing array type implementation (type: "+type+")");
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);
}
}
\ 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;
/**
* 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 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,
FLOAT,
INT,
BYTE,
BOOLEAN,
EMPTY,
VEC2,
VEC3,
STRUCT,
ARRAY
}
// @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);
@Override
public String toString(){
switch(type){
case DOUBLE: return "double";
case FLOAT: return "float";
case INT: return "int";
case BYTE: return "byte";
case BOOLEAN: return "bool";
case EMPTY: return "void";
case VEC2: return "Vec2";
case VEC3: return "Vec3";
case STRUCT: return "struct";
case ARRAY: return "array";
default: return "UNKNOWN_TYPE";
Type(Class<?> c, Class<?> arrayC, String name, int size) {
this.c = c;
this.arrayC = arrayC;
this.name = name;
this.size = size;
}
public final Class<?> c;
public final Class<?> arrayC;
public final String name;
public final int size;
}
public int getDataSize(){
switch (type){
case DOUBLE: return 8;
case FLOAT: return 4;
case INT: return 4;
case BYTE: return 1;
case BOOLEAN: return 1;
case EMPTY: return 0;
case VEC2: return 16;
case VEC3: return 24;
default:
return -1; //Should not occur
}
@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 int dataSize;
public DataType(Type type){
public DataType(Type type) {
this.type = type;
//this.dataSize = getDataSize();
// this.dataSize = getDataSize();
}
// protected DataType(Type type, int dataSize){
// this.type = type;
// this.dataSize = dataSize;
// this.type = type;
// this.dataSize = dataSize;
// }
@Override
public int hashCode() {
......@@ -89,47 +79,25 @@ public class DataType {
}
@Override
public boolean equals(Object o){
public boolean equals(Object o) {
if (o == null)
return false;