Skip to content

Commit

Permalink
Allow authors to specify order on injector annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed May 24, 2024
1 parent 1f34ee9 commit 02d7470
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 67 deletions.
23 changes: 23 additions & 0 deletions src/main/java/org/spongepowered/asm/mixin/injection/Inject.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,27 @@
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). The exception being redirect injectors, which apply in
* a later pass.
*
* <p>The default order for injectors is <tt>1000</tt>, and redirect
* injectors use <tt>10000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>900</tt> will cause the
* injector to apply before others, while <tt>1100</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses DEFAULT (1000) if
* not specified
*/
public int order() default 1000;

}
23 changes: 23 additions & 0 deletions src/main/java/org/spongepowered/asm/mixin/injection/ModifyArg.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,28 @@
* @return Constraints for this annotation
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). The exception being redirect injectors, which apply in
* a later pass.
*
* <p>The default order for injectors is <tt>1000</tt>, and redirect
* injectors use <tt>10000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>900</tt> will cause the
* injector to apply before others, while <tt>1100</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses DEFAULT (1000) if
* not specified
*/
public int order() default 1000;

}
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,28 @@
* @return Constraints for this annotation
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). The exception being redirect injectors, which apply in
* a later pass.
*
* <p>The default order for injectors is <tt>1000</tt>, and redirect
* injectors use <tt>10000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>900</tt> will cause the
* injector to apply before others, while <tt>1100</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses DEFAULT (1000) if
* not specified
*/
public int order() default 1000;

}
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,27 @@
* @return Constraints for this annotation
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). Redirect injectors apply in a later pass.
*
* <p>The default order for redirect injectors is <tt>10000</tt>, and all
* other injectors use <tt>1000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>9900</tt> will cause the
* injector to apply before others, while <tt>11000</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses default REDIRECT
* order (10000) if not specified
*/
public int order() default 10000;

}
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,28 @@
* @return Constraints for this annotation
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). The exception being redirect injectors, which apply in
* a later pass.
*
* <p>The default order for injectors is <tt>1000</tt>, and redirect
* injectors use <tt>10000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>900</tt> will cause the
* injector to apply before others, while <tt>1100</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses DEFAULT (1000) if
* not specified
*/
public int order() default 1000;

}
22 changes: 22 additions & 0 deletions src/main/java/org/spongepowered/asm/mixin/injection/Redirect.java
Original file line number Diff line number Diff line change
Expand Up @@ -438,5 +438,27 @@
* @return Constraints for this annotation
*/
public String constraints() default "";

/**
* By default almost all injectors for a target class apply their injections
* at the same time. In other words, if multiple mixins target the same
* class then injectors are applied in priority order (since the mixins
* themselves are merged in priority order, and injectors run in the order
* they were merged). Redirect injectors apply in a later pass.
*
* <p>The default order for redirect injectors is <tt>10000</tt>, and all
* other injectors use <tt>1000</tt>.</p>
*
* <p>Specifying a value for <tt>order</tt> alters this default behaviour
* and causes the injector to inject either earlier or later than it
* normally would. For example specifying <tt>9900</tt> will cause the
* injector to apply before others, while <tt>11000</tt> will apply later.
* Injectors with the same <tt>order</tt> will still apply in order of their
* mixin's <tt>priority</tt>.
*
* @return the application order for this injector, uses default REDIRECT
* order (10000) if not specified
*/
public int order() default 10000;

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* Information about a callback to inject, usually specified by {@link Inject}
*/
@AnnotationType(Inject.class)
@InjectorOrder(InjectorOrder.BUILTIN_CALLBACKS)
@InjectorOrder(InjectorOrder.DEFAULT)
public class CallbackInjectionInfo extends InjectionInfo {

protected CallbackInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,88 +123,41 @@ public abstract class InjectionInfo extends SpecialMethodInfo implements ISliceC
/**
* Decoration for subclasses which specifies the order (phase) in which the
* injector should be applied relative to other injectors. Built-in
* injectors all have predefined orders which allows custom injectors to
* specify their own order either as an explicit priority (eg. LATE) or
* relative to a known injector (eg. InjectorOrder.BUILTIN_REDIRECT - 100).
* injectors except for redirectors all run at DEFAULT unless specified in
* the injector annotation.
*
* <p>Built-in injectors are grouped into three separate phases rather than
* split into individual phases, in order to retain the existing behaviour
* of mixin priority. Injectors in the same order are sorted by mixin
* priority and declaration order within the mixin as always.</p>
* <p>Injectors in the same order are sorted by mixin priority and
* declaration order within the mixin as always.</p>
*/
@Retention(RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(ElementType.TYPE)
public @interface InjectorOrder {

/**
* The lowest possible order, avoid using this unlesss you are insane
*/
public static final int FIRST = Integer.MIN_VALUE;

/**
* A very early injector, will run before injectors such as ModifyArgs
* and ModifyVariable, as well as before EARLY injectors
*/
public static final int VERY_EARLY = 100;

/**
* An early injector, will run before injectors suchs as ModifyArgs
* and ModifyVariable
*/
public static final int EARLY = 250;

/**
* Built-in order for ModifyArg injectors
*/
public static final int BUILTIN_MODIFYARG = 500;

/**
* Built-in order for ModifyArgs injectors
* An early injector, run before most injectors
*/
public static final int BUILTIN_MODIFYARGS = 500;

/**
* Built-in order for ModifyVariable injectors
*/
public static final int BUILTIN_MODIFYVARIABLE = 500;
public static final int EARLY = 0;

/**
* Default order
* Default order, all injectors except redirect run here unless manually
* adjusted
*/
public static final int DEFAULT = 1000;

/**
* Built-in order for Inject injectors
*/
public static final int BUILTIN_CALLBACKS = 1000;

/**
* Late injector, runs after most injectors except VERY_LATE and
* Redirect injectors
* Late injector, runs after most injectors but before redirects
*/
public static final int LATE = 2000;

/**
* Built-in order for ModifyConstant injectors
*/
public static final int BUILTIN_MODIFYCONSTANT = 5000;

/**
* Built-in order for Redirect injectors
*/
public static final int BUILTIN_REDIRECT = 5000;

/**
* Very late injector, runs after nearly all injectors including
* Redirect injectors
*/
public static final int VERY_LATE = 10000;
public static final int REDIRECT = 10000;

/**
* The highest possible order, using this causes the universe to
* implode, bringing about the end of days.
* Injector which should run after redirect injector
*/
public static final int LAST = Integer.MAX_VALUE;
public static final int AFTER_REDIRECT = 20000;

/**
* String prefix for conforming handler methods
Expand Down Expand Up @@ -361,6 +314,12 @@ InjectionInfo create(MixinTargetContext mixin, MethodNode method, AnnotationNode
*/
private List<String> messages;

/**
* Injector order, parsed from either the injector annotation or uses the
* default for this injection type
*/
private int order;

/**
* ctor
*
Expand Down Expand Up @@ -400,6 +359,8 @@ protected void readAnnotation() {
this.readInjectionPoints();
activity.next("Parse Requirements");
this.parseRequirements();
activity.next("Parse Order");
this.parseOrder();
activity.next("Parse Selectors");
this.parseSelectors();
activity.next("Find Targets");
Expand Down Expand Up @@ -448,6 +409,17 @@ protected void parseRequirements() {
this.maxCallbackCount = Math.max(Math.max(this.requiredCallbackCount, 1), allow);
}
}

protected void parseOrder() {
Integer userOrder = Annotations.<Integer>getValue(this.annotation, "order");
if (userOrder != null) {
this.order = userOrder.intValue();
return;
}

InjectorOrder injectorDefault = this.getClass().<InjectorOrder>getAnnotation(InjectorOrder.class);
this.order = injectorDefault != null ? injectorDefault.value() : InjectorOrder.DEFAULT;
}

protected void parseSelectors() {
Set<ITargetSelector> selectors = new LinkedHashSet<ITargetSelector>();
Expand Down Expand Up @@ -484,8 +456,7 @@ public boolean isValid() {
* Get the application order for this injector type
*/
public int getOrder() {
InjectorOrder injectorOrder = this.getClass().<InjectorOrder>getAnnotation(InjectorOrder.class);
return injectorOrder != null ? injectorOrder.value() : InjectorOrder.DEFAULT;
return this.order;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
*/
@AnnotationType(ModifyArg.class)
@HandlerPrefix("modify")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYARG)
@InjectorOrder(InjectorOrder.DEFAULT)
public class ModifyArgInjectionInfo extends InjectionInfo {

public ModifyArgInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*/
@AnnotationType(ModifyArgs.class)
@HandlerPrefix("args")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYARG)
@InjectorOrder(InjectorOrder.DEFAULT)
public class ModifyArgsInjectionInfo extends InjectionInfo {

public ModifyArgsInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
*/
@AnnotationType(ModifyConstant.class)
@HandlerPrefix("constant")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYCONSTANT)
@InjectorOrder(InjectorOrder.REDIRECT)
public class ModifyConstantInjectionInfo extends InjectionInfo {

private static final String CONSTANT_ANNOTATION_CLASS = Constant.class.getName().replace('.', '/');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
*/
@AnnotationType(ModifyVariable.class)
@HandlerPrefix("localvar")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYVARIABLE)
@InjectorOrder(InjectorOrder.DEFAULT)
public class ModifyVariableInjectionInfo extends InjectionInfo {

public ModifyVariableInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*/
@AnnotationType(Redirect.class)
@HandlerPrefix("redirect")
@InjectorOrder(InjectorOrder.BUILTIN_REDIRECT)
@InjectorOrder(InjectorOrder.REDIRECT)
public class RedirectInjectionInfo extends InjectionInfo {

public RedirectInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down

0 comments on commit 02d7470

Please sign in to comment.