Entity name mapping

This commit is contained in:
Anuken
2020-02-07 09:36:51 -05:00
parent eeae5149a1
commit 33e818a757
12 changed files with 453 additions and 387 deletions

View File

@ -71,6 +71,10 @@ public abstract class BaseProcessor extends AbstractProcessor{
return cons.newInstance(name); return cons.newInstance(name);
} }
public static TypeName tname(Class<?> c){
return ClassName.get(c).box();
}
public static TypeVariableName getTVN(TypeParameterElement element) { public static TypeVariableName getTVN(TypeParameterElement element) {
String name = element.getSimpleName().toString(); String name = element.getSimpleName().toString();
List<? extends TypeMirror> boundsMirrors = element.getBounds(); List<? extends TypeMirror> boundsMirrors = element.getBounds();
@ -113,6 +117,10 @@ public abstract class BaseProcessor extends AbstractProcessor{
} }
} }
public Array<Selement> elements(Class<? extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).map(Selement::new);
}
public Array<Stype> types(Class<? extends Annotation> type){ public Array<Stype> types(Class<? extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof TypeElement) return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof TypeElement)
.map(e -> new Stype((TypeElement)e)); .map(e -> new Stype((TypeElement)e));

View File

@ -30,7 +30,7 @@ public class EntityProcess extends BaseProcessor{
Array<Stype> baseComponents; Array<Stype> baseComponents;
ObjectMap<String, Stype> componentNames = new ObjectMap<>(); ObjectMap<String, Stype> componentNames = new ObjectMap<>();
ObjectMap<Stype, Array<Stype>> componentDependencies = new ObjectMap<>(); ObjectMap<Stype, Array<Stype>> componentDependencies = new ObjectMap<>();
ObjectMap<Stype, Array<Stype>> defComponents = new ObjectMap<>(); ObjectMap<Selement, Array<Stype>> defComponents = new ObjectMap<>();
ObjectMap<Svar, String> varInitializers = new ObjectMap<>(); ObjectMap<Svar, String> varInitializers = new ObjectMap<>();
ObjectSet<String> imports = new ObjectSet<>(); ObjectSet<String> imports = new ObjectSet<>();
@ -45,7 +45,7 @@ public class EntityProcess extends BaseProcessor{
if(round == 1){ if(round == 1){
baseComponents = types(BaseComponent.class); baseComponents = types(BaseComponent.class);
Array<Smethod> allGroups = methods(GroupDef.class); Array<Smethod> allGroups = methods(GroupDef.class);
Array<Stype> allDefs = types(EntityDef.class); Array<Selement> allDefs = elements(EntityDef.class);
Array<Stype> allComponents = types(Component.class); Array<Stype> allComponents = types(Component.class);
//store components //store components
@ -157,13 +157,15 @@ public class EntityProcess extends BaseProcessor{
} }
//look at each definition //look at each definition
for(Stype type : allDefs){ for(Selement<?> type : allDefs){
EntityDef ann = type.annotation(EntityDef.class); EntityDef ann = type.annotation(EntityDef.class);
boolean isFinal = ann.isFinal(); boolean isFinal = ann.isFinal();
if(!type.name().endsWith("Def")){ if(type.isType() && !type.name().endsWith("Def")){
err("All entity def names must end with 'Def'", type.e); err("All entity def names must end with 'Def'", type.e);
} }
String name = type.name().replace("Def", "Entity"); String name = type.isType() ?
type.name().replace("Def", "Entity") :
createName(type);
TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC); TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC);
if(isFinal) builder.addModifiers(Modifier.FINAL); if(isFinal) builder.addModifiers(Modifier.FINAL);
@ -287,7 +289,7 @@ public class EntityProcess extends BaseProcessor{
.returns(tname(packageName + "." + name)) .returns(tname(packageName + "." + name))
.addStatement(ann.pooled() ? "return Pools.obtain($L.class, " +name +"::new)" : "return new $L()", name).build()); .addStatement(ann.pooled() ? "return Pools.obtain($L.class, " +name +"::new)" : "return new $L()", name).build());
definitions.add(new EntityDefinition("mindustry.gen." + name, builder, type, components, groups)); definitions.add(new EntityDefinition(packageName + "." + name, builder, type, components, groups));
} }
//generate groups //generate groups
@ -357,17 +359,25 @@ public class EntityProcess extends BaseProcessor{
PropertiesUtils.store(map, idProps.writer(false), "Maps entity names to IDs. Autogenerated."); PropertiesUtils.store(map, idProps.writer(false), "Maps entity names to IDs. Autogenerated.");
//build mapping class for sync IDs //build mapping class for sync IDs
TypeSpec.Builder idBuilder = TypeSpec.classBuilder("ClassMapping").addModifiers(Modifier.PUBLIC) TypeSpec.Builder idBuilder = TypeSpec.classBuilder("EntityMapping").addModifiers(Modifier.PUBLIC)
.addField(FieldSpec.builder(TypeName.get(Prov[].class), "mapping", Modifier.PRIVATE, Modifier.STATIC).initializer("new Prov[256]").build()) .addField(FieldSpec.builder(TypeName.get(Prov[].class), "idMap", Modifier.PRIVATE, Modifier.STATIC).initializer("new Prov[256]").build())
.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(ObjectMap.class),
tname(String.class), tname(Prov.class)),
"nameMap", Modifier.PRIVATE, Modifier.STATIC).initializer("new ObjectMap<>()").build())
.addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(TypeName.get(Prov.class)).addParameter(int.class, "id").addStatement("return mapping[id]").build()); .returns(TypeName.get(Prov.class)).addParameter(int.class, "id").addStatement("return idMap[id]").build())
.addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(TypeName.get(Prov.class)).addParameter(String.class, "name").addStatement("return nameMap.get(name)").build());
CodeBlock.Builder idStore = CodeBlock.builder(); CodeBlock.Builder idStore = CodeBlock.builder();
//store the mappings //store the mappings
for(EntityDefinition def : definitions){ for(EntityDefinition def : definitions){
//store mapping //store mapping
idStore.addStatement("mapping[$L] = $L::new", def.classID, def.name); idStore.addStatement("idMap[$L] = $L::new", def.classID, def.name);
idStore.addStatement("nameMap.put($S, $L::new)", def.name.substring(packageName.length() + 1), def.name);
idStore.addStatement("nameMap.put($S, $L::new)", def.base.name(), def.name);
//return mapping //return mapping
def.builder.addMethod(MethodSpec.methodBuilder("classId").addAnnotation(Override.class) def.builder.addMethod(MethodSpec.methodBuilder("classId").addAnnotation(Override.class)
.returns(int.class).addModifiers(Modifier.PUBLIC).addStatement("return " + def.classID).build()); .returns(int.class).addModifiers(Modifier.PUBLIC).addStatement("return " + def.classID).build());
@ -489,7 +499,7 @@ public class EntityProcess extends BaseProcessor{
} }
/** @return all components that a entity def has */ /** @return all components that a entity def has */
Array<Stype> allComponents(Stype type){ Array<Stype> allComponents(Selement<?> type){
if(!defComponents.containsKey(type)){ if(!defComponents.containsKey(type)){
//get base defs //get base defs
Array<Stype> components = types(type.annotation(EntityDef.class), EntityDef::value); Array<Stype> components = types(type.annotation(EntityDef.class), EntityDef::value);
@ -542,6 +552,12 @@ public class EntityProcess extends BaseProcessor{
return componentNames.get(name); return componentNames.get(name);
} }
String createName(Selement<?> elem){
Array<Stype> comps = types(elem.annotation(EntityDef.class), EntityDef::value);
comps.sortComparing(Selement::name);
return comps.toString("", s -> s.name().replace("Comp", "")) + "Entity";
}
boolean isComponent(Stype type){ boolean isComponent(Stype type){
return type.annotation(Component.class) != null; return type.annotation(Component.class) != null;
} }
@ -560,7 +576,7 @@ public class EntityProcess extends BaseProcessor{
final ClassName baseType; final ClassName baseType;
final Array<Stype> components; final Array<Stype> components;
final boolean spatial, mapping; final boolean spatial, mapping;
final ObjectSet<Stype> manualInclusions = new ObjectSet<>(); final ObjectSet<Selement> manualInclusions = new ObjectSet<>();
public GroupDefinition(String name, ClassName bestType, Array<Stype> components, boolean spatial, boolean mapping){ public GroupDefinition(String name, ClassName bestType, Array<Stype> components, boolean spatial, boolean mapping){
this.baseType = bestType; this.baseType = bestType;
@ -580,11 +596,11 @@ public class EntityProcess extends BaseProcessor{
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 Selement base;
final String name; final String name;
int classID; int classID;
public EntityDefinition(String name, Builder builder, Stype base, Array<Stype> components, Array<GroupDefinition> groups){ public EntityDefinition(String name, Builder builder, Selement base, Array<Stype> components, Array<GroupDefinition> groups){
this.builder = builder; this.builder = builder;
this.name = name; this.name = name;
this.base = base; this.base = base;

View File

@ -15,6 +15,34 @@ public class Selement<T extends Element>{
this.e = e; this.e = e;
} }
public String fullName(){
return e.toString();
}
public Stype asType(){
return new Stype((TypeElement)e);
}
public Svar asVar(){
return new Svar((VariableElement)e);
}
public Smethod asMethod(){
return new Smethod((ExecutableElement)e);
}
public boolean isVar(){
return e instanceof VariableElement;
}
public boolean isType(){
return e instanceof TypeElement;
}
public boolean isMethod(){
return e instanceof ExecutableElement;
}
public Array<? extends AnnotationMirror> annotations(){ public Array<? extends AnnotationMirror> annotations(){
return Array.with(e.getAnnotationMirrors()); return Array.with(e.getAnnotationMirrors());
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 KiB

After

Width:  |  Height:  |  Size: 697 KiB

View File

@ -1,21 +1,24 @@
package mindustry.content; package mindustry.content;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
public class UnitTypes implements ContentList{ public class UnitTypes implements ContentList{
public static UnitDef public static UnitDef
draug, spirit, phantom, draug, spirit, phantom,
wraith, ghoul, revenant, lich, reaper, wraith, ghoul, revenant, lich, reaper,
dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator; crawler, titan, fortress, eruptor, chaosArray, eradicator;
//TODO can't get comp classes
public static UnitDef dagger;
public static UnitDef vanguard, alpha, delta, tau, omega, dart, javelin, trident, glaive; public static UnitDef vanguard, alpha, delta, tau, omega, dart, javelin, trident, glaive;
public static UnitDef starter; public static UnitDef starter;
@Override @Override
public void load(){ public void load(){
dagger = new UnitDef("dagger", GenericUnitEntity::create){{ dagger = new UnitDef("dagger"){{
speed = 0.2f; speed = 0.2f;
drag = 0.4f; drag = 0.4f;
hitsize = 8f; hitsize = 8f;

View File

@ -340,7 +340,7 @@ public class NetClient implements ApplicationListener{
//entity must not be added yet, so create it //entity must not be added yet, so create it
if(entity == null){ if(entity == null){
entity = (Syncc)ClassMapping.map(typeID).get(); entity = (Syncc)EntityMapping.map(typeID).get();
entity.id(id); entity.id(id);
if(!netClient.isEntityUsed(entity.id())){ if(!netClient.isEntityUsed(entity.id())){
add = true; add = true;

View File

@ -138,8 +138,8 @@ abstract class UnitComp implements Healthc, Velc, Statusc, Teamc, Itemsc, Hitbox
//ScorchDecal.create(getX(), getY()); //ScorchDecal.create(getX(), getY());
Fx.explosion.at(this); Fx.explosion.at(this);
Effects.shake(2f, 2f, this); Effects.shake(2f, 2f, this);
type.deathSound.at(this);
Sounds.bang.at(this);
Events.fire(new UnitDestroyEvent(this)); Events.fire(new UnitDestroyEvent(this));
//TODO implement suicide bomb trigger //TODO implement suicide bomb trigger

View File

@ -247,7 +247,7 @@ public abstract class SaveVersion extends SaveFileReader{
for(int j = 0; j < amount; j++){ for(int j = 0; j < amount; j++){
readChunk(stream, true, in -> { readChunk(stream, true, in -> {
byte typeid = in.readByte(); byte typeid = in.readByte();
Syncc sync = (Syncc)ClassMapping.map(typeid).get(); Syncc sync = (Syncc)EntityMapping.map(typeid).get();
sync.read(in); sync.read(in);
}); });
} }

View File

@ -53,13 +53,14 @@ public class UnitDef extends UnlockableContent{
public Array<Weapon> weapons = new Array<>(); public Array<Weapon> weapons = new Array<>();
public TextureRegion baseRegion, legRegion, region, cellRegion, occlusionRegion; public TextureRegion baseRegion, legRegion, region, cellRegion, occlusionRegion;
public UnitDef(String name, Prov<Unitc> constructor){
super(name);
this.constructor = constructor;
}
public UnitDef(String name){ public UnitDef(String name){
this(name, () -> Nulls.unit); super(name);
if(EntityMapping.map(name) != null){
constructor = EntityMapping.map(name);
}else{
constructor = () -> Nulls.unit;
}
} }
public UnitController createController(){ public UnitController createController(){

View File

@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=0e6ac9406fa34f2f5596ff1b151a3ebd07856aac archash=0046591e6664a02c2f6a632963240c991e9afc96

View File

@ -1,10 +1,10 @@
package mindustry.tools; package mindustry.tools;
import arc.struct.*;
import arc.files.*; import arc.files.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.noise.*; import arc.util.noise.*;
import mindustry.ctype.*; import mindustry.ctype.*;
@ -187,7 +187,6 @@ public class Generators{
ImagePacker.generate("unit-icons", () -> { ImagePacker.generate("unit-icons", () -> {
content.units().each(type -> !type.flying, type -> { content.units().each(type -> !type.flying, type -> {
type.load(); type.load();
type.weapons.each(Weapon::load);
Image image = ImagePacker.get(type.region); Image image = ImagePacker.get(type.region);
@ -196,14 +195,18 @@ public class Generators{
image.draw(type.legRegion, true, false); image.draw(type.legRegion, true, false);
image.draw(type.region); image.draw(type.region);
//TODO draw weapons with proper offsets for(Weapon weapon : type.weapons){
/* weapon.load();
for(boolean b : Mathf.booleans){
image.draw(type.weapon.region, for(int i : (weapon.mirror ? Mathf.signs : Mathf.one)){
(int)(Mathf.sign(b) * type.weapon.width / Draw.scl + image.width / 2 - type.weapon.region.getWidth() / 2), i *= Mathf.sign(weapon.flipped);
(int)(type.weaponOffsetY / Draw.scl + image.height / 2f - type.weapon.region.getHeight() / 2f),
b, false); image.draw(weapon.region,
}*/ (int)(i * weapon.x / Draw.scl + image.width / 2 - weapon.region.getWidth() / 2),
(int)(weapon.y / Draw.scl + image.height / 2f - weapon.region.getHeight() / 2f),
i > 0, false);
}
}
image.save("unit-" + type.name + "-full"); image.save("unit-" + type.name + "-full");
}); });