mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-11-13 07:15:28 +03:00
Annotation processor cleanup
This commit is contained in:
parent
85e0103ff8
commit
5e977312a7
@ -14,43 +14,20 @@ import javax.tools.Diagnostic.*;
|
||||
import javax.tools.*;
|
||||
import java.util.*;
|
||||
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
|
||||
public class AssetsAnnotationProcessor extends AbstractProcessor{
|
||||
/** Name of the base package to put all the generated classes. */
|
||||
private static final String packageName = "mindustry.gen";
|
||||
public class AssetsAnnotationProcessor extends BaseProcessor{
|
||||
private String path;
|
||||
private int round;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||
super.init(processingEnv);
|
||||
//put all relevant utils into utils class
|
||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||
Utils.elementUtils = processingEnv.getElementUtils();
|
||||
Utils.filer = processingEnv.getFiler();
|
||||
Utils.messager = processingEnv.getMessager();
|
||||
}
|
||||
public void process(RoundEnvironment env) throws Exception{
|
||||
path = Fi.get(Utils.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no")
|
||||
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
|
||||
.parent().parent().parent().parent().parent().parent().toString();
|
||||
path = path.replace("%20", " ");
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
if(round++ != 0) return false; //only process 1 round
|
||||
|
||||
try{
|
||||
path = Fi.get(Utils.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no")
|
||||
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
|
||||
.parent().parent().parent().parent().parent().parent().toString();
|
||||
path = path.replace("%20", " ");
|
||||
|
||||
processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound");
|
||||
processSounds("Musics", path + "/assets/music", "arc.audio.Music");
|
||||
processUI(roundEnv.getElementsAnnotatedWith(StyleDefaults.class));
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound");
|
||||
processSounds("Musics", path + "/assets/music", "arc.audio.Music");
|
||||
processUI(env.getElementsAnnotatedWith(StyleDefaults.class));
|
||||
}
|
||||
|
||||
void processUI(Set<? extends Element> elements) throws Exception{
|
||||
|
@ -0,0 +1,38 @@
|
||||
package mindustry.annotations;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.*;
|
||||
import javax.lang.model.element.*;
|
||||
import java.util.*;
|
||||
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
public abstract class BaseProcessor extends AbstractProcessor{
|
||||
/** Name of the base package to put all the generated classes. */
|
||||
public static final String packageName = "mindustry.gen";
|
||||
|
||||
private int round;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||
super.init(processingEnv);
|
||||
//put all relevant utils into utils class
|
||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||
Utils.elementUtils = processingEnv.getElementUtils();
|
||||
Utils.filer = processingEnv.getFiler();
|
||||
Utils.messager = processingEnv.getMessager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
if(round++ != 0) return false; //only process 1 round
|
||||
try{
|
||||
process(roundEnv);
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void process(RoundEnvironment env) throws Exception;
|
||||
}
|
@ -14,109 +14,86 @@ import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize")
|
||||
public class SerializeAnnotationProcessor extends AbstractProcessor{
|
||||
public class SerializeAnnotationProcessor extends BaseProcessor{
|
||||
/** Target class name. */
|
||||
private static final String className = "Serialization";
|
||||
/** Name of the base package to put all the generated classes. */
|
||||
private static final String packageName = "mindustry.gen";
|
||||
private static final String data = "eJztV0tvGzcQvvfQ3zDRIeDCKhsbQVDUsgP5UViH2IHl9BIEBsUdSYxX3C3Jlawm+XH9Z53hUg/bkuOmOfRQwfDuDme++ebBWe6PfwU3/wTwUU2VLJQdSYfDAnWQvxkschjCAUyMzWtPetJikF2nzzG8deXU5OjkW6VvMPTRGVWYP0mgC+W9HGE4Qbp1mEcg0Zo5E9C1sn2AofQYulqj92ZQoAiuxqVc2Loo2iCU03JYWy2PS+v3OndJNF7bDW1rSnk0D3hUD4foDjNRtWGQwU+HQIGZoajAWB+U1VgOYROOZx+Wgm4eMzJ7ghpoyo14Cl5FsQ2I4PsPcE2/XXpssk7kOMw6mEJe9KXxXZu70uTM4Jjz2Hl9CJ79xCc5LN25mqBoqUZPVosy9DEEY0eebnTtMKZ5iaDddgRd2oA2MGO+XqIvi2mq0xJAqQ0ARHzA8dncywWar91QaZwanMkUS7eqCqNVMKW9x+qRuO6wug3R8GGLvsEwLnMYMZBS6z3XrIgWidYhLgYfyQ50IyKrkZbGTssbjHU4Lh1KVVWbvaUNEf8fUFXYX+rt7vnJ5UXv5Lp3Et30g6NagDK55RZpHrNoyUaxwx+PyA+XLtZCaYBabSpoOzlptttX0uM8oen7aJsqnhLkkixmyPlFjlLe1kL0a/ER6YVis4UXKO2YCbYyNkCBnBQv6ToKY5Gt9kauAveZxVkjYc2fYe8DT4bSCTY2tP5iny4dxuGbnQPY4+3Cxu9N1GdODJAJcTxWTmmaOzI3IxOEl5ok3SBM1obdVxl0OvAyA9iB7Zq0uNtoM9cvy9gpvLoIiXAjW+1mnwZi7Ht5pDy+enlc8k5Fq+kqmG8EpBnQIEn8o1aFp25a/C66B60sgzB25Sx6uaxtMBM8vdVYMbBoHakc3r3rnchYvjhdiBGDM1csPD4cMr3Sc8ZSGHVtuJ+X/e8Xk2TZcKLFOtR2rVYizM8EdDqpwlxkDJZKeCcnUfYLl4+f2MFEhbG8pE0uMhqXt4Gntk/hM3Ti8k0JTSgM8zCWqg7LKPiyWcurKYr1PDaYi0x+Wi08gVaOkdYT85paa+Enbubo4NTWE3QRvtO87eg1Qy/gWeluerQd47w9BCRSsHWdfd6XebGcGptMoKw58Dhe4IwrXJYFKkspEKnYfImdRB0R7+GAasezjRIXamdhSP2M+1/rjv7cB5xI5Zya67KaN2BteNFOFvE2CtPUYObJxbN/1Sxb9hw8f/7dgbsMnKoMcAbjlIezWAcecJRxkmHcGacFTmg48xrLuYBnyuUzerl185y8UPkW6YbPn+HZWFJhtmlmMSKUY+XfUC8m8NgBG52uDeXrVFnYhv3Py3u9sb7X9wu8eMUE9x1GArUoAW0rNyVw42r3WwfwanDQHx1+9FhcMYii4y6E/6fvf3T6UiaZLA3BtXO9Zvvf0Xn2MahNEfmv1unr42peYe9Cxk+chD6gU5qcNla8/GQbSwfhJyvXvslmpC2oxOXAUIe9TgegXfgVXizXOSxN4RSlW9nEnK4eGzsGolO9pw+6xXC6d/pa0yDBzs7db6ZHGEczPgSbO+88qBpVMYjSbH/Trgn0vUM8+oE+O67otMbt8uWHvwGqGwCj";
|
||||
|
||||
private int round;
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
if(round++ != 0) return false; //only process 1 round
|
||||
public void process(RoundEnvironment env) throws Exception{
|
||||
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Serialize.class));
|
||||
|
||||
try{
|
||||
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Serialize.class));
|
||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||
classBuilder.addStaticBlock(CodeBlock.of(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)))).readUTF()));
|
||||
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
|
||||
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||
|
||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||
classBuilder.addStaticBlock(CodeBlock.of(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)))).readUTF()));
|
||||
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
|
||||
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
for(TypeElement elem : elements){
|
||||
TypeName type = TypeName.get(elem.asType());
|
||||
String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1);
|
||||
|
||||
for(TypeElement elem : elements){
|
||||
TypeName type = TypeName.get(elem.asType());
|
||||
String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1);
|
||||
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
||||
.addSuperinterface(ParameterizedTypeName.get(
|
||||
ClassName.bestGuess("arc.Settings.TypeSerializer"), type));
|
||||
|
||||
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
||||
.addSuperinterface(ParameterizedTypeName.get(
|
||||
ClassName.bestGuess("arc.Settings.TypeSerializer"), type));
|
||||
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
||||
.returns(void.class)
|
||||
.addParameter(DataOutput.class, "stream")
|
||||
.addParameter(type, "object")
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
||||
.returns(void.class)
|
||||
.addParameter(DataOutput.class, "stream")
|
||||
.addParameter(type, "object")
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
||||
.returns(type)
|
||||
.addParameter(DataInput.class, "stream")
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
||||
.returns(type)
|
||||
.addParameter(DataInput.class, "stream")
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
readMethod.addStatement("$L object = new $L()", type, type);
|
||||
|
||||
readMethod.addStatement("$L object = new $L()", type, type);
|
||||
List<VariableElement> fields = ElementFilter.fieldsIn(Utils.elementUtils.getAllMembers(elem));
|
||||
for(VariableElement field : fields){
|
||||
if(field.getModifiers().contains(Modifier.STATIC) || field.getModifiers().contains(Modifier.TRANSIENT) || field.getModifiers().contains(Modifier.PRIVATE))
|
||||
continue;
|
||||
|
||||
List<VariableElement> fields = ElementFilter.fieldsIn(Utils.elementUtils.getAllMembers(elem));
|
||||
for(VariableElement field : fields){
|
||||
if(field.getModifiers().contains(Modifier.STATIC) || field.getModifiers().contains(Modifier.TRANSIENT) || field.getModifiers().contains(Modifier.PRIVATE))
|
||||
continue;
|
||||
String name = field.getSimpleName().toString();
|
||||
String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.');
|
||||
String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||
|
||||
String name = field.getSimpleName().toString();
|
||||
String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.');
|
||||
String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||
|
||||
if(field.asType().getKind().isPrimitive()){
|
||||
writeMethod.addStatement("stream.write" + capName + "(object." + name + ")");
|
||||
readMethod.addStatement("object." + name + "= stream.read" + capName + "()");
|
||||
}else{
|
||||
writeMethod.addStatement("arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
|
||||
readMethod.addStatement("object." + name + " = (" + typeName + ")arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
|
||||
}
|
||||
if(field.asType().getKind().isPrimitive()){
|
||||
writeMethod.addStatement("stream.write" + capName + "(object." + name + ")");
|
||||
readMethod.addStatement("object." + name + "= stream.read" + capName + "()");
|
||||
}else{
|
||||
writeMethod.addStatement("arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
|
||||
readMethod.addStatement("object." + name + " = (" + typeName + ")arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
|
||||
}
|
||||
|
||||
readMethod.addStatement("return object");
|
||||
|
||||
serializer.addMethod(writeMethod.build());
|
||||
serializer.addMethod(readMethod.build());
|
||||
|
||||
method.addStatement("arc.Core.settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
||||
|
||||
name(writeMethod, "write" + simpleTypeName);
|
||||
name(readMethod, "read" + simpleTypeName);
|
||||
|
||||
writeMethod.addModifiers(Modifier.STATIC);
|
||||
readMethod.addModifiers(Modifier.STATIC);
|
||||
|
||||
classBuilder.addMethod(writeMethod.build());
|
||||
classBuilder.addMethod(readMethod.build());
|
||||
}
|
||||
|
||||
classBuilder.addMethod(method.build());
|
||||
readMethod.addStatement("return object");
|
||||
|
||||
//write result
|
||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||
serializer.addMethod(writeMethod.build());
|
||||
serializer.addMethod(readMethod.build());
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
method.addStatement("arc.Core.settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
||||
|
||||
name(writeMethod, "write" + simpleTypeName);
|
||||
name(readMethod, "read" + simpleTypeName);
|
||||
|
||||
writeMethod.addModifiers(Modifier.STATIC);
|
||||
readMethod.addModifiers(Modifier.STATIC);
|
||||
|
||||
classBuilder.addMethod(writeMethod.build());
|
||||
classBuilder.addMethod(readMethod.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||
super.init(processingEnv);
|
||||
//put all relevant utils into utils class
|
||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||
Utils.elementUtils = processingEnv.getElementUtils();
|
||||
Utils.filer = processingEnv.getFiler();
|
||||
Utils.messager = processingEnv.getMessager();
|
||||
classBuilder.addMethod(method.build());
|
||||
|
||||
//write result
|
||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||
}
|
||||
|
||||
static void name(MethodSpec.Builder builder, String name){
|
||||
|
@ -17,148 +17,126 @@ import java.util.Set;
|
||||
* Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size.
|
||||
* It would be nice if Java didn't make crazy hacks like this necessary.
|
||||
*/
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedAnnotationTypes({
|
||||
"mindustry.annotations.Annotations.Struct"
|
||||
})
|
||||
public class StructAnnotationProcessor extends AbstractProcessor{
|
||||
/** Name of the base package to put all the generated classes. */
|
||||
private static final String packageName = "mindustry.gen";
|
||||
private int round;
|
||||
public class StructAnnotationProcessor extends BaseProcessor{
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||
super.init(processingEnv);
|
||||
//put all relevant utils into utils class
|
||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||
Utils.elementUtils = processingEnv.getElementUtils();
|
||||
Utils.filer = processingEnv.getFiler();
|
||||
Utils.messager = processingEnv.getMessager();
|
||||
}
|
||||
public void process(RoundEnvironment env) throws Exception{
|
||||
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Struct.class));
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
if(round++ != 0) return false; //only process 1 round
|
||||
for(TypeElement elem : elements){
|
||||
|
||||
try{
|
||||
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class));
|
||||
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
||||
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(TypeElement elem : elements){
|
||||
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
||||
String structParam = structName.toLowerCase();
|
||||
|
||||
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
||||
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
||||
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
||||
|
||||
try{
|
||||
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
||||
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
|
||||
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
||||
|
||||
if(variables.size() == 0){
|
||||
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
||||
String structParam = structName.toLowerCase();
|
||||
//obtain type which will be stored
|
||||
Class<?> structType = typeForSize(structSize);
|
||||
|
||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
||||
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
||||
//[constructor] get(fields...) : structType
|
||||
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
|
||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||
.returns(structType);
|
||||
|
||||
try{
|
||||
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
||||
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
|
||||
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
||||
StringBuilder cons = new StringBuilder();
|
||||
StringBuilder doc = new StringBuilder();
|
||||
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
||||
|
||||
if(variables.size() == 0){
|
||||
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
|
||||
continue;
|
||||
}
|
||||
int offset = 0;
|
||||
for(VariableElement var : variables){
|
||||
int size = varSize(var);
|
||||
TypeName varType = TypeName.get(var.asType());
|
||||
String varName = var.getSimpleName().toString();
|
||||
|
||||
//obtain type which will be stored
|
||||
Class<?> structType = typeForSize(structSize);
|
||||
//add val param to constructor
|
||||
constructor.addParameter(varType, varName);
|
||||
|
||||
//[constructor] get(fields...) : structType
|
||||
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
|
||||
//[get] field(structType) : fieldType
|
||||
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||
.returns(structType);
|
||||
.returns(varType)
|
||||
.addParameter(structType, structParam);
|
||||
//[set] field(structType, fieldType) : structType
|
||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||
.returns(structType)
|
||||
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||
|
||||
StringBuilder cons = new StringBuilder();
|
||||
StringBuilder doc = new StringBuilder();
|
||||
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
||||
|
||||
int offset = 0;
|
||||
for(VariableElement var : variables){
|
||||
int size = varSize(var);
|
||||
TypeName varType = TypeName.get(var.asType());
|
||||
String varName = var.getSimpleName().toString();
|
||||
|
||||
//add val param to constructor
|
||||
constructor.addParameter(varType, varName);
|
||||
|
||||
//[get] field(structType) : fieldType
|
||||
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||
.returns(varType)
|
||||
.addParameter(structType, structParam);
|
||||
//[set] field(structType, fieldType) : structType
|
||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||
.returns(structType)
|
||||
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||
|
||||
//[getter]
|
||||
if(varType == TypeName.BOOLEAN){
|
||||
//bools: single bit, is simplified
|
||||
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
||||
}else if(varType == TypeName.FLOAT){
|
||||
//floats: need conversion
|
||||
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
|
||||
}else{
|
||||
//bytes, shorts, chars, ints
|
||||
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
|
||||
}
|
||||
|
||||
//[setter] + [constructor building]
|
||||
if(varType == TypeName.BOOLEAN){
|
||||
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
|
||||
|
||||
//bools: single bit, needs special case to clear things
|
||||
setter.beginControlFlow("if(value)");
|
||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
|
||||
setter.nextControlFlow("else");
|
||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
|
||||
setter.endControlFlow();
|
||||
}else if(varType == TypeName.FLOAT){
|
||||
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
|
||||
|
||||
//floats: need conversion
|
||||
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||
}else{
|
||||
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
||||
|
||||
//bytes, shorts, chars, ints
|
||||
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||
}
|
||||
|
||||
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
|
||||
|
||||
//add finished methods
|
||||
classBuilder.addMethod(getter.build());
|
||||
classBuilder.addMethod(setter.build());
|
||||
|
||||
offset += size;
|
||||
//[getter]
|
||||
if(varType == TypeName.BOOLEAN){
|
||||
//bools: single bit, is simplified
|
||||
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
||||
}else if(varType == TypeName.FLOAT){
|
||||
//floats: need conversion
|
||||
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
|
||||
}else{
|
||||
//bytes, shorts, chars, ints
|
||||
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
|
||||
}
|
||||
|
||||
classBuilder.addJavadoc(doc.toString());
|
||||
//[setter] + [constructor building]
|
||||
if(varType == TypeName.BOOLEAN){
|
||||
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
|
||||
|
||||
//add constructor final statement + add to class and build
|
||||
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
||||
classBuilder.addMethod(constructor.build());
|
||||
//bools: single bit, needs special case to clear things
|
||||
setter.beginControlFlow("if(value)");
|
||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
|
||||
setter.nextControlFlow("else");
|
||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
|
||||
setter.endControlFlow();
|
||||
}else if(varType == TypeName.FLOAT){
|
||||
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
|
||||
|
||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||
}catch(IllegalArgumentException e){
|
||||
e.printStackTrace();
|
||||
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
|
||||
//floats: need conversion
|
||||
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||
}else{
|
||||
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
||||
|
||||
//bytes, shorts, chars, ints
|
||||
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||
}
|
||||
|
||||
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
|
||||
|
||||
//add finished methods
|
||||
classBuilder.addMethod(getter.build());
|
||||
classBuilder.addMethod(setter.build());
|
||||
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
classBuilder.addJavadoc(doc.toString());
|
||||
|
||||
//add constructor final statement + add to class and build
|
||||
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
||||
classBuilder.addMethod(constructor.build());
|
||||
|
||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||
}catch(IllegalArgumentException e){
|
||||
e.printStackTrace();
|
||||
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static String bitString(int offset, int size, int totalSize){
|
||||
|
@ -308,8 +308,10 @@ project(":annotations"){
|
||||
apply plugin: "java"
|
||||
|
||||
dependencies{
|
||||
def arcVersion = "e287fdce0449a87fb15599c67b5167ac0273bcb6"
|
||||
|
||||
compile 'com.squareup:javapoet:1.11.0'
|
||||
compile "com.github.Anuken.Arc:arc-core:b77767039334b2658f44d69e72d1ef6bc84f95b0"
|
||||
compile "com.github.Anuken.Arc:arc-core:$arcVersion"
|
||||
compile files("${System.getProperty('java.home')}/../lib/tools.jar")
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import java.util.*;
|
||||
|
||||
import static arc.Core.settings;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Vars implements Loadable{
|
||||
/** Whether to load locales.*/
|
||||
public static boolean loadLocales = true;
|
||||
@ -60,7 +59,7 @@ public class Vars implements Loadable{
|
||||
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json";
|
||||
/** URL to the JSON file containing all the BE servers. Only queried in BE. */
|
||||
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
|
||||
/** URL the links to the wiki's modding guide.*/
|
||||
/** URL of the github issue report template.*/
|
||||
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?template=bug_report.md";
|
||||
/** list of built-in servers.*/
|
||||
public static final Array<String> defaultServers = Array.with();
|
||||
|
@ -1,3 +1,3 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=bf5f253d458e0b8bddf9efcc3642a644f4b48fb6
|
||||
archash=e287fdce0449a87fb15599c67b5167ac0273bcb6
|
||||
|
Loading…
Reference in New Issue
Block a user