User Tools

Site Tools


tutorial:mixin_tips

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
tutorial:mixin_tips [2023/12/18 01:54] solidblocktutorial:mixin_tips [2023/12/18 02:06] (current) solidblock
Line 5: Line 5:
 This is a collection of different tips some might find useful. It's recommended to read the previous articles to understand the tips. This is a collection of different tips some might find useful. It's recommended to read the previous articles to understand the tips.
  
-===== Why make a class abstract===== +===== Make abstract classes =====
- +
-==== 1. Prevent instantiation ====+
  
 It's fair to say that you should never instantiate a mixin class, mainly because the class doesn't make sense to java if it isn't used in a mixin environment, and there are other ways to access methods declared in a mixin. It's fair to say that you should never instantiate a mixin class, mainly because the class doesn't make sense to java if it isn't used in a mixin environment, and there are other ways to access methods declared in a mixin.
Line 17: Line 15:
 </code> </code>
  
- +====Make abstract shadow methods =====
-==== 2. Make more elegant shadow methods ====+
  
 If you want to access a unaccessible method or field from your target class into your mixin class, you need to use ''@Shadow'' to make that method/field visible. If you want to access a unaccessible method or field from your target class into your mixin class, you need to use ''@Shadow'' to make that method/field visible.
Line 37: Line 34:
 Note: this doesn't work with private methods, since you can't have private abstract methods, and hence you need to use the normal one. Note: this doesn't work with private methods, since you can't have private abstract methods, and hence you need to use the normal one.
  
-==== 3. Access the ''this'' instance more easily ====+====Access the ''this'' instance more easily =====
  
-In mixin, if you want to access the "this" instance, you have to do a cast inside your mixin class:+In mixin, if you want to access the "''this''" instance, you have to cast it into ''Object'' first.
  
 <code java> <code java>
Line 100: Line 97:
 These are the same as the static inaccessible inner classes, the only difference is that since they don't have a name, they are declared by appearance order, for example: the anonymous inner class if declared in our previous example class first would be named Outer$1, a second one would be named Outer$2, a third one Outer$3 and so on (the declaration order is on source level). These are the same as the static inaccessible inner classes, the only difference is that since they don't have a name, they are declared by appearance order, for example: the anonymous inner class if declared in our previous example class first would be named Outer$1, a second one would be named Outer$2, a third one Outer$3 and so on (the declaration order is on source level).
  
-** UNDER CONSTRUCTION **+===== How to mixin to lambdas =====
  
 +Sometimes you want to mixin to lambdas. However, lambda do not have visible names. In this case, remember that **mixin is applied to bytecode instead of source**. Therefore, you can view the bytecode to view lambdas.
 +
 +For example, we want to inject the lambda in ''EntitySelectors''. The target code is seen as follows:
 +<code java>
 +public class EntitySelectorOptions {
 +  public static void register() {
 +    if (...) {
 +      putOption("name", reader -> {
 +        // Assume that you want to mixin to here
 +        int i = reader.getReader().getCursor();
 +        // ...
 +      }
 +      // ...
 +    }
 +  }
 +}
 +</code>
 +
 +If you directly injects to ''register'' method, that does not work. Please view the bytecode, and you will find:
 +<code java>
 +  private static synthetic method_9982(Lnet/minecraft/command/EntitySelectorReader;)V throws com/mojang/brigadier/exceptions/CommandSyntaxException 
 +   L0
 +   // ...
 +</code>
 +
 +Therefore, the method name of the lambda you want to mixin should be ''method_9982''.
 +
 +===== Mixin to those not remapped =====
 +
 +If you want to mixin to classes, methods or fields that are not remapped in yarn, such as ''com.mojang.brigadier.StringReader'', you may add ''remap = false'' to avoid potential errors. For example:
 +<code java>
 +@Mixin(value = StringReader.class, remap = false)
 +public abstract class StringReaderMixin { ... }
 +</code>
 +
 +Another example is:
 +
 +<code java>
 +@Mixin(EntitySelectorReader.class)
 +public abstract class EntitySelectorReaderMixin {
 +  @Inject(method = "readTagCharacter", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/StringReader;skipWhitespace()V", remap = false)
 +  // your injection method ...
 +}
 +</code>
tutorial/mixin_tips.txt · Last modified: 2023/12/18 02:06 by solidblock