Skip to content

Commit 8c9cc62

Browse files
authored
Merge uujuju1 RegionsProcessor-pr
2 parents e66528b + 7ce33b1 commit 8c9cc62

4 files changed

Lines changed: 164 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
template.annotations.processors.impl.AssetsProcessor
22
template.annotations.processors.impl.LoadProcessor
33
template.annotations.processors.impl.StructProcessor
4+
template.annotations.processors.impl.RegionsProcessor
45
template.annotations.processors.entity.EntityProcessor
56
template.annotations.processors.entity.MergeProcessor
67
template.annotations.processors.entity.DupeProcessor

annotations/src/template/annotations/Annotations.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package template.annotations;
22

33
import arc.func.*;
4+
import arc.graphics.g2d.*;
45
import arc.struct.*;
56
import com.squareup.javapoet.*;
67
import com.sun.tools.javac.code.*;
@@ -467,6 +468,46 @@ enum Method{
467468
int outlineRadius() default 4;
468469
}
469470

471+
/**
472+
* Fields annotated with this will be put on the ContentRegionRegistry, separated by enclosing class.
473+
* Names are parsed based on the following:
474+
* <ul>
475+
* <p> @ -> content name(modname included)
476+
* <p> @modname -> mod name
477+
* <p> @size -> block size
478+
* <p> #0$, #1$, #2$ -> index number, for arrays
479+
* <ul>
480+
* <p> # -> INDEX, Regular prefix for array variable. Number suffix starts at 0 for each dimension of array.
481+
* <P> The following characters up to an $ are appended right after INDEX without being separated by a string
482+
* <p> $ Is required so that the annotation processor knows when the array variable ends.
483+
* <p> Examples: #$ -> INDEX, #0$ -> INDEX0, #1$ -> INDEX1, #2$ -> INDEX2
484+
* </ul>
485+
* </ul>
486+
* <p> Will throw an {@link IllegalArgumentException} if this annotation is used outside a {@link TextureRegion TextureRegion} field whose enclosing class is
487+
* an instance of {@link mindustry.ctype.MappableContent MappableContent}
488+
*/
489+
@Target(ElementType.FIELD)
490+
@Retention(RetentionPolicy.SOURCE)
491+
public @interface Load {
492+
/**
493+
* Name used by the region
494+
*/
495+
String value();
496+
/**
497+
* Array lengths. One value for each dimension
498+
*/
499+
int[] lengths() default {};
500+
/**
501+
* Name used by the region if {@link #value()} returns error
502+
*/
503+
String fallBack() default "error";
504+
}
505+
/**
506+
* Ensures that the ContentRegionRegistry is generated.
507+
*/
508+
@Retention(RetentionPolicy.SOURCE)
509+
public @interface EnsureLoad{}
510+
470511
//anuke's implementation of annotation proxy maker, to replace the broken one from oracle
471512
//thanks, anuke
472513
//damn you, oracle
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package template.annotations.processors.impl;
2+
3+
import arc.*;
4+
import arc.graphics.g2d.*;
5+
import arc.struct.*;
6+
import arc.util.*;
7+
import com.squareup.javapoet.*;
8+
import mindustry.ctype.*;
9+
import template.annotations.Annotations.*;
10+
import template.annotations.processors.*;
11+
12+
import javax.annotation.processing.*;
13+
import javax.lang.model.element.*;
14+
import javax.lang.model.type.*;
15+
import java.util.*;
16+
17+
/**
18+
* Whenever a {@link arc.graphics.g2d.TextureRegion TextureRegion} is annotated with {@link Load @Load},
19+
* it'll generate a finder method inside the ContentRegionRegistry, which must be called for every
20+
* content in {@link mindustry.game.EventType.ContentInitEvent ContentInitEvent}
21+
*/
22+
public class RegionsProcessor extends BaseProcessor {
23+
public ObjectMap<Element, Seq<Element>> annotated = new ObjectMap<>();
24+
25+
{
26+
rounds = 1;
27+
}
28+
29+
@Override
30+
public Set<String> getSupportedAnnotationTypes() {
31+
Set<String> types = new HashSet<>();
32+
String prefix = processingEnv.getOptions().get("modName") + ".annotations.Annotations.";
33+
types.add(prefix + "Load");
34+
types.add(prefix + "EnsureLoad");
35+
return types;
36+
}
37+
38+
@Override
39+
public void process(RoundEnvironment roundEnv) throws Exception {
40+
if (round == 1) {
41+
TypeSpec.Builder regionsClass = TypeSpec.classBuilder(classPrefix + "ContentRegionRegistry")
42+
.addModifiers(Modifier.PUBLIC)
43+
.addJavadoc("Class generated for loading regions annotated with {@link template.annotations.Annotations.Load load}");
44+
45+
MethodSpec.Builder loadMethod = MethodSpec.methodBuilder("load")
46+
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
47+
.addParameter(tName(MappableContent.class), "content");
48+
49+
for (Element element : roundEnv.getElementsAnnotatedWith(Load.class)) {
50+
TypeMirror type = element.asType();
51+
while (type.getKind() == TypeKind.ARRAY) {
52+
type = ((ArrayType) type).getComponentType();
53+
}
54+
if (!types.isSameType(type, toType(TextureRegion.class).asType())) {
55+
throw new IllegalAccessException("Only TextureRegions should be annotated with @Load");
56+
}
57+
58+
annotated.get(element.getEnclosingElement(), Seq::new).add(element);
59+
}
60+
61+
for (Element base : annotated.keys().toSeq()) {
62+
if (!types.isSameType(base.asType(), toType(MappableContent.class).asType())) {
63+
throw new IllegalAccessException("@Load annotated TextureRegions must have a MappableContent enclosing class");
64+
}
65+
66+
loadMethod.beginControlFlow("if (content instanceof $T)", cName(base));
67+
68+
for (Element field : annotated.get(base)) {
69+
Load annotation = field.getAnnotation(Load.class);
70+
71+
StringBuilder depth = new StringBuilder();
72+
for (int i = 0; i < annotation.lengths().length; i++) {
73+
loadMethod.beginControlFlow(
74+
"for (int INDEX$L = 0; INDEX$L < $L; INDEX$L++)",
75+
i, i, annotation.lengths()[i], i
76+
);
77+
78+
depth.append("[INDEX").append(i).append("]");
79+
}
80+
81+
loadMethod.addStatement(
82+
"(($T) content).$L$L = $T.atlas.find($L, $L)",
83+
cName(base),
84+
field.getSimpleName(),
85+
depth.toString(),
86+
cName(Core.class),
87+
parse(annotation.value()),
88+
parse(annotation.fallBack())
89+
);
90+
91+
for (int i = 0; i < annotation.lengths().length; i++) {
92+
loadMethod.endControlFlow();
93+
}
94+
}
95+
96+
loadMethod.endControlFlow();
97+
}
98+
99+
regionsClass.addMethod(loadMethod.build());
100+
101+
write(regionsClass.build());
102+
}
103+
}
104+
105+
public String parse(String other) {
106+
other = '"' + other + '"';
107+
return other
108+
.replace("@modname", modName)
109+
.replace("@size", "\" + ((mindustry.world.Block) content).size + \"")
110+
.replace("@", "\" + content.name + \"")
111+
.replace("#", "\" + INDEX")
112+
.replace("$", " + \"");
113+
}
114+
}

main/src/template/Template.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import arc.*;
44
import arc.util.*;
55

6+
import mindustry.*;
67
import mindustry.ctype.*;
78
import mindustry.game.EventType.*;
89
import mindustry.mod.*;
@@ -17,7 +18,8 @@
1718
* The mod's main mod class. Contains static references to other modules.
1819
* @author Avant Team
1920
*/
20-
@LoadRegs("error") // Need this temporarily, so the class gets generated.
21+
@LoadRegs("error")// Need this temporarily, so the class gets generated.
22+
@EnsureLoad
2123
public class Template extends Mod{
2224
public static boolean tools = false;
2325

@@ -53,6 +55,11 @@ public Template(boolean tools){
5355
Events.on(ContentInitEvent.class, e -> {
5456
if(!headless){
5557
Regions.load();
58+
Vars.content.each(content -> {
59+
if (isTemplate(content) && content instanceof MappableContent mContent) {
60+
TemplateContentRegionRegistry.load(mContent);
61+
}
62+
});
5663
}
5764
});
5865
}

0 commit comments

Comments
 (0)