tutorial:mixin_tips
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:mixin_tips [2025/09/22 21:27] – Change FIXME to indicate page has been both WIP and inactive for prolonged periods of time, putting it at risk of advice being outdated and/or incomplete gauntrecluse | tutorial:mixin_tips [2025/10/20 00:27] (current) – [Mixing into inner classes] Make example mixin class go from public class -> abstract class gauntrecluse | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | FIXME //This page is currently incomplete and has been inactive for prolonged periods of time, it may change at any time or contain incomplete or outdated advice!// | + | FIXME //This page is currently incomplete and still contains relatively very old edits, it may change at any time or contain incomplete or outdated advice!// |
| ====== Mixin Tips (WIP) ====== | ====== Mixin Tips (WIP) ====== | ||
| - | This is a collection of different tips some might find useful. It's recommended to read the previous articles | + | This is a collection of different tips some might find useful. It's recommended to read [[tutorial: |
| + | |||
| + | ===== Extend and implement the target class' | ||
| + | |||
| + | When working with Mixins, you may want to use a method from the target' | ||
| + | < | ||
| + | public class class_3222 extends class_1657 { | ||
| + | //... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Should have the following Mixin class: | ||
| + | < | ||
| + | abstract class SomeMixin extends class_1657 { | ||
| + | //... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | This page's other sections will showcase the different benefits of also making | ||
| + | |||
| + | ---- | ||
| ===== Make abstract classes ===== | ===== Make abstract classes ===== | ||
| - | It's fair to say that you should never instantiate a mixin class, | + | It's fair to say that you should never instantiate a mixin class, |
| - | Declaring a mixin class abstract doesn' | + | Declaring a mixin class abstract doesn' |
| <code java> | <code java> | ||
| - | MixinClass foo = new MixinClass(); | + | abstract class SomeMixin implements TargetsInterfaces { |
| + | //Does not need to implement TargetsInterfaces' | ||
| + | } | ||
| </ | </ | ||
| - | ===== Make abstract shadow methods | + | ---- |
| + | |||
| + | ==== Make abstract shadow methods ==== | ||
| - | If you want to access | + | If you want to access |
| - | You can perfectly | + | You can do this as you'd expect within |
| <code java> | <code java> | ||
| Line 26: | Line 50: | ||
| </ | </ | ||
| - | But it' | + | But it' |
| <code java> | <code java> | ||
| @Shadow | @Shadow | ||
| Line 32: | Line 56: | ||
| </ | </ | ||
| - | Note: this doesn' | + | :!: This doesn' |
| - | ===== Access the '' | + | If a method requires a return type, it is conventional to throw an '' |
| + | <code java> | ||
| + | @Shadow | ||
| + | protected Type hiddenMethod() { | ||
| + | throw new AssertionError(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ==== Access the '' | ||
| - | In mixin, if you want to access the "'' | + | In a Mixin class, if you want to access the '' |
| <code java> | <code java> | ||
| Line 42: | Line 76: | ||
| </ | </ | ||
| - | But that only works if your mixin class extends/implements everything that your target class does, which can be a pain because | + | But this can only work if your Mixin class extends |
| - | Luckily, this can all be avoided by using an abstract class, in which case you don't have to implement methods and all problems are avoided. | + | ===== How to mix into inner classes ===== |
| - | ===== How to mixin inner classes | + | ==== Non-static inaccessible |
| - | ==== 1. Normal | + | Since you cannot directly access (and hence mention) these classes from outside, you need to use the " |
| - | Since this you can't directly access (and hence mention) these classes from outside, you need to use the " | + | For an inner class, you do this by using the complete name of the outer class, then a '' |
| - | + | ||
| - | You do this by using the complete name of the outer class, then a '' | + | |
| Class: | Class: | ||
| Line 70: | Line 102: | ||
| <code java> | <code java> | ||
| @Mixin(targets = " | @Mixin(targets = " | ||
| - | public | + | abstract |
| @Inject(method = " | @Inject(method = " | ||
| private void injected(CallbackInfo ci) { | private void injected(CallbackInfo ci) { | ||
| Line 88: | Line 120: | ||
| - | ==== 2. Static inaccessible inner classes ==== | + | |
| + | ==== Static inaccessible inner classes ==== | ||
| These are the same as above, the only difference is that the constructor doesn' | These are the same as above, the only difference is that the constructor doesn' | ||
| - | ==== 3. Anonymous inner classes ==== | + | ==== Anonymous inner classes ==== |
| - | 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 | + | 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. It is best to check the Bytecode to be certain of the order of the Anonymous classes if any issues are encountered. |
| - | ===== 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 | + | ===== Mixing into lambdas ===== |
| + | |||
| + | Sometimes you want to mix into lambdas. However, lambda do not have visible names. In this case, remember that **Mixin is applied to bytecode | ||
| For example, we want to inject the lambda in '' | For example, we want to inject the lambda in '' | ||
| Line 117: | Line 152: | ||
| </ | </ | ||
| - | If you directly injects to '' | + | If you directly injects to '' |
| <code java> | <code java> | ||
| private static synthetic method_9982(Lnet/ | private static synthetic method_9982(Lnet/ | ||
| Line 124: | Line 159: | ||
| </ | </ | ||
| - | Therefore, the method name of the lambda you want to mixin should be '' | + | Therefore, the method name of the lambda you want to mixin should be '' |
| - | ===== Mixin to those not remapped ===== | + | If you are using the MCDev plugin, its autocomplete for target methods will also include lambdas, and the autocomplete widget will also show parameters for each lambda, which may be leveraged |
| - | If you want to mixin to classes, methods or fields that are not remapped in yarn, such as '' | + | ---- |
| + | |||
| + | ===== Mixing into those not remapped ===== | ||
| + | |||
| + | If you want to mix into classes, methods or fields that are not remapped in yarn, you may try to add '' | ||
| <code java> | <code java> | ||
| @Mixin(value = StringReader.class, | @Mixin(value = StringReader.class, | ||
| - | public | + | abstract class StringReaderMixin { ... } |
| </ | </ | ||
| Line 138: | Line 177: | ||
| <code java> | <code java> | ||
| @Mixin(EntitySelectorReader.class) | @Mixin(EntitySelectorReader.class) | ||
| - | public | + | abstract class EntitySelectorReaderMixin { |
| @Inject(method = " | @Inject(method = " | ||
| // your injection method ... | // your injection method ... | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | :!: Disabling remapping on an annotation causes the internal remapper to skip the annotation entirely, thus, if the '' | ||
| + | |||
| + | :!: Changing the remap setting may not fix an issue that would apparently seem to be remapping related, however, so it is best to seek direct support for your specific case. | ||
tutorial/mixin_tips.1758576438.txt.gz · Last modified: 2025/09/22 21:27 by gauntrecluse