tutorial:mixin_injects
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:mixin_injects [2022/08/04 21:37] – clomclem | tutorial:mixin_injects [2025/12/15 16:52] (current) – Added an extra bracket to show that it has to be inside @At more clearly mcgambingpro | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== | + | FIXME //This page is due rewrites because of inaccuracies. This page may change very suddenly and should be taken with a grain of salt.// |
| + | |||
| + | ====== | ||
| ===== Introduction ===== | ===== Introduction ===== | ||
| - | Injects allows you to place custom code at a specified | + | In the context of Mixins, when talking about injects, it is typically in reference |
| + | |||
| + | '' | ||
| + | |||
| + | |||
| + | ===== Effects & Use-Cases ===== | ||
| + | '' | ||
| + | |||
| + | This makes '' | ||
| + | * Listening to a specific method' | ||
| + | * Note that depending on the specific operation, some injectors able to get more context about individual operations may be more suitable. | ||
| + | * Adding a consistent operation at a part of a target method, without the intent of replacing any of the existing | ||
| + | * Populating fields added by a Mixin class, via an injection at the tail of the target class' | ||
| + | * Adding new operations at the head or tail of a method | ||
| + | |||
| + | |||
| + | ==== Limitations and Alternatives ==== | ||
| + | |||
| + | === Cancelling, Modifying or Diverting individual operations === | ||
| + | It is important to not use '' | ||
| + | |||
| + | === Context-Sensitive Injections === | ||
| + | FIXME //This section should use a more concrete example.// | ||
| + | |||
| + | '' | ||
| + | For example, | ||
| + | <code java> | ||
| + | public void calculateSlap(int quantity, Person haykam) { | ||
| + | /*...*/ | ||
| + | float force = complexCalculation(quantity); | ||
| + | haykam.slap(quantity, | ||
| + | |||
| + | /*...*/ | ||
| + | } | ||
| + | </ | ||
| + | if we wished to inject right after the '' | ||
| + | For the sake of showing how to appropriately add our new operations after the original method call outside of void returns, we'll say '' | ||
| + | <code java> | ||
| + | @WrapOperation(method = " | ||
| + | private boolean onHaykamSlapped(Person instance, int quantity, float forceOverResistance, | ||
| + | boolean originalValue = original.call(instance, | ||
| + | newOperations(forceOverResistance, | ||
| + | return originalValue; | ||
| + | } | ||
| + | </ | ||
| + | This allows us to get the returned value of the '' | ||
| + | |||
| + | :!: Note that '' | ||
| + | In summary of this subsection, '' | ||
| + | ===== Structure ===== | ||
| + | A barebones structure of '' | ||
| <code java> | <code java> | ||
| - | @Inject(method = "METHODNAME", at = @At(" | + | @Inject(method = "TARGET METHOD NAME OR SIGNATURE", at = @At(value = " |
| - | private void injectMethod(METHOD | + | private void injectedHandlerMethod(< |
| } | } | ||
| </ | </ | ||
| - | The [[https://github.com/ | + | Note that the '' |
| + | |||
| + | Most of the attributes of '' | ||
| + | |||
| + | ==== Target method ==== | ||
| + | The '' | ||
| + | |||
| + | It should be noted that for both target methods and injection point targets, the [[https://mcdev.io|MCDev]] IntelliJ plugin provides autocompletion to get around | ||
| + | |||
| + | === Targeting Constructors === | ||
| + | Constructors include the " | ||
| + | |||
| + | The static constructor | ||
| + | |||
| + | Non-static constructors are targeted by inputting ''"< | ||
| + | |||
| + | :!: Fabric' | ||
| + | |||
| + | |||
| + | ==== Injection Point ==== | ||
| + | The injection point defines what instructions to inject at in the target method. The following table describes a few of the options: | ||
| ^ Name ^ Description ^ | ^ Name ^ Description ^ | ||
| | HEAD | Top of the method | | | HEAD | Top of the method | | ||
| - | | RETURN | Before every return | + | | RETURN | Before every return |
| | INVOKE | At a method call | | | INVOKE | At a method call | | ||
| - | | TAIL | Before the final return | + | | TAIL | Before the final return |
| - | In the case of injection points that reference | + | See the [[https:// |
| + | |||
| + | ==== Injection Point Target ==== | ||
| + | In the case of injection points that target calls, | ||
| Oracle defines the following [[https:// | Oracle defines the following [[https:// | ||
| Line 28: | Line 103: | ||
| | D | double | double-precision floating-point value | | | D | double | double-precision floating-point value | | ||
| | F | float | single-precision floating-point value | | | F | float | single-precision floating-point value | | ||
| - | | I | int | integer | | + | | I | int | signed |
| - | | J | long | long integer | | + | | J | long | signed |
| | L// | | L// | ||
| | S | short | signed short | | | S | short | signed short | | ||
| Line 35: | Line 110: | ||
| | [ | reference | one array dimension | | | [ | reference | one array dimension | | ||
| - | A method descriptor is comprised of the method name, followed by a set of parentheses containing the input types, followed by the output | + | A method descriptor is comprised of the method name, followed by a set of parentheses containing the parameter |
| - | In the case that the output | + | In the case that the return |
| - | Generics' | + | Generics' |
| - | //@Inject// methods always have a void return type. The method name does not matter and neither does the access modifier; using something that describes what the inject does is best. The target method' | + | Furthermore, |
| - | === Returning & Cancelling from Inject | + | ===== Handler Method ===== |
| - | To cancel or return early inside a method, | + | A handler |
| - | <code java> | + | |
| - | @Inject(method | + | |
| - | </ | + | |
| + | '' | ||
| - | === Injecting into Constructors === | ||
| - | To inject into a constructor, | ||
| - | To inject into a static constructor, use ''< | + | ==== Cancelling the target method ==== |
| + | '' | ||
| - | ===== Practical Example ===== | + | This is also possible for other injectors via MixinExtras' |
| - | The following example injects a print statement at the top of '' | + | |
| - | <code java [enable_line_numbers=" | + | ===== Shifting ===== |
| - | @Mixin(TitleScreen.class) | + | '' |
| - | public class ExampleMixin { | + | |
| - | @Inject(at = @At(" | + | |
| - | private void init(CallbackInfo info) { | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | For more information on this particular example, view its usage in the [[https:// | + | The only common form of shifting comes in the form of using '' |
| + | < | ||
| + | @Inject(method = "...", at = @At(value = " | ||
| + | </ | ||
tutorial/mixin_injects.1659649070.txt.gz · Last modified: 2022/08/04 21:37 by clomclem