====== Инжекторы Миксинов ====== ===== Вступление ===== Инжекторы позволяют размещать пользовательский код в указанной позиции внутри существующего метода. Для рабочего примера просмотрите [[ru:tutorial:mixin_injects#Пример|категорию внизу этой страницы]]. Стандартная форма внедрения выглядит так, как показано в коде: @Inject(method = "", at = @At("INJECTION POINT REFERENCE")) private void injectMethod(METHOD ARGS, CallbackInfo info) { } [[https://github.com/SpongePowered/Mixin/wiki/Injection-Point-Reference|Контрольная-Точка-Внедрения]] определяет, где код внутри тела метода вводится внутри целевого метода. В следующей таблице описаны некоторые из вариантов: ^ Имя ^ Описание ^ | HEAD | Верхняя часть метода | | RETURN | Перед каждым оператором return | | INVOKE | При вызове метода | | TAIL | Перед заключительным оператором возврата | В случае точек внедрения, которые ссылаются на операторы или элементы, целевое значение может быть установлено внутри //@At//. Целевое значение задается с помощью дескрипторов байт-кода JVM. Oracle определяет следующее [[https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.3.2|поля дескрипторов]]: ^ Дескриптор ^ Тип ^ Описание ^ | B | byte | Записанный байт | | C | char | Кодовая точка символа Юникода в базовой многоязычной плоскости, закодированная с помощью UTF-16 | | D | double | Значение с плавающей точкой двойной точности | | F | float | Значение с плавающей точкой одинарной точности | | I | int | Целое число | | J | long | Длинное целое число | | L//ClassName//; | reference | экземпляр //ClassName// | | S | short | Краткая запись | | Z | boolean | ''true''(правда) или ''false''(ложь) | | [ | reference | Одно измерение массива | Дескриптор метода состоит из имени метода, за которым следует набор круглых скобок, содержащих типы ввода, за которыми следует тип вывода. Метод, определенный в Java как ''Object m(int i, double[] d, Thread t)'' будет иметь дескриптор метода ''m(I[DLjava/lang/Thread;)Ljava/lang/Object;''. Типы дженериков не учитываются, так как дженерики не существуют во время выполнения. Значит ''Pair‍>'' станет ''Lcom/mojang/datafixers/util/Pair''. //@Inject// методы всегда имеют возвращаемый тип void. Имя метода не имеет значения; лучше всего использовать что-то, описывающее, что делает внедрение. Аргументы целевого метода помещаются первыми в заголовок метода, за которым следует объект "CallbackInfo". Если целевой метод имеет возвращаемый тип (T), вместо "CallbackInfoReturnable" используется "Callbackinfo". === Возврат и отмена при внедрении === Чтобы отменить или вернуться раньше внутри метода, используйте ''CallbackInfo#cancel'' или ''CallbackInfoReturnable#setReturnValue(T)''. Обратите внимание, что "cancel" не обязательно вызывается после "setReturnValue". В обоих случаях для параметра "cancellable" в аннотации внедрения должно быть установлено значение true: @Inject(method = "...", at = @At("..."), cancellable = true) === Внедрение в конструкторы === Чтобы внедрить в конструктор, используйте ''()V'' в качестве целевого метода, ''()'' содержит дескрипторы аргументов конструктора. При вводе в конструкторы "@At" должно быть установлено либо на "TAIL", либо на "RETURN". Никакие другие формы внедрения официально не поддерживаются. Обратите внимание, что некоторые классы имеют методы с именем "init", которые отличаются от "". Не путайте! Чтобы внедрить в статический конструктор, используйте "" в качестве имени метода. ===== Пример ===== В следующем примере вводится оператор печати в верхней части "TitleScreen#init" (примечание: метод "init" является обычным методом, а не конструктором). @Mixin(TitleScreen.class) public class ExampleMixin { @Inject(at = @At("HEAD"), method = "init()V") private void init(CallbackInfo info) { System.out.println("Эта строка написана модом через миксин!"); } } Для получения дополнительной информации об этом конкретном примере ознакомьтесь с его использованием в [[https://github.com/FabricMC/fabric-example-mod/blob/master/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java|репозитории Fabric Example Mod]].