This is an old revision of the document!
Mixin注入
介绍
注入(Injects)允许你在已存在的模组中的特定位置放置自定义的代码。关于工作实例可参考本页底部的实例段落。注入的标准如下:
@Inject(method = "", at = @At("INJECTION POINT REFERENCE")) private void injectMethod(METHOD ARGS, CallbackInfo info) { }
注入点参考定义了注入目标方法的方法主体的哪个代码。下表描述了几个选项:
| 名称 | 描述 |
|---|---|
| HEAD | 方法顶部 |
| RETURN | 返回语句之前 |
| INVOKE | 在方法调用 |
| TAIL | 最终的返回语句前 |
注入点引用语句或成员的情况下,目标值设置在@At中。目标值使用JVM字节码描述符指定。
Oracle定义了如下域描述符:
| 描述符 | 原名 | 描述 |
|---|---|---|
| B | byte | 带符号的字节 |
| C | char | Basic Multilingual Plane中的Unicode字符代码点,使用UTF-16编码 |
| D | double | 双精度浮点值 |
| F | float | 单精度浮点值 |
| I | int | 正数 |
| J | long | 长整数 |
| L类名称; | reference | 类名称的实例 |
| S | short | 带符号的短整型 |
| Z | boolean | true或 false |
| [ | reference | 单数组维度 |
方法描述符包括方法名称,接着一系列包含输入类型的括号,以及输出类型。Java中定义的像Object m(int i, double[] d, Thread t)这样的方法描述符会有m(I[DLjava/lang/Thread;)Ljava/lang/Object;这样的方法描述符。
@Inject方法总是返回void类。方法名称不重要,最好用这次注入所做的事情来命名。方法头中,最先是目标方法的变量,随后是CallbackInfo对象。如果目标方法有一个返回类型(T),则使用CallbackInfoReturnable<T>而不是CallbackInfo。
从注入中返回和取消
如需在方法中提前取消或者返回,使用CallbackInfo#cancel或者CallbackInfoReturnable<T>#setReturnValue(T)。注意cancel不需要在selReturnValue之后调用。在这两个实例中,cancellable需要在注入注解中设为true:
@Inject(method = "...", at = @At("..."), cancellable = true)
向构造器中注入
如需向构造器中注入,方法目标使用<init>()V,其中()包含构造器变量描述符。向构造器中注入时,@At必须是TAIL或者RETURN,其他格式的注入均不支持。注意有一些类有名为init的方法,与<init>不同,不要弄混!
如需向静态构造器中注入,方法名称使用<clinit>。
实例
以下示例会把一个print语句注入到TitleScreen#init的顶部(注意:方法init是正常的方法,不是构造器)。
@Mixin(TitleScreen.class) public class ExampleMixin { @Inject(at = @At("HEAD"), method = "init()V") private void init(CallbackInfo info) { System.out.println("这一行是示例模组mixin输出的!"); } }
关于此实例的更多信息,可以在Fabric Example Mod repo中查看其用途。