package com.llamalad7.mixinextras.sugar;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.CLASS;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* The Cancellable annotation can be applied on arguments of a {@link Redirect} handler
* to allow the possibility to cancel large quantities of logic within the injected method.
* More specifically, this annotation may only be applied on a {@link CallbackInfo}
* or {@link CallbackInfoReturnable} argument, which makes that argument behave similar
* to as if the {@link CallbackInfo} was used in a traditional setting with {@link Inject}
* and {@link Inject#cancellable()} set to true. Callback instances
* are reused where applicable and created lazily.
*
*
* private static int redirectStaticReturnable() {
* CancellableTest.counter1 = 1;
* CancellableTest.counter1 = new MutableInt(2).intValue();
* CancellableTest.counter1 = 3;
* return 0;
* }
*
*
* Execution of this method can be aborted after the redirected invocation of intValue
* using following mixin handler:
*
* @Redirect(at = @At(value = "INVOKE", target = "intValue"), method = "redirectStaticReturnable")
* private static int handleRedirectStaticReturnable(@NotNull MutableInt caller, @Cancellable CallbackInfoReturnable<Integer> ci) {
* ci.setReturnValue(1);
* return 4;
* }
*
*
* This results in following code:
*
*
* @CommonCIInstance(index=1)
* private static void redirectStatic() {
* CallbackInfo callbackInfo = null;
* counter0 = 1;
* MutableInt mutableInt = new MutableInt(2);
* if (callbackInfo == null) {
* callbackInfo = new CallbackInfo("redirectStatic", true);
* }
* int i = CancellableTest.$handler$0$redirect$handleRedirectStatic(mutableInt, callbackInfo);
* if (callbackInfo.isCancelled()) {
* return;
* }
* counter0 = i;
* counter0 = 3;
* }
*
*
* Note that in this case the assignment to counter0 will be cancelled, too.
*
* @since 0.6.3
*/
@Documented
@Retention(CLASS)
@Target(PARAMETER)
public @interface Cancellable { }