本篇教程由作者设定使用 CC BY-NC 协议。
注解
注解的类注解
注解类要求生命周期为运行时,即要有@Retention(RetentionPolicy.RUNTIME);
一般其使用范围为仅用于字段,即要有@Target(ElementType.FIELD);
为了确定目标字段的类型,Anno添加了一个新的注解@TargetType(Class<?>[] value)用于注解类,
例如:注册燃料应该限制类型为Item,那么注册燃料的@TargetType应该为@TargetType({Item.class})。如果要求字段可重复标注(例如@Lang),可以自行百度@Repeatable注解。
注解的属性
自由发挥,属性需要具体需要具体分析,请保证你会Java中创建新的注解。
示例(燃料注解)
@TargetType(Item.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Burnable {
int value();
}
解析器
解析器用于处理字段实例与注解,不同情况下具体实现差异较大。
我们这里以燃料注解为例子。
示例
public class FuelResolver implements Resolver<Burnable> {
@Override
public <T> void process(Target<T> target, Class<?> registration) {
if (target.object() instanceof Item item) {
int time = target.field().getAnnotation(Burnable.class).value();
FuelRegistry.INSTANCE.add(item, time);
}
}
@Override
public Class<Burnable> annoClass() {
return Burnable.class;
}
@Override
public String name() {
return "Fuel";
}
}
说明
解析器的实现也很简单,Target<T>为一个记录类,它包装了实例与字段。
process(arg...)为具体的处理流程,这里我们新增燃料的流程如下:
首先判断实例的类型,转换后直接用Fabric API的新增燃料注册。
annoClass()仅仅只需要返回注解的类。
在Minecraft-1.21.1及其后续版本,我们还需要实现name(),该名称不应与其他解析器相同。
注册
注解无需注册,解析器应该在模组主类的onInitialize()位于顶部使用AnnoResolvers.regiter(arg...)注册。
示例
public class Anno implements ModInitializer {
public static final String MOD_ID = "anno";
@Override
public void onInitialize() {
AnnoResolvers.register(id("fuel"), new FuelResolver());
AnnoResolvers.resolve(AnnoRegistration.class);
}
public static Identifier id(String path) {
return Identifier.of(MOD_ID, path);
}
}
注意事项
如果需要DataGeneration相关解析器可以参考Anno官方实现。
相同id的解析器,后注册的会覆盖先注册的。