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);
}
public static TypeName tname(Class<?> c){
return ClassName.get(c).box();
}
public static TypeVariableName getTVN(TypeParameterElement element) {
String name = element.getSimpleName().toString();
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){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof TypeElement)
.map(e -> new Stype((TypeElement)e));

View File

@ -30,7 +30,7 @@ public class EntityProcess extends BaseProcessor{
Array<Stype> baseComponents;
ObjectMap<String, Stype> componentNames = 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<>();
ObjectSet<String> imports = new ObjectSet<>();
@ -45,7 +45,7 @@ public class EntityProcess extends BaseProcessor{
if(round == 1){
baseComponents = types(BaseComponent.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);
//store components
@ -157,13 +157,15 @@ public class EntityProcess extends BaseProcessor{
}
//look at each definition
for(Stype type : allDefs){
for(Selement<?> type : allDefs){
EntityDef ann = type.annotation(EntityDef.class);
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);
}
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);
if(isFinal) builder.addModifiers(Modifier.FINAL);
@ -287,7 +289,7 @@ public class EntityProcess extends BaseProcessor{
.returns(tname(packageName + "." + name))
.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
@ -357,17 +359,25 @@ public class EntityProcess extends BaseProcessor{
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())
TypeSpec.Builder idBuilder = TypeSpec.classBuilder("EntityMapping").addModifiers(Modifier.PUBLIC)
.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)
.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();
//store the mappings
for(EntityDefinition def : definitions){
//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
def.builder.addMethod(MethodSpec.methodBuilder("classId").addAnnotation(Override.class)
.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 */
Array<Stype> allComponents(Stype type){
Array<Stype> allComponents(Selement<?> type){
if(!defComponents.containsKey(type)){
//get base defs
Array<Stype> components = types(type.annotation(EntityDef.class), EntityDef::value);
@ -542,6 +552,12 @@ public class EntityProcess extends BaseProcessor{
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){
return type.annotation(Component.class) != null;
}
@ -560,7 +576,7 @@ public class EntityProcess extends BaseProcessor{
final ClassName baseType;
final Array<Stype> components;
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){
this.baseType = bestType;
@ -580,11 +596,11 @@ public class EntityProcess extends BaseProcessor{
final Array<GroupDefinition> groups;
final Array<Stype> components;
final TypeSpec.Builder builder;
final Stype base;
final Selement base;
final String name;
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.name = name;
this.base = base;

View File

@ -15,6 +15,34 @@ public class Selement<T extends Element>{
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(){
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;
import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.type.*;
public class UnitTypes implements ContentList{
public static UnitDef
draug, spirit, phantom,
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 starter;
@Override
public void load(){
dagger = new UnitDef("dagger", GenericUnitEntity::create){{
dagger = new UnitDef("dagger"){{
speed = 0.2f;
drag = 0.4f;
hitsize = 8f;

View File

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

View File

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

View File

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

View File

@ -53,13 +53,14 @@ public class UnitDef extends UnlockableContent{
public Array<Weapon> weapons = new Array<>();
public TextureRegion baseRegion, legRegion, region, cellRegion, occlusionRegion;
public UnitDef(String name, Prov<Unitc> constructor){
super(name);
this.constructor = constructor;
}
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(){

View File

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

View File

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