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());
}