User Tools

Site Tools


zh_cn:tutorial:mixin_examples

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
zh_cn:tutorial:mixin_examples [2021/08/29 13:58] – 中文本地化 hendrix-shenzh_cn:tutorial:mixin_examples [2023/12/18 02:19] (current) – [捕获局部变量] solidblock
Line 1: Line 1:
 ====== Mixin 示例 ====== ====== Mixin 示例 ======
-收录了较为常见的 Mixin 示例.+收录了较为常见的 Mixin 示例。此页面旨在帮助开发者快速学习 Mixin 的使用,建议在开始之前先查看 [[zh_cn:tutorial:mixin_introduction|Mixin介绍]]。 
 + 
 +===== 注入到内部私有类的一个方法 ===== 
 +使用 targets 参数并添加 ''$'' 符号来指向内部类。 
 +<code java> 
 +@Mixin(targets = "net.minecraft.client.render.block.BlockModelRenderer$AmbientOcclusionCalculator"
 +public class AmbientOcclusionCalculatorMixin { 
 +    // 为所欲为 ^ v ^ 
 +
 +</code> 
 + 
 +===== 在 Mixin 类中获取目标类实例对象 ===== 
 +注意:应该避免像这样两次强转 ''this''。如果你是要使用来自目标来的方法或字段,使用 ''@Shadow''。如果方法或字段是来自目标类的父类,可以直接将你的这个 mixin 继承那个父类。 
 +Mixin: 
 +<code java> 
 +@Mixin(TargetClass.class) 
 +public class MyMixin extends EveryThingThatTargetClassExtends implements EverythingThatTargetClassImplements { 
 +  @Inject(method = "foo()V", at = @At("HEAD")) 
 +  private void injected(CallbackInfo ci) { 
 +    TargetClass thisObject = (TargetClass)(Object)this; 
 +  } 
 +
 +</code> 
 +===== 注入到静态初始化代码块的开头 ===== 
 +Mixin: 
 +<code java> 
 +@Inject(method = "<clinit>", at = @At("HEAD")) 
 +private void injected(CallbackInfo ci) { 
 +    doSomething3(); 
 +
 +</code> 
 + 
 +结果: 
 +<code diff> 
 +static { 
 ++   injected(new CallbackInfo(“<clinit>”, false)); 
 +    doSomething1(); 
 +    doSomething2(); 
 +
 +</code>
  
 ===== 注入在一个方法的开头 ===== ===== 注入在一个方法的开头 =====
Line 101: Line 140:
 +   injected(new CallbackInfo("foo", false)); +   injected(new CallbackInfo("foo", false));
     doSomething2();     doSomething2();
 +  }
 +</code>
 +
 +===== 使用偏移量注入 =====
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "INVOKE", target = "La/b/c/Something;doSomething()V", shift = At.Shift.BY, by = 2))
 +private void injected(CallbackInfo ci) {
 +  doSomething3();
 +}
 +</code>
 +
 +结果:
 +<code diff>
 +  public void foo() {
 +    doSomething1();
 +    Something something = new Something();
 +    something.doSomething();
 +    doSomething2();
 ++   injected(new CallbackInfo("foo", false));
   }   }
 </code> </code>
Line 184: Line 243:
 </code> </code>
  
 +===== 捕获局部变量 =====
 +==== 不用 MixinExtras 捕获局部变量 ====
 +
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
 +private void injected(CallbackInfo ci, TypeArg1 arg1) {
 +  //CAPTURE_FAILHARD: 如果计算局部变量与预期不符则抛出一个异常。
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +结果:
 +<code diff>
 +  public void foo() {
 +    TypeArg1 arg1 = getArg1();
 +    arg1.doSomething1();
 +    arg1.doSomething2();
 +    TypeArg2 arg2 = getArg2();
 +    arg2.doSomething3();
 ++   injected(new CallbackInfo("foo", false), arg1);
 +  }
 +</code>
 +
 +
 +==== 使用 MixinExtras 捕获局部变量 ====
 +:!: MixinExtras 需要 Fabric Loader 0.15 或者以上版本,否则你需要在 ''build.gradle'' 中手动指定。
 +
 +:!: 如果有多个同一类型的局部变量,你需要指定 ''ordinal'' 否则会抛出错误。
 +
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "TAIL"))
 +private void injected(CallbackInfo ci, @Local TypeArg2 arg2) {
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +结果:
 +<code diff>
 +  public void foo() {
 +    TypeArg1 arg1 = getArg1();
 +    arg1.doSomething1();
 +    arg1.doSomething2();
 +    TypeArg2 arg2 = getArg2();
 +    arg2.doSomething3();
 ++   injected(new CallbackInfo("foo", false), arg2);
 +  }
 +</code>
 +
 +==== 捕获多个同一类型的局部变量中的一个 ====
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "TAIL"))
 +private void injected(CallbackInfo ci, @Local(ordinal = 2) TypeArg arg) {
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +结果:
 +<code diff>
 +  public void foo() {
 +    TypeArg arg1 = getArg1();
 +    TypeArg arg2 = getArg2();
 +    TypeArg arg3 = getArg3();
 +    TypeArg arg4 = getArg4();
 +    doSomething();
 ++   injected(new CallbackInfo("foo", false), arg3);
 +  }
 +</code>
 ===== 修改返回值 ===== ===== 修改返回值 =====
 Mixin: Mixin:
Line 314: Line 443:
     Something something = new Something();     Something something = new Something();
 -   something.doSomething(3, 2.5D, true); -   something.doSomething(3, 2.5D, true);
-+   // 事实上, Args 子类运行时候生成, ++   // 事实上,自动生成的 Args 子类是在运行时被创建的, 
-+   // 但是我们省略了一些细节以便于理解。++   // 但是我们抹去了一些细节以便于理解。
 +   Args args = new Args(new Object[] { 3, 2.5D, true }); +   Args args = new Args(new Object[] { 3, 2.5D, true });
 +   injected(args); +   injected(args);
zh_cn/tutorial/mixin_examples.1630245483.txt.gz · Last modified: 2021/08/29 13:58 by hendrix-shen