mirror of https://github.com/Minestom/Minestom.git
254 lines
12 KiB
Java
254 lines
12 KiB
Java
package net.minestom.codegen.attribute;
|
|
|
|
import com.google.gson.*;
|
|
import com.google.gson.stream.JsonReader;
|
|
import com.squareup.javapoet.*;
|
|
import net.minestom.codegen.MinestomCodeGenerator;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import javax.lang.model.element.Modifier;
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileReader;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
public final class AttributeGenerator extends MinestomCodeGenerator {
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(AttributeGenerator.class);
|
|
private final File attributesFile;
|
|
private final File outputFolder;
|
|
|
|
public AttributeGenerator(@NotNull File attributesFile, @NotNull File outputFolder) {
|
|
this.attributesFile = attributesFile;
|
|
this.outputFolder = outputFolder;
|
|
}
|
|
|
|
@Override
|
|
public void generate() {
|
|
if (!attributesFile.exists()) {
|
|
LOGGER.error("Failed to find attributes.json.");
|
|
LOGGER.error("Stopped code generation for attributes.");
|
|
return;
|
|
}
|
|
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
|
|
LOGGER.error("Output folder for code generation does not exist and could not be created.");
|
|
return;
|
|
}
|
|
// Important classes we use alot
|
|
ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID");
|
|
ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
|
|
|
|
JsonArray attributes;
|
|
try {
|
|
attributes = GSON.fromJson(new JsonReader(new FileReader(attributesFile)), JsonArray.class);
|
|
} catch (FileNotFoundException e) {
|
|
LOGGER.error("Failed to find attributes.json.");
|
|
LOGGER.error("Stopped code generation for attributes.");
|
|
return;
|
|
}
|
|
List<JavaFile> filesToWrite = new ArrayList<>();
|
|
|
|
ClassName attributeClassName = ClassName.get("net.minestom.server.attribute", "Attribute");
|
|
|
|
// Attribute
|
|
TypeSpec.Builder attributeClass = TypeSpec.classBuilder(attributeClassName)
|
|
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
|
|
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
|
attributeClass.addField(
|
|
FieldSpec.builder(namespaceIDClassName, "id")
|
|
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
|
|
);
|
|
attributeClass.addField(
|
|
FieldSpec.builder(TypeName.DOUBLE, "defaultValue")
|
|
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
|
);
|
|
attributeClass.addField(
|
|
FieldSpec.builder(TypeName.BOOLEAN, "clientSyncable")
|
|
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
|
);
|
|
attributeClass.addMethod(
|
|
MethodSpec.constructorBuilder()
|
|
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
|
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
|
|
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
|
|
.addStatement("this.id = id")
|
|
.addStatement("this.clientSyncable = clientSyncable")
|
|
.addStatement("this.defaultValue = defaultValue")
|
|
.addModifiers(Modifier.PROTECTED)
|
|
.build()
|
|
);
|
|
// Override key method (adventure)
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("key")
|
|
.returns(ClassName.get("net.kyori.adventure.key", "Key"))
|
|
.addAnnotation(Override.class)
|
|
.addAnnotation(NotNull.class)
|
|
.addStatement("return this.id")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// getId method
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("getId")
|
|
.returns(namespaceIDClassName)
|
|
.addAnnotation(NotNull.class)
|
|
.addStatement("return this.id")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// getDefaultValue
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("getDefaultValue")
|
|
.returns(TypeName.DOUBLE)
|
|
.addStatement("return this.defaultValue")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// isClientSyncable
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("isClientSyncable")
|
|
.returns(TypeName.BOOLEAN)
|
|
.addStatement("return this.clientSyncable")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// isShared
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("isShared")
|
|
.addAnnotation(Deprecated.class)
|
|
.returns(TypeName.BOOLEAN)
|
|
.addStatement("return this.clientSyncable")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// values method
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("values")
|
|
.addAnnotation(NotNull.class)
|
|
.returns(ParameterizedTypeName.get(ClassName.get(List.class), attributeClassName))
|
|
.addStatement("return $T.ATTRIBUTE_REGISTRY.values()", registryClassName)
|
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
|
.build()
|
|
);
|
|
// toString method
|
|
attributeClass.addMethod(
|
|
MethodSpec.methodBuilder("toString")
|
|
.addAnnotation(NotNull.class)
|
|
.addAnnotation(Override.class)
|
|
.returns(String.class)
|
|
// this resolves to [Namespace]
|
|
.addStatement("return \"[\" + this.id + \"]\"")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// Creating ClampedAttribute
|
|
ClassName clampedAttributeClassName = ClassName.get("net.minestom.server.attribute", "ClampedAttribute");
|
|
|
|
TypeSpec.Builder clampedAttributeClass = TypeSpec.classBuilder(clampedAttributeClassName)
|
|
.superclass(attributeClassName)
|
|
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
|
clampedAttributeClass.addField(
|
|
FieldSpec.builder(TypeName.DOUBLE, "minValue")
|
|
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
|
);
|
|
clampedAttributeClass.addField(
|
|
FieldSpec.builder(TypeName.DOUBLE, "maxValue")
|
|
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
|
);
|
|
clampedAttributeClass.addMethod(
|
|
MethodSpec.constructorBuilder()
|
|
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
|
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
|
|
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
|
|
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "minValue").build())
|
|
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "maxValue").build())
|
|
.addStatement("super(id, clientSyncable, defaultValue)")
|
|
.addStatement("this.minValue = minValue")
|
|
.addStatement("this.maxValue = maxValue")
|
|
.addModifiers(Modifier.PROTECTED)
|
|
.build()
|
|
);
|
|
// getMinValue
|
|
clampedAttributeClass.addMethod(
|
|
MethodSpec.methodBuilder("getMinValue")
|
|
.returns(TypeName.DOUBLE)
|
|
.addStatement("return this.minValue")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
// getMaxValue
|
|
clampedAttributeClass.addMethod(
|
|
MethodSpec.methodBuilder("getMaxValue")
|
|
.returns(TypeName.DOUBLE)
|
|
.addStatement("return this.maxValue")
|
|
.addModifiers(Modifier.PUBLIC)
|
|
.build()
|
|
);
|
|
|
|
CodeBlock.Builder staticBlock = CodeBlock.builder();
|
|
// Use data
|
|
for (JsonElement a : attributes) {
|
|
JsonObject attribute = a.getAsJsonObject();
|
|
String attributeName = attribute.get("name").getAsString();
|
|
|
|
JsonObject range = attribute.getAsJsonObject("range");
|
|
if (range == null) {
|
|
// Normal attribute
|
|
attributeClass.addField(
|
|
FieldSpec.builder(
|
|
attributeClassName,
|
|
attributeName
|
|
).initializer(
|
|
"new $T($T.from($S), $L, $L)",
|
|
attributeClassName,
|
|
namespaceIDClassName,
|
|
attribute.get("id").getAsString(),
|
|
attribute.get("clientSync").getAsBoolean(),
|
|
attribute.get("defaultValue").getAsDouble()
|
|
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
|
);
|
|
} else {
|
|
// ClampedAttribute
|
|
attributeClass.addField(
|
|
FieldSpec.builder(
|
|
attributeClassName,
|
|
attributeName
|
|
).initializer(
|
|
"new $T($T.from($S), $L, $L, $L, $L)",
|
|
clampedAttributeClassName,
|
|
namespaceIDClassName,
|
|
attribute.get("id").getAsString(),
|
|
attribute.get("clientSync").getAsBoolean(),
|
|
attribute.get("defaultValue").getAsDouble(),
|
|
range.get("minValue").getAsDouble(),
|
|
range.get("maxValue").getAsDouble()
|
|
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
|
);
|
|
}
|
|
// Add to static init.
|
|
staticBlock.addStatement("$T.ATTRIBUTE_REGISTRY.register($N)", registryClassName, attributeName);
|
|
}
|
|
attributeClass.addStaticBlock(staticBlock.build());
|
|
|
|
filesToWrite.add(
|
|
JavaFile.builder("net.minestom.server.attribute", attributeClass.build())
|
|
.indent(" ")
|
|
.skipJavaLangImports(true)
|
|
.build()
|
|
);
|
|
filesToWrite.add(
|
|
JavaFile.builder("net.minestom.server.attribute", clampedAttributeClass.build())
|
|
.indent(" ")
|
|
.skipJavaLangImports(true)
|
|
.build()
|
|
);
|
|
|
|
// Write files to outputFolder
|
|
writeFiles(
|
|
filesToWrite,
|
|
outputFolder
|
|
);
|
|
}
|
|
} |