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
Next revision
Previous revision
tutorial:mixin_tips [2025/09/27 22:49] – [Make abstract classes] clarify that it is not just obnoxious but also may lead to unintended behavior and errors to implement the target's interface's methods. gauntreclusetutorial:mixin_tips [2025/10/20 00:27] (current) – [Mixing into inner classes] Make example mixin class go from public class -> abstract class gauntrecluse
Line 16: Line 16:
 Should have the following Mixin class: Should have the following Mixin class:
 <yarncode java> <yarncode java>
-public abstract class SomeMixin extends class_1657 {+abstract class SomeMixin extends class_1657 {
 //... //...
 } }
Line 27: Line 27:
 ===== Make abstract classes ===== ===== Make abstract classes =====
  
-It's fair to say that you should never instantiate a mixin class, as Mixin classes exist to be merged. Along with this, it may both be obnoxious and lead to errors and unintended behavior to have to implement all of the methods from interfaces implemented in the target class.+It's fair to say that you should never instantiate a mixin class, as Mixin classes exist to be merged. Along with this, it may both be obnoxious and lead to errors and unintended behavior to have to implement all of the methods from your target class's parent interfaces.
  
 Declaring a mixin class abstract doesn't affect its function, and it becomes protected against accidental instantiation and removes the burden of having to implement many of the parent's methods that you don't need: Declaring a mixin class abstract doesn't affect its function, and it becomes protected against accidental instantiation and removes the burden of having to implement many of the parent's methods that you don't need:
  
 <code java> <code java>
-public abstract class SomeMixin implements TargetsInterfaces {+abstract class SomeMixin implements TargetsInterfaces {
 //Does not need to implement TargetsInterfaces' methods. //Does not need to implement TargetsInterfaces' methods.
 } }
Line 57: Line 57:
  
 :!: This doesn't work with private methods, since you can't have private abstract methods, and hence you need to implement a dummy body on those ones. :!: This doesn't work with private methods, since you can't have private abstract methods, and hence you need to implement a dummy body on those ones.
 +
 +If a method requires a return type, it is conventional to throw an ''AssertionError'' as the content is never executed. 
 +<code java>
 +@Shadow
 +protected Type hiddenMethod() {
 +    throw new AssertionError();
 +}
 +</code>
  
 ---- ----
Line 94: Line 102:
 <code java> <code java>
 @Mixin(targets = "some.random.package.Outer$Inner") @Mixin(targets = "some.random.package.Outer$Inner")
-public class MyMixin {+abstract class MyMixin {
     @Inject(method = "someRandomMethod()V", at = @At("HEAD"))     @Inject(method = "someRandomMethod()V", at = @At("HEAD"))
     private void injected(CallbackInfo ci) {     private void injected(CallbackInfo ci) {
Line 162: Line 170:
 <code java> <code java>
 @Mixin(value = StringReader.class, remap = false) @Mixin(value = StringReader.class, remap = false)
-public abstract class StringReaderMixin { ... }+abstract class StringReaderMixin { ... }
 </code> </code>
  
Line 169: Line 177:
 <code java> <code java>
 @Mixin(EntitySelectorReader.class) @Mixin(EntitySelectorReader.class)
-public abstract class EntitySelectorReaderMixin {+abstract class EntitySelectorReaderMixin {
   @Inject(method = "readTagCharacter", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/StringReader;skipWhitespace()V", remap = false)   @Inject(method = "readTagCharacter", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/StringReader;skipWhitespace()V", remap = false)
   // your injection method ...   // your injection method ...
 } }
 </code> </code>
 +
 +:!: Disabling remapping on an annotation causes the internal remapper to skip the annotation entirely, thus, if the ''@Inject'' does not need remapping but the ''@At'' does, remapping must be explicitly re-enabled in the ''@At'' via ''remap=true''. Mixin can tell the difference between an annotation attribute being set or whether it uses the default.
  
 :!: 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. :!: 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.1759013342.txt.gz · Last modified: 2025/09/27 22:49 by gauntrecluse