Class ID mapping

This commit is contained in:
Anuken
2020-02-04 13:57:42 -05:00
parent be50997f94
commit 012421afcb
21 changed files with 106 additions and 63 deletions
@@ -17,6 +17,12 @@ public class Annotations{
public @interface Component{ public @interface Component{
} }
/** Indicates that a method is implemented by the annotation processor. */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface InternalImpl{
}
/** Indicates priority of a method in an entity. Methods with higher priority are done last. */ /** Indicates priority of a method in an entity. Methods with higher priority are done last. */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@@ -1,5 +1,6 @@
package mindustry.annotations; package mindustry.annotations;
import arc.files.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
@@ -30,6 +31,7 @@ public abstract class BaseProcessor extends AbstractProcessor{
protected int round; protected int round;
protected int rounds = 1; protected int rounds = 1;
protected RoundEnvironment env; protected RoundEnvironment env;
protected Fi rootDirectory;
public static String getMethodName(Element element){ public static String getMethodName(Element element){
return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName(); return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName();
@@ -113,6 +115,17 @@ public abstract class BaseProcessor extends AbstractProcessor{
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
if(round++ >= rounds) return false; //only process 1 round if(round++ >= rounds) return false; //only process 1 round
if(rootDirectory == null){
try{
String path = Fi.get(filer.getResource(StandardLocation.CLASS_OUTPUT, "no", "no")
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
.parent().parent().parent().parent().parent().parent().parent().toString().replace("%20", " ");
rootDirectory = Fi.get(path);
}catch(IOException e){
throw new RuntimeException(e);
}
}
this.env = roundEnv; this.env = roundEnv;
try{ try{
process(roundEnv); process(roundEnv);
@@ -5,29 +5,22 @@ import arc.scene.style.*;
import arc.struct.*; import arc.struct.*;
import arc.util.serialization.*; import arc.util.serialization.*;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.annotations.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.*; import javax.lang.model.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.Diagnostic.*; import javax.tools.Diagnostic.*;
import javax.tools.*;
import java.util.*; import java.util.*;
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults") @SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
public class AssetsProcess extends BaseProcessor{ public class AssetsProcess extends BaseProcessor{
private String path;
@Override @Override
public void process(RoundEnvironment env) throws Exception{ public void process(RoundEnvironment env) throws Exception{
path = Fi.get(BaseProcessor.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no") processSounds("Sounds", rootDirectory + "/core/assets/sounds", "arc.audio.Sound");
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length())) processSounds("Musics", rootDirectory + "/core/assets/music", "arc.audio.Music");
.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(env.getElementsAnnotatedWith(StyleDefaults.class)); processUI(env.getElementsAnnotatedWith(StyleDefaults.class));
} }
@@ -38,8 +31,8 @@ public class AssetsProcess extends BaseProcessor{
MethodSpec.Builder load = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder load = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
MethodSpec.Builder loadStyles = MethodSpec.methodBuilder("loadStyles").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder loadStyles = MethodSpec.methodBuilder("loadStyles").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
MethodSpec.Builder icload = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder icload = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
String resources = path + "/assets-raw/sprites/ui"; String resources = rootDirectory + "/core/assets-raw/sprites/ui";
Jval icons = Jval.read(Fi.get(path + "/assets-raw/fontgen/config.json").readString()); Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString());
ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class), ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class),
"icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build()); "icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build());
@@ -1,8 +1,10 @@
package mindustry.annotations.impl; package mindustry.annotations.impl;
import arc.files.*;
import arc.func.*; import arc.func.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
import com.squareup.javapoet.TypeSpec.*; import com.squareup.javapoet.TypeSpec.*;
import com.sun.source.tree.*; import com.sun.source.tree.*;
@@ -21,7 +23,7 @@ import java.lang.annotation.*;
"mindustry.annotations.Annotations.BaseComponent" "mindustry.annotations.Annotations.BaseComponent"
}) })
public class EntityProcess extends BaseProcessor{ public class EntityProcess extends BaseProcessor{
Array<Definition> definitions = new Array<>(); Array<EntityDefinition> definitions = new Array<>();
Array<GroupDefinition> groupDefs = new Array<>(); Array<GroupDefinition> groupDefs = new Array<>();
Array<Stype> baseComponents; Array<Stype> baseComponents;
ObjectMap<String, Stype> componentNames = new ObjectMap<>(); ObjectMap<String, Stype> componentNames = new ObjectMap<>();
@@ -161,7 +163,7 @@ public class EntityProcess extends BaseProcessor{
//only write the block if it's a void method with several entries //only write the block if it's a void method with several entries
boolean writeBlock = first.ret().toString().equals("void") && entry.value.size > 1; boolean writeBlock = first.ret().toString().equals("void") && entry.value.size > 1;
if((entry.value.first().is(Modifier.ABSTRACT) || entry.value.first().is(Modifier.NATIVE)) && entry.value.size == 1){ if((entry.value.first().is(Modifier.ABSTRACT) || entry.value.first().is(Modifier.NATIVE)) && entry.value.size == 1 && !entry.value.first().has(InternalImpl.class)){
err(entry.value.first().up().getSimpleName() + "#" + entry.value.first() + " is an abstract method and must be implemented in some component", type); err(entry.value.first().up().getSimpleName() + "#" + entry.value.first() + " is an abstract method and must be implemented in some component", type);
} }
@@ -208,7 +210,7 @@ public class EntityProcess extends BaseProcessor{
builder.addMethod(mbuilder.build()); builder.addMethod(mbuilder.build());
} }
definitions.add(new Definition(builder, type, components, groups)); definitions.add(new EntityDefinition("mindustry.gen." + name, builder, type, components, groups));
} }
//generate groups //generate groups
@@ -216,6 +218,7 @@ public class EntityProcess extends BaseProcessor{
MethodSpec.Builder groupInit = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder groupInit = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
for(GroupDefinition group : groupDefs){ for(GroupDefinition group : groupDefs){
Stype ctype = group.components.first(); Stype ctype = group.components.first();
//class names for interface/group
ClassName itype = ClassName.bestGuess("mindustry.gen." + interfaceName(ctype)); ClassName itype = ClassName.bestGuess("mindustry.gen." + interfaceName(ctype));
ClassName groupc = ClassName.bestGuess("mindustry.entities.EntityGroup"); ClassName groupc = ClassName.bestGuess("mindustry.entities.EntityGroup");
@@ -226,16 +229,61 @@ public class EntityProcess extends BaseProcessor{
groupInit.addStatement("$L = new $T<>($L, $L)", group.name, groupc, group.def.spatial(), group.def.mapping()); groupInit.addStatement("$L = new $T<>($L, $L)", group.name, groupc, group.def.spatial(), group.def.mapping());
} }
//write the groups
groupsBuilder.addMethod(groupInit.build()); groupsBuilder.addMethod(groupInit.build());
write(groupsBuilder); write(groupsBuilder);
//load map of sync IDs
StringMap map = new StringMap();
Fi idProps = rootDirectory.child("annotations/src/main/resources/classids.properties");
if(!idProps.exists()) idProps.writeString("");
PropertiesUtils.load(map, idProps.reader());
//next ID to be used in generation
Integer max = map.values().toArray().map(Integer::parseInt).max(i -> i);
int maxID = max == null ? 0 : max + 1;
//assign IDs
definitions.sort(Structs.comparing(t -> t.base.toString()));
for(EntityDefinition def : definitions){
String name = def.base.fullName();
if(map.containsKey(name)){
def.classID = map.getInt(name);
}else{
def.classID = maxID++;
map.put(name, def.classID + "");
}
}
//write assigned IDs
PropertiesUtils.store(map, idProps.writer(false), "Maps entity names to IDs. Autogenerated.");
//build mapping class for sync IDs
TypeSpec.Builder idBuilder = TypeSpec.classBuilder("ClassMapping").addModifiers(Modifier.PUBLIC)
.addField(FieldSpec.builder(TypeName.get(Prov[].class), "mapping", Modifier.PRIVATE, Modifier.STATIC).initializer("new Prov[256]").build())
.addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(TypeName.get(Prov.class)).addParameter(int.class, "id").addStatement("return mapping[id]").build());
CodeBlock.Builder idStore = CodeBlock.builder();
//store the mappings
for(EntityDefinition def : definitions){
//store mapping
idStore.addStatement("mapping[$L] = $L::new", def.classID, def.name);
//return mapping
def.builder.addMethod(MethodSpec.methodBuilder("classId").addAnnotation(Override.class)
.returns(int.class).addModifiers(Modifier.PUBLIC).addStatement("return " + def.classID).build());
}
idBuilder.addStaticBlock(idStore.build());
write(idBuilder);
}else{ }else{
//round 2: generate actual classes and implement interfaces //round 2: generate actual classes and implement interfaces
Array<Stype> interfaces = types(EntityInterface.class); Array<Stype> interfaces = types(EntityInterface.class);
//implement each definition //implement each definition
for(Definition def : definitions){ for(EntityDefinition def : definitions){
//get interface for each component //get interface for each component
for(Stype comp : def.components){ for(Stype comp : def.components){
@@ -369,14 +417,17 @@ public class EntityProcess extends BaseProcessor{
} }
} }
class Definition{ class EntityDefinition{
final Array<GroupDefinition> groups; final Array<GroupDefinition> groups;
final Array<Stype> components; final Array<Stype> components;
final TypeSpec.Builder builder; final TypeSpec.Builder builder;
final Stype base; final Stype base;
final String name;
int classID;
public Definition(Builder builder, Stype base, Array<Stype> components, Array<GroupDefinition> groups){ public EntityDefinition(String name, Builder builder, Stype base, Array<Stype> components, Array<GroupDefinition> groups){
this.builder = builder; this.builder = builder;
this.name = name;
this.base = base; this.base = base;
this.groups = groups; this.groups = groups;
this.components = components; this.components = components;
@@ -16,6 +16,10 @@ public class Stype extends Selement<TypeElement>{
return new Stype((TypeElement)BaseProcessor.typeu.asElement(mirror)); return new Stype((TypeElement)BaseProcessor.typeu.asElement(mirror));
} }
public String fullName(){
return mirror().toString();
}
public Array<Stype> interfaces(){ public Array<Stype> interfaces(){
return Array.with(e.getInterfaces()).map(Stype::of); return Array.with(e.getInterfaces()).map(Stype::of);
} }
@@ -0,0 +1,7 @@
#Maps entity names to IDs. Autogenerated.
#Tue Feb 04 13:56:56 EST 2020
mindustry.entities.def.EntityDefs.DecalDef=1
mindustry.entities.def.EntityDefs.EffectDef=2
mindustry.entities.def.EntityDefs.TileDef=3
mindustry.entities.def.EntityDefs.BulletDef=0
-18
View File
@@ -1,18 +0,0 @@
package mindustry.content;
import mindustry.entities.effect.Fire;
import mindustry.entities.effect.Puddle;
import mindustry.entities.type.Player;
import mindustry.ctype.ContentList;
import mindustry.type.TypeID;
public class TypeIDs implements ContentList{
public static TypeID fire, puddle, player;
@Override
public void load(){
fire = new TypeID("fire", Fire::new);
puddle = new TypeID("puddle", Puddle::new);
player = new TypeID("player", Player::new);
}
}
@@ -42,7 +42,6 @@ public class ContentLoader{
new Weathers(), new Weathers(),
new Planets(), new Planets(),
new Zones(), new Zones(),
new TypeIDs(),
//these are not really content classes, but this makes initialization easier //these are not really content classes, but this makes initialization easier
new LegacyColorMapper(), new LegacyColorMapper(),
-1
View File
@@ -12,7 +12,6 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
-2
View File
@@ -3,8 +3,6 @@ package mindustry.entities;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import mindustry.entities.traits.*;
/** /**
* Class for predicting shoot angles based on velocities of targets. * Class for predicting shoot angles based on velocities of targets.
*/ */
@@ -55,7 +55,7 @@ public class EntityComps{
@Override @Override
public void controller(UnitController controller){ public void controller(UnitController controller){
this.controller = controller; this.controller = controller;
controller.set(this); controller.unit(this);
} }
@Override @Override
@@ -1291,7 +1291,7 @@ public class EntityComps{
} }
@Component @Component
abstract class ShielderComp implements Damagec{ abstract class ShielderComp implements Damagec, Teamc, Posc{
void absorb(){ void absorb(){
@@ -1536,7 +1536,7 @@ public class EntityComps{
@Component @Component
@BaseComponent @BaseComponent
class EntityComp{ abstract class EntityComp{
private boolean added; private boolean added;
int id; int id;
@@ -1563,5 +1563,8 @@ public class EntityComps{
<T> T as(Class<T> type){ <T> T as(Class<T> type){
return (T)this; return (T)this;
} }
@InternalImpl
abstract int classId();
} }
} }
@@ -9,7 +9,6 @@ import arc.util.pooling.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -17,7 +17,6 @@ import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.ctype.ContentType; import mindustry.ctype.ContentType;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.traits.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -5,7 +5,6 @@ import arc.math.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
@@ -3,10 +3,7 @@ package mindustry.entities.units;
import mindustry.gen.*; import mindustry.gen.*;
//TODO rename //TODO rename
public abstract class UnitController{ public interface UnitController{
protected Unitc unit; void unit(Unitc unit);
Unitc unit();
public void set(Unitc unit){
this.unit = unit;
}
} }
-2
View File
@@ -3,8 +3,6 @@ package mindustry.type;
import arc.func.*; import arc.func.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.ctype.ContentType; import mindustry.ctype.ContentType;
import mindustry.entities.traits.*;
public class TypeID extends MappableContent{ public class TypeID extends MappableContent{
public final Prov<? extends TypeTrait> constructor; public final Prov<? extends TypeTrait> constructor;
-1
View File
@@ -7,7 +7,6 @@ import arc.util.ArcAnnotate.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.bullet.*; import mindustry.entities.bullet.*;
import mindustry.entities.traits.*;
import mindustry.gen.*; import mindustry.gen.*;
public class Weapon{ public class Weapon{
-1
View File
@@ -4,7 +4,6 @@ import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.type.Weather.*; import mindustry.type.Weather.*;
@@ -9,7 +9,7 @@ import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.type.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
@@ -17,7 +17,7 @@ import mindustry.world.meta.*;
import java.io.*; import java.io.*;
import static mindustry.Vars.*; import static mindustry.Vars.tilesize;
public class ForceProjector extends Block{ public class ForceProjector extends Block{
public final int timerUse = timers++; public final int timerUse = timers++;
@@ -35,12 +35,12 @@ public class ForceProjector extends Block{
private static Tile paramTile; private static Tile paramTile;
private static ForceProjector paramBlock; private static ForceProjector paramBlock;
private static ForceEntity paramEntity; private static ForceEntity paramEntity;
private static Cons<AbsorbTrait> shieldConsumer = trait -> { private static Cons<Shielderc> shieldConsumer = trait -> {
if(trait.canBeAbsorbed() && trait.getTeam() != paramTile.getTeam() && Intersector.isInsideHexagon(trait.getX(), trait.getY(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){ if(trait.team() != paramTile.getTeam() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
trait.absorb(); trait.absorb();
Fx.absorb.at(trait); Fx.absorb.at(trait);
paramEntity.hit = 1f; paramEntity.hit = 1f;
paramEntity.buildup += trait.getShieldDamage() * paramEntity.warmup; paramEntity.buildup += trait.damage() * paramEntity.warmup;
} }
}; };
@@ -8,7 +8,6 @@ import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
@@ -9,7 +9,6 @@ import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*; import mindustry.entities.type.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;