User Tools

Site Tools


tutorial:mixin_injects

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_injects [2020/02/07 01:58] draylartutorial:mixin_injects [2022/08/05 19:19] (current) – Added signed to integer types clomclem
Line 2: Line 2:
  
 ===== Introduction ===== ===== Introduction =====
-Injects allows you to place custom code at a specified position inside an existing method. For a working example, view the [[https://fabricmc.net/wiki/tutorial:mixin_injects#practical_example|Practical Example]] category at the bottom of this page. The standard form of an inject is as shown:+Injects allows you to place custom code at a specified position inside an existing method. For a working example, view the [[tutorial:mixin_injects#practical_example|Practical Example]] category at the bottom of this page. The standard form of an inject is as shown:
  
 <code java> <code java>
-@Inject(method = "", at = @At("INJECTION POINT REFERENCE"))+@Inject(method = "METHOD NAME OR SIGNATURE", at = @At("INJECTION POINT REFERENCE"))
 private void injectMethod(METHOD ARGS, CallbackInfo info) { private void injectMethod(METHOD ARGS, CallbackInfo info) {
  
Line 19: Line 19:
 | TAIL | Before the final return statement | | TAIL | Before the final return statement |
  
-In the case of injection points that reference statements or members, the target value can be set inside //@At//.+In the case of injection points that reference statements or members, the target value can be set inside //@At//. Target value is specified using JVM bytecode descriptors.
  
-//@Inject// methods always have a void return type. The method name does not matter; using something that describes what the inject does is best. The target method's arguments are placed first in the method's header, followed by a ''CallbackInfo'' object. If the target method has a return type (T), ''CallbackInfoReturnable<T>'' is used instead of ''CallbackInfo''.+Oracle defines the following [[https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.3.2|field descriptors]]: 
 + 
 +^ Descriptor ^ Primitive ^ Description ^ 
 +| B | byte | signed byte | 
 +| C | char | Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16 | 
 +| D | double | double-precision floating-point value | 
 +| F | float | single-precision floating-point value | 
 +| I | int | signed integer | 
 +| J | long | signed long integer | 
 +| L//ClassName//; | reference | an instance of //ClassName//
 +| S | short | signed short | 
 +| Z | boolean | ''true'' or ''false''
 +| [ | reference | one array dimension | 
 + 
 +A method descriptor is comprised of the method name, followed by a set of parentheses containing the parameter types, followed by the return type. A method defined in Java as ''Object m(int i, double[] d, Thread t)'' would have the method descriptor ''m(I[DLjava/lang/Thread;)Ljava/lang/Object;''
 + 
 +In the case that the return type is void, you need to use V (Void Descriptor Type) as the type (for example, ''void foo(String bar)'' would become ''foo(Ljava/lang/String;)V''). 
 + 
 +Generics' types are left out, as generics don't exist on runtime. So ''Pair<Integer, ? extends Task<? super VillagerEntity>‍>'' would become ''Lcom/mojang/datafixers/util/Pair''
 + 
 +''@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's arguments are placed first in the method's header, followed by a ''CallbackInfo'' object. If the target method has a return type (T), ''CallbackInfoReturnable<T>'' is used instead of ''CallbackInfo''.
  
 === Returning & Cancelling from Inject === === Returning & Cancelling from Inject ===
Line 31: Line 51:
  
 === Injecting into Constructors === === Injecting into Constructors ===
-To inject into a constructor, use ''<init>()V'' as the method target, with ''()'' containing the constructor argument descriptors. When injecting into constructors, ''@At'' must be set to either ''TAIL'' or ''RETURN''.+To inject into a constructor, use ''<init>()V'' as the method target, with ''()'' containing the constructor argument descriptors. When injecting into constructors, ''@At'' must be set to either ''TAIL'' or ''RETURN''. No other forms of injection are officially supported. Note that some classes have methods named ''init'' which are different from ''<init>''. Don't get confused! 
 + 
 +To inject into a static constructor, use ''<clinit>'' as the method name.
  
 ===== Practical Example ===== ===== Practical Example =====
-The following example injects a print statement at the top of ''TitleScreen#init''.+The following example injects a print statement at the top of ''TitleScreen#init'' (note: the method ''init'' is a normal method and not a constructor).
  
 <code java [enable_line_numbers="false"]> <code java [enable_line_numbers="false"]>
Line 46: Line 68:
 </code> </code>
  
-For more information on this particular example, view its usage in the [[Fabric Example Mod repo]].+For more information on this particular example, view its usage in the [[https://github.com/FabricMC/fabric-example-mod/blob/master/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java|Fabric Example Mod repo]].
tutorial/mixin_injects.1581040709.txt.gz · Last modified: 2020/02/07 01:58 by draylar