User Tools

Site Tools


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
tutorial:mixin_examples [2021/12/29 16:19] – add private inner class example bananatutorial:mixin_examples [2024/01/13 15:02] (current) arkosammy12
Line 5: Line 5:
  
 ===== Mixing into a private inner class ===== ===== Mixing into a private inner class =====
 +Use the targets parameter and a ''$'' sign to get the inner class.
 <code java> <code java>
 @Mixin(targets = "net.minecraft.client.render.block.BlockModelRenderer$AmbientOcclusionCalculator") @Mixin(targets = "net.minecraft.client.render.block.BlockModelRenderer$AmbientOcclusionCalculator")
-public class Calculator {+public class AmbientOcclusionCalculatorMixin {
     // do your stuff here     // do your stuff here
 } }
 </code> </code>
  
-===== Access `thisinstance of the class your mixin is targeting =====+===== Access the this instance of the class your mixin is targeting ===== 
 +Note: Double casting ''this'' should be avoided when possible. If you intend to use a method or field from the target class, use ''@Shadow''. If the method or field is from a parent of the target class, have your mixin extend the direct parent of the target class. 
 Mixin: Mixin:
 <code java> <code java>
-@Mixin(ClassMyMixinIsTargeting.class) +@Mixin(TargetClass.class) 
-public class MyMixin {+public class MyMixin extends EveryThingThatTargetClassExtends implements EverythingThatTargetClassImplements {
   @Inject(method = "foo()V", at = @At("HEAD"))   @Inject(method = "foo()V", at = @At("HEAD"))
   private void injected(CallbackInfo ci) {   private void injected(CallbackInfo ci) {
-    ((ClassMyMixinIsTargeting)(Object)this).functionOfTheTargetClass();+    TargetClass thisObject = (TargetClass)(Object)this;
   }   }
 +}
 +</code>
 +
 +===== Injecting into the head of a static block =====
 +Mixin:
 +<code java>
 +@Inject(method = "<clinit>", at = @At("HEAD"))
 +private void injected(CallbackInfo ci) {
 +    doSomething3();
 +}
 +</code>
 +
 +Result:
 +<code diff>
 +static {
 ++   injected(new CallbackInfo(“<clinit>”, false));
 +    doSomething1();
 +    doSomething2();
 } }
 </code> </code>
Line 123: Line 144:
 +   injected(new CallbackInfo("foo", false)); +   injected(new CallbackInfo("foo", false));
     doSomething2();     doSomething2();
 +  }
 +</code>
 +
 +===== Injecting into the point with shift amount =====
 +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>
 +
 +Result:
 +<code diff>
 +  public void foo() {
 +    doSomething1();
 +    Something something = new Something();
 +    something.doSomething();
 +    doSomething2();
 ++   injected(new CallbackInfo("foo", false));
   }   }
 </code> </code>
Line 206: Line 247:
 </code> </code>
  
 +===== Capturing local values =====
 +==== Capture locals without 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: If the calculated locals are different from the expected values, throws an error.
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +Result:
 +<code diff>
 +  public void foo() {
 +    TypeArg1 arg1 = getArg1();
 +    arg1.doSomething1();
 +    arg1.doSomething2();
 +    TypeArg2 arg2 = getArg2();
 +    arg2.doSomething3();
 ++   injected(new CallbackInfo("foo", false), arg1);
 +  }
 +</code>
 +
 +==== Capture locals with MixinExtras ====
 +:!: See the oficial MixinExtra's [[https://github.com/LlamaLad7/MixinExtras/wiki/Local|Wiki]].
 +
 +:!: MixinExtras required Fabric Loader 0.15 or above, or you have to manually specify it in ''build.gradle''.
 +
 +:!: If there are multiple locals with that type, you have to specify ''ordinal'' or it will throw an error.
 +
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "TAIL"))
 +private void injected(CallbackInfo ci, @Local TypeArg2 arg2) {
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +Result:
 +<code diff>
 +  public void foo() {
 +    TypeArg1 arg1 = getArg1();
 +    arg1.doSomething1();
 +    arg1.doSomething2();
 +    TypeArg2 arg2 = getArg2();
 +    arg2.doSomething3();
 ++   injected(new CallbackInfo("foo", false), arg2);
 +  }
 +</code>
 +
 +==== Capturing one of multiple locals of a type ====
 +Mixin:
 +<code java>
 +@Inject(method = "foo()V", at = @At(value = "TAIL"))
 +private void injected(CallbackInfo ci, @Local(ordinal = 2) TypeArg arg) {
 +  arg1.doSomething4();
 +}
 +</code>
 +
 +Result:
 +<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>
 +
 +===== Modifying locals =====
 +This requires MixinExtras.
 +
 +Mixin:
 +<code java>
 +  @Inject(method = "foo()V", at = @At(value = "INVOKE", target = "doSomething()V", shift = At.Shift.AFTER))
 +  private static void injected(CallbackInfo ci, @Local LocalRef<String> localRef) {
 +    localRef.set(localRef.get() + " - modified")
 +  }
 +</code>
 +
 +Result:
 +<code diff>
 +  public void foo() {
 +    String s = "example string";
 +    doSomething();
 ++   s = s + " - modified";
 +    doSomething2(s);
 +  }
 +</code>
 ===== Modifying a return value ===== ===== Modifying a return value =====
 Mixin: Mixin:
tutorial/mixin_examples.1640794746.txt.gz · Last modified: 2021/12/29 16:19 by banana