mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-12-15 15:20:57 -08:00
Auto-generated serialization code
This commit is contained in:
parent
dadc83800b
commit
2cb6e454c8
13 changed files with 160 additions and 41 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -21,7 +21,7 @@
|
|||
/android/assets/mindustry-saves/
|
||||
/core/assets/gifexport/
|
||||
/core/assets/version.properties
|
||||
/core/assets/locales.json
|
||||
/core/assets/locales
|
||||
/ios/src/io/anuke/mindustry/gen/
|
||||
*.gif
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ import java.lang.annotation.Target;
|
|||
*/
|
||||
public class Annotations{
|
||||
|
||||
/** Marks a class as serializable.*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Serialize{
|
||||
|
||||
}
|
||||
|
||||
public enum PacketPriority{
|
||||
/** Gets put in a queue and processed if not connected. */
|
||||
normal,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
package io.anuke.annotations;
|
||||
|
||||
import com.squareup.javapoet.*;
|
||||
import io.anuke.annotations.Annotations.Serialize;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedAnnotationTypes({
|
||||
"io.anuke.annotations.Annotations.Serialize"
|
||||
})
|
||||
public class SerializeAnnotationProcessor extends AbstractProcessor{
|
||||
/**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 = "io.anuke.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 boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||
if(round++ != 0) return false; //only process 1 round
|
||||
|
||||
try{
|
||||
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Serialize.class));
|
||||
|
||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
|
||||
for(TypeElement elem : elements){
|
||||
TypeName type = TypeName.get(elem.asType());
|
||||
|
||||
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
||||
.addSuperinterface(ParameterizedTypeName.get(
|
||||
ClassName.get(Class.forName("io.anuke.ucore.io.TypeSerializer")), type));
|
||||
|
||||
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
||||
.returns(void.class)
|
||||
.addParameter(DataOutput.class, "stream")
|
||||
.addParameter(type, "object")
|
||||
.addAnnotation(Override.class)
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
||||
.returns(type)
|
||||
.addParameter(DataInput.class, "stream")
|
||||
.addAnnotation(Override.class)
|
||||
.addException(IOException.class)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
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;
|
||||
|
||||
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("io.anuke.ucore.core.Settings.getSerializer(" + typeName+ ".class).write(stream, object." + name + ")");
|
||||
readMethod.addStatement("object." + name + " = (" +typeName+")io.anuke.ucore.core.Settings.getSerializer(" + typeName+ ".class).read(stream)");
|
||||
}
|
||||
}
|
||||
|
||||
readMethod.addStatement("return object");
|
||||
|
||||
serializer.addMethod(writeMethod.build());
|
||||
serializer.addMethod(readMethod.build());
|
||||
|
||||
method.addStatement("io.anuke.ucore.core.Settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
||||
}
|
||||
|
||||
classBuilder.addMethod(method.build());
|
||||
|
||||
//write result
|
||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
build.gradle
14
build.gradle
|
|
@ -27,7 +27,7 @@ allprojects {
|
|||
appName = 'Mindustry'
|
||||
gdxVersion = '1.9.8'
|
||||
roboVMVersion = '2.3.0'
|
||||
uCoreVersion = '7aa05daa277ffb67cda3d2d047c37b2f441e4e4e'
|
||||
uCoreVersion = '7fafee20b6bf5615e009d2be20d1c1331d1e66c1'
|
||||
|
||||
getVersionString = {
|
||||
String buildVersion = getBuildVersion()
|
||||
|
|
@ -44,14 +44,13 @@ allprojects {
|
|||
}
|
||||
|
||||
generateLocales = {
|
||||
def output = '["en",'
|
||||
def output = 'en\n'
|
||||
def bundles = new File(project(':core').projectDir, 'assets/bundles/')
|
||||
bundles.listFiles().each { other ->
|
||||
if(other.name == "bundle.properties") return;
|
||||
output += '"' + other.name.substring("bundle".length() + 1, other.name.lastIndexOf('.')) + '",'
|
||||
output += other.name.substring("bundle".length() + 1, other.name.lastIndexOf('.')) + "\n"
|
||||
}
|
||||
output = (output.substring(0, output.size() - 1) + "]")
|
||||
new File(project(':core').projectDir, 'assets/locales.json').text = output;
|
||||
new File(project(':core').projectDir, 'assets/locales').text = output;
|
||||
}
|
||||
|
||||
writeVersion = {
|
||||
|
|
@ -118,9 +117,6 @@ project(":html") {
|
|||
compile "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion:sources"
|
||||
}
|
||||
|
||||
compileJava.options.compilerArgs = [
|
||||
"-processor", "io.anuke.annotations.RemoteMethodAnnotationProcessor"
|
||||
]
|
||||
}
|
||||
|
||||
project(":ios") {
|
||||
|
|
@ -185,7 +181,7 @@ project(":core") {
|
|||
}
|
||||
|
||||
compileJava.options.compilerArgs = [
|
||||
"-processor", "io.anuke.annotations.RemoteMethodAnnotationProcessor"
|
||||
"-processor", "io.anuke.annotations.RemoteMethodAnnotationProcessor,io.anuke.annotations.SerializeAnnotationProcessor"
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.Application.ApplicationType;
|
|||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import io.anuke.mindustry.core.*;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
|
|
@ -16,6 +15,7 @@ import io.anuke.mindustry.entities.traits.SyncTrait;
|
|||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Version;
|
||||
import io.anuke.mindustry.gen.Serialization;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
|
|
@ -138,9 +138,10 @@ public class Vars{
|
|||
public static final Translator[] tmptr = new Translator[]{new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
|
||||
public static void init(){
|
||||
Serialization.init();
|
||||
|
||||
//load locales
|
||||
String[] stra = new Json().fromJson(String[].class, Gdx.files.internal("locales.json"));
|
||||
String[] stra = Gdx.files.internal("locales").readString().split("\n");
|
||||
locales = new Locale[stra.length];
|
||||
for(int i = 0; i < locales.length; i++){
|
||||
String code = stra[i];
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public class Control extends Module{
|
|||
private Throwable error;
|
||||
|
||||
public Control(){
|
||||
|
||||
saves = new Saves();
|
||||
db = new ContentDatabase();
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class ContentDatabase{
|
|||
}
|
||||
|
||||
public void load(){
|
||||
ObjectMap<ContentType, Array<String>> result = Settings.getJson("content-database", ObjectMap.class);
|
||||
ObjectMap<ContentType, Array<String>> result = Settings.getBinary("content-database", ObjectMap.class, () -> new ObjectMap<>());
|
||||
|
||||
for(Entry<ContentType, Array<String>> entry : result.entries()){
|
||||
ObjectSet<String> set = new ObjectSet<>();
|
||||
|
|
@ -87,7 +87,7 @@ public class ContentDatabase{
|
|||
write.put(entry.key, entry.value.iterator().toArray());
|
||||
}
|
||||
|
||||
Settings.putJson("content-database", write);
|
||||
Settings.putBinary("content-database", write);
|
||||
Settings.save();
|
||||
dirty = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package io.anuke.mindustry.game;
|
|||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntArray;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
|
|
@ -44,9 +45,10 @@ public class Saves{
|
|||
|
||||
public void load(){
|
||||
saves.clear();
|
||||
int[] slots = Settings.getJson("save-slots", int[].class);
|
||||
IntArray slots = Settings.getBinary("save-slots", IntArray.class, IntArray::new);
|
||||
|
||||
for(int index : slots){
|
||||
for(int i = 0; i < slots.size; i ++){
|
||||
int index = slots.get(i);
|
||||
if(SaveIO.isSaveValid(index)){
|
||||
SaveSlot slot = new SaveSlot(index);
|
||||
saves.add(slot);
|
||||
|
|
@ -138,11 +140,10 @@ public class Saves{
|
|||
}
|
||||
|
||||
private void saveSlots(){
|
||||
int[] result = new int[saves.size];
|
||||
for(int i = 0; i < result.length; i++){
|
||||
result[i] = saves.get(i).index;
|
||||
}
|
||||
Settings.putJson("save-slots", result);
|
||||
IntArray result = new IntArray(saves.size);
|
||||
for(int i = 0; i < saves.size; i++) result.add(saves.get(i).index);
|
||||
|
||||
Settings.putBinary("save-slots", result);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public class Maps implements Disposable{
|
|||
Settings.putString("map-data-" + name, new String(Base64Coder.encode(stream.toByteArray())));
|
||||
if(!customMapNames.contains(name, false)){
|
||||
customMapNames.add(name);
|
||||
Settings.putJson("custom-maps", customMapNames);
|
||||
Settings.putBinary("custom-maps", customMapNames);
|
||||
}
|
||||
Settings.save();
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ public class Maps implements Disposable{
|
|||
} else {
|
||||
customMapNames.removeValue(map.name, false);
|
||||
Settings.putString("map-data-" + map.name, "");
|
||||
Settings.putJson("custom-maps", customMapNames);
|
||||
Settings.putBinary("custom-maps", customMapNames);
|
||||
Settings.save();
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ public class Maps implements Disposable{
|
|||
}
|
||||
|
||||
}else{
|
||||
customMapNames = Settings.getJson("custom-maps", Array.class);
|
||||
customMapNames = Settings.getBinary("custom-maps", Array.class, () -> new Array<>());
|
||||
|
||||
for(String name : customMapNames){
|
||||
try{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package io.anuke.mindustry.maps;
|
|||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.annotations.Annotations.Serialize;
|
||||
import io.anuke.mindustry.game.Difficulty;
|
||||
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||
import io.anuke.mindustry.game.SpawnGroup;
|
||||
|
|
@ -12,6 +13,7 @@ import io.anuke.ucore.util.Bits;
|
|||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
|
||||
@Serialize
|
||||
public class Sector{
|
||||
/**Position on the map, can be positive or negative.*/
|
||||
public short x, y;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ public class Sectors{
|
|||
|
||||
private GridMap<Sector> grid = new GridMap<>();
|
||||
|
||||
public Sectors(){
|
||||
Settings.json().addClassTag("Sector", Sector.class);
|
||||
}
|
||||
|
||||
public void playSector(Sector sector){
|
||||
if(sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
sector.getSave().delete();
|
||||
|
|
@ -117,7 +113,7 @@ public class Sectors{
|
|||
}
|
||||
grid.clear();
|
||||
|
||||
Array<Sector> out = Settings.getJson("sectors", Array.class);
|
||||
Array<Sector> out = Settings.getBinary("sectors", Array.class, () -> new Array<>());
|
||||
|
||||
for(Sector sector : out){
|
||||
createTexture(sector);
|
||||
|
|
@ -141,7 +137,7 @@ public class Sectors{
|
|||
out.add(sector);
|
||||
}
|
||||
|
||||
Settings.putJson("sectors", out);
|
||||
Settings.putBinary("sectors", out);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package io.anuke.mindustry.net;
|
|||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.annotations.Annotations.Serialize;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
|
||||
import static io.anuke.mindustry.Vars.headless;
|
||||
|
|
@ -276,16 +277,17 @@ public class Administration{
|
|||
}
|
||||
|
||||
public void save(){
|
||||
Settings.putJson("player-info", playerInfo);
|
||||
Settings.putJson("banned-ips", bannedIPs);
|
||||
Settings.putBinary("player-info", playerInfo);
|
||||
Settings.putBinary("banned-ips", bannedIPs);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
private void load(){
|
||||
playerInfo = Settings.getJson("player-info", ObjectMap.class);
|
||||
bannedIPs = Settings.getJson("banned-ips", Array.class);
|
||||
playerInfo = Settings.getBinary("player-info", ObjectMap.class, () -> new ObjectMap<>());
|
||||
bannedIPs = Settings.getBinary("banned-ips", Array.class, () -> new Array<>());
|
||||
}
|
||||
|
||||
@Serialize
|
||||
public static class PlayerInfo{
|
||||
public String id;
|
||||
public String lastName = "<unknown>", lastIP = "<unknown>";
|
||||
|
|
@ -303,7 +305,7 @@ public class Administration{
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
private PlayerInfo(){
|
||||
public PlayerInfo(){
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.dialogs;
|
|||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.annotations.Annotations.Serialize;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.Platform;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
|
|
@ -326,22 +327,24 @@ public class JoinDialog extends FloatingDialog{
|
|||
}
|
||||
|
||||
private void loadServers(){
|
||||
servers = Settings.getJson("server-list", Array.class);
|
||||
servers = Settings.getBinary("server-list", Array.class, () -> new Array<>());
|
||||
}
|
||||
|
||||
private void saveServers(){
|
||||
Settings.putJson("server-list", servers);
|
||||
Settings.putBinary("server-list", servers);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
static class Server{
|
||||
String ip;
|
||||
int port;
|
||||
@Serialize
|
||||
public static class Server{
|
||||
public String ip;
|
||||
public int port;
|
||||
|
||||
transient Host host;
|
||||
transient Table content;
|
||||
|
||||
void setIP(String ip){
|
||||
|
||||
//parse ip:port, if unsuccessful, use default values
|
||||
if(ip.lastIndexOf(':') != -1 && ip.lastIndexOf(':') != ip.length()-1){
|
||||
try{
|
||||
|
|
@ -362,6 +365,6 @@ public class JoinDialog extends FloatingDialog{
|
|||
return ip + (port != Vars.port ? ":" + port : "");
|
||||
}
|
||||
|
||||
Server(){}
|
||||
public Server(){}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue