Entity IO fixes

This commit is contained in:
Anuken
2020-05-14 17:40:49 -04:00
parent 12f4d5a9a4
commit 6d23963e98
29 changed files with 226 additions and 109 deletions

View File

@@ -2,6 +2,7 @@ package mindustry.annotations.entity;
import arc.files.*;
import arc.struct.*;
import arc.util.*;
import arc.util.serialization.*;
import com.squareup.javapoet.*;
import mindustry.annotations.Annotations.*;
@@ -45,8 +46,8 @@ public class EntityIO{
Array<FieldSpec> fields = Array.with(type.fieldSpecs).select(spec ->
!spec.hasModifier(Modifier.TRANSIENT) &&
!spec.hasModifier(Modifier.STATIC) &&
!spec.hasModifier(Modifier.FINAL) &&
(spec.type.isPrimitive() || serializer.has(spec.type.toString())));
!spec.hasModifier(Modifier.FINAL)/* &&
(spec.type.isPrimitive() || serializer.has(spec.type.toString()))*/);
//sort to keep order
fields.sortComparing(f -> f.name);
@@ -116,6 +117,55 @@ public class EntityIO{
st("$L(write, $L)", serializer.writers.get(type), field);
}else if(serializer.readers.containsKey(type) && !write){
st("$L$L(read)", field, serializer.readers.get(type));
}else if(type.endsWith("[]")){ //it's a 1D array
String rawType = type.substring(0, type.length() - 2);
if(write){
s("i", field + ".length");
cont("for(int INDEX = 0; INDEX < $L.length; INDEX ++)", field);
io(rawType, field + "[INDEX]");
}else{
String fieldName = field.replace(" = ", "").replace("this.", "");
String lenf = fieldName + "_LENGTH";
s("i", "int " + lenf + " = ");
if(!field.isEmpty()){
st("$Lnew $L[$L]", field, type.replace("[]", ""), lenf);
}
cont("for(int INDEX = 0; INDEX < $L; INDEX ++)", lenf);
io(rawType, field.replace(" = ", "[INDEX] = "));
}
econt();
}else if(type.startsWith("arc.struct") && type.contains("<")){ //it's some type of data structure
String struct = type.substring(0, type.indexOf("<"));
String generic = type.substring(type.indexOf("<") + 1, type.indexOf(">"));
if(struct.equals("arc.struct.Queue") || struct.equals("arc.struct.Array")){
if(write){
s("i", field + ".size");
cont("for(int INDEX = 0; INDEX < $L.size; INDEX ++)", field);
io(generic, field + ".get(INDEX)");
}else{
String fieldName = field.replace(" = ", "").replace("this.", "");
String lenf = fieldName + "_LENGTH";
s("i", "int " + lenf + " = ");
if(!field.isEmpty()){
st("$L.clear()", field.replace(" = ", ""));
}
cont("for(int INDEX = 0; INDEX < $L; INDEX ++)", lenf);
io(generic, field.replace(" = ", "_ITEM = ").replace("this.", generic + " "));
if(!field.isEmpty()){
String temp = field.replace(" = ", "_ITEM").replace("this.", "");
st("if($L != null) $L.add($L)", temp, field.replace(" = ", ""), temp);
}
}
econt();
}else{
Log.warn("Missing serialization code for collection '@' in '@'", type, name);
}
}else{
Log.warn("Missing serialization code for type '@' in '@'", type, name);
}
}

View File

@@ -4,6 +4,7 @@ import arc.*;
import arc.files.*;
import arc.func.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.pooling.Pool.*;
@@ -262,7 +263,7 @@ public class EntityProcess extends BaseProcessor{
.addModifiers(Modifier.PUBLIC)
.addStatement("return $S + $L", name + "#", "id").build());
EntityIO io = new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name));
EntityIO io = ann.serialize() ? new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name)) : null;
//add all methods from components
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
@@ -323,7 +324,7 @@ public class EntityProcess extends BaseProcessor{
//SPECIAL CASE: I/O code
//note that serialization is generated even for non-serializing entities for manual usage
if((first.name().equals("read") || first.name().equals("write")) && ann.genio()){
if((first.name().equals("read") || first.name().equals("write")) && ann.genio() && ann.serialize()){
io.write(mbuilder, first.name().equals("write"));
}
@@ -620,7 +621,17 @@ public class EntityProcess extends BaseProcessor{
Array<Stype> allComponents(Selement<?> type){
if(!defComponents.containsKey(type)){
//get base defs
Array<Stype> components = types(type.annotation(EntityDef.class), EntityDef::value).map(this::interfaceToComp);
Array<Stype> interfaces = types(type.annotation(EntityDef.class), EntityDef::value);
Array<Stype> components = new Array<>();
for(Stype i : interfaces){
Stype comp = interfaceToComp(i);
if(comp != null){
components.add(comp);
}else{
throw new IllegalArgumentException("Type '" + i + "' is not a component interface!");
}
}
ObjectSet<Stype> out = new ObjectSet<>();
for(Stype comp : components){
//get dependencies for each def, add them
@@ -665,7 +676,7 @@ public class EntityProcess extends BaseProcessor{
return interfaceToComp(type) != null;
}
Stype interfaceToComp(Stype type){
@Nullable Stype interfaceToComp(Stype type){
String name = type.name().substring(0, type.name().length() - 1) + "Comp";
return componentNames.get(name);
}