Make FlagManager patch handle both impls of CoFH Core
This commit is contained in:
parent
2b4199c0a6
commit
92a204c253
|
|
@ -7,7 +7,9 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import java.util.function.BooleanSupplier;
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix getOrCreateFlag accessing the FLAGS map without synchronization by wrapping all calls to it
|
* Fix getOrCreateFlag accessing the FLAGS map without synchronization by wrapping all calls to it
|
||||||
|
|
@ -18,19 +20,36 @@ import java.util.function.BooleanSupplier;
|
||||||
@RequiresMod("cofh_core")
|
@RequiresMod("cofh_core")
|
||||||
public class FlagManagerMixin {
|
public class FlagManagerMixin {
|
||||||
@Shadow @Final
|
@Shadow @Final
|
||||||
private static Object2ObjectOpenHashMap<String, BooleanSupplier> FLAGS;
|
private static Object2ObjectOpenHashMap<String, ?> FLAGS;
|
||||||
|
|
||||||
@Shadow
|
@Unique
|
||||||
private BooleanSupplier getOrCreateFlag(String flag) {
|
private static final MethodHandle mfix$getOrCreateFlag;
|
||||||
throw new AssertionError();
|
|
||||||
|
static {
|
||||||
|
// use this reflection dance to avoid depending on whether it's implemented via BooleanSupplier or Supplier<Boolean>
|
||||||
|
try {
|
||||||
|
Method m = MethodHandles.lookup().lookupClass().getDeclaredMethod("getOrCreateFlag", String.class);
|
||||||
|
m.setAccessible(true);
|
||||||
|
mfix$getOrCreateFlag = MethodHandles.lookup().unreflect(m);
|
||||||
|
} catch(ReflectiveOperationException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(method = "*", at = @At(value = "INVOKE", target = "getOrCreateFlag"), require = 0)
|
@Redirect(method = "*", at = @At(value = "INVOKE", target = "getOrCreateFlag"), require = 0)
|
||||||
private BooleanSupplier getFlag(@Coerce Object flagHandler, String flag) {
|
@Coerce
|
||||||
|
private Object getFlag(@Coerce Object flagHandler, String flag) {
|
||||||
if(flagHandler != this)
|
if(flagHandler != this)
|
||||||
throw new AssertionError("Redirect targeted bad getOrCreateFlag invocation");
|
throw new AssertionError("Redirect targeted bad getOrCreateFlag invocation");
|
||||||
synchronized (FLAGS) {
|
synchronized (FLAGS) {
|
||||||
return this.getOrCreateFlag(flag);
|
try {
|
||||||
|
return mfix$getOrCreateFlag.invoke((Object)this, flag);
|
||||||
|
} catch(Throwable e) {
|
||||||
|
if(e instanceof RuntimeException)
|
||||||
|
throw (RuntimeException)e;
|
||||||
|
else
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user