mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-26 14:24:30 +00:00
Mark tiles at transform time instead of using reflection (#2024)
This commit is contained in:
1 parent
bc8116006c
commit
553dec5b6d
13 files changed
+188
-185
No files matched your search
+13
-5
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.loading.fml.transformers;
|
||||
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
|
||||
import com.gtnewhorizons.angelica.loading.shared.AngelicaClassDump;
|
||||
import com.gtnewhorizons.angelica.loading.shared.transformers.CeleritasBlockTransform;
|
||||
import com.gtnewhorizons.angelica.loading.shared.transformers.TileEntityMarkerTransform;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
@@ -12,10 +13,12 @@ import org.objectweb.asm.tree.ClassNode;
|
||||
public class CeleritasBlockTransformer implements IClassTransformer {
|
||||
|
||||
private final CeleritasBlockTransform inner;
|
||||
private final TileEntityMarkerTransform tileEntities;
|
||||
private final String[] exclusions;
|
||||
|
||||
public CeleritasBlockTransformer() {
|
||||
this.inner = new CeleritasBlockTransform(AngelicaClientTweaker.isObfEnv());
|
||||
this.tileEntities = new TileEntityMarkerTransform(AngelicaClientTweaker.isObfEnv());
|
||||
this.exclusions = inner.getTransformerExclusions();
|
||||
}
|
||||
|
||||
@@ -31,14 +34,19 @@ public class CeleritasBlockTransformer implements IClassTransformer {
|
||||
}
|
||||
|
||||
final ClassReader cr = new ClassReader(basicClass);
|
||||
inner.trackBlockSubclasses(cr.getClassName(), cr.getSuperName());
|
||||
final String className = cr.getClassName();
|
||||
inner.trackBlockSubclasses(className, cr.getSuperName());
|
||||
tileEntities.track(className, cr.getSuperName());
|
||||
|
||||
if (!inner.shouldTransform(basicClass)) {
|
||||
return basicClass;
|
||||
final int markers = tileEntities.markersFor(className, basicClass);
|
||||
final byte[] marked = markers == 0 ? basicClass : tileEntities.addMarkers(basicClass, markers);
|
||||
|
||||
if (!inner.shouldTransform(marked)) {
|
||||
return marked;
|
||||
}
|
||||
|
||||
final ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, 0);
|
||||
(markers == 0 ? cr : new ClassReader(marked)).accept(cn, 0);
|
||||
final boolean changed = inner.transformClassNode(transformedName, cn);
|
||||
if (changed) {
|
||||
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
@@ -47,7 +55,7 @@ public class CeleritasBlockTransformer implements IClassTransformer {
|
||||
AngelicaClassDump.dumpClass(transformedName, basicClass, bytes, this);
|
||||
return bytes;
|
||||
}
|
||||
return basicClass;
|
||||
return marked;
|
||||
}
|
||||
|
||||
}
|
||||
+24
-3
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.loading.rfb.transformers;
|
||||
|
||||
import com.gtnewhorizons.angelica.loading.shared.AngelicaClassDump;
|
||||
import com.gtnewhorizons.angelica.loading.shared.transformers.CeleritasBlockTransform;
|
||||
import com.gtnewhorizons.angelica.loading.shared.transformers.TileEntityMarkerTransform;
|
||||
import com.gtnewhorizons.retrofuturabootstrap.api.ClassHeaderMetadata;
|
||||
import com.gtnewhorizons.retrofuturabootstrap.api.ClassNodeHandle;
|
||||
import com.gtnewhorizons.retrofuturabootstrap.api.ExtensibleClassLoader;
|
||||
@@ -9,15 +10,18 @@ import com.gtnewhorizons.retrofuturabootstrap.api.RfbClassTransformer;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class RFBCeleritasBlockTransformer implements RfbClassTransformer {
|
||||
|
||||
private final CeleritasBlockTransform inner;
|
||||
private final TileEntityMarkerTransform tileEntities;
|
||||
|
||||
public RFBCeleritasBlockTransformer(boolean isObf) {
|
||||
inner = new CeleritasBlockTransform(isObf);
|
||||
tileEntities = new TileEntityMarkerTransform(isObf);
|
||||
}
|
||||
|
||||
@Pattern("[a-z0-9-]+")
|
||||
@@ -54,15 +58,32 @@ public class RFBCeleritasBlockTransformer implements RfbClassTransformer {
|
||||
return false;
|
||||
}
|
||||
|
||||
inner.trackBlockSubclasses(metadata.binaryThisName(), metadata.binarySuperName());
|
||||
return inner.shouldTransform(classNode.getOriginalBytes());
|
||||
final String thisName = metadata.binaryThisName();
|
||||
final String superName = metadata.binarySuperName();
|
||||
final byte[] originalBytes = classNode.getOriginalBytes();
|
||||
|
||||
inner.trackBlockSubclasses(thisName, superName);
|
||||
if (context == RfbClassTransformer.Context.LCL_WITH_TRANSFORMS) {
|
||||
tileEntities.track(thisName, superName);
|
||||
if (tileEntities.markersFor(thisName, originalBytes) != 0) return true;
|
||||
}
|
||||
return inner.shouldTransform(originalBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformClassIfNeeded(@NotNull ExtensibleClassLoader classLoader,
|
||||
@NotNull RfbClassTransformer.Context context, @Nullable Manifest manifest,
|
||||
@NotNull String className, @NotNull ClassNodeHandle classNode) {
|
||||
final boolean changed = inner.transformClassNode(className, classNode.getNode());
|
||||
final ClassNode node = classNode.getNode();
|
||||
boolean changed = false;
|
||||
if (context == RfbClassTransformer.Context.LCL_WITH_TRANSFORMS) {
|
||||
final int markers = tileEntities.markersFor(node.name, classNode.getOriginalBytes());
|
||||
if (markers != 0) {
|
||||
tileEntities.addMarkers(node, markers);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
changed |= inner.transformClassNode(className, node);
|
||||
if (changed) {
|
||||
classNode.computeMaxs();
|
||||
AngelicaClassDump.dumpRFBClass(className, classNode, this);
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package com.gtnewhorizons.angelica.loading.shared.transformers;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.asm.ClassConstantPoolParser;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Marks TileEntity subclasses that declare getDescriptionPacket, shouldRenderInPass or getDistanceFrom with a
|
||||
* corresponding interface, so runtime code can test with instanceof instead of reflection.
|
||||
*/
|
||||
public final class TileEntityMarkerTransform {
|
||||
|
||||
public static final int MARK_DESCRIPTION_PACKET = 1 << 0;
|
||||
public static final int MARK_SHOULD_RENDER_IN_PASS = 1 << 1;
|
||||
public static final int MARK_GET_DISTANCE_FROM = 1 << 2;
|
||||
|
||||
private static final String SENDS_DESCRIPTION_PACKET = "com/gtnewhorizons/angelica/mixins/interfaces/SendsDescriptionPacket";
|
||||
private static final String OVERRIDES_SHOULD_RENDER_IN_PASS = "com/gtnewhorizons/angelica/mixins/interfaces/OverridesShouldRenderInPass";
|
||||
private static final String OVERRIDES_GET_DISTANCE_FROM = "com/gtnewhorizons/angelica/mixins/interfaces/OverridesGetDistanceFrom";
|
||||
|
||||
private static final String TILE_ENTITY = "net/minecraft/tileentity/TileEntity";
|
||||
private static final int SCAN_FLAGS = ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES;
|
||||
|
||||
private record Marker(int bit, String method, String desc, String iface) {}
|
||||
|
||||
private final Marker[] markers;
|
||||
private final ClassConstantPoolParser prefilter;
|
||||
private final Set<String> tileEntities = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
|
||||
public TileEntityMarkerTransform(boolean isObf) {
|
||||
this.markers = new Marker[] {
|
||||
new Marker(MARK_DESCRIPTION_PACKET, isObf ? "func_145844_m" : "getDescriptionPacket", "()Lnet/minecraft/network/Packet;", SENDS_DESCRIPTION_PACKET),
|
||||
new Marker(MARK_SHOULD_RENDER_IN_PASS, "shouldRenderInPass", "(I)Z", OVERRIDES_SHOULD_RENDER_IN_PASS),
|
||||
new Marker(MARK_GET_DISTANCE_FROM, isObf ? "func_145835_a" : "getDistanceFrom", "(DDD)D", OVERRIDES_GET_DISTANCE_FROM) };
|
||||
|
||||
final String[] methods = new String[markers.length];
|
||||
for (int i = 0; i < markers.length; i++) methods[i] = markers[i].method();
|
||||
this.prefilter = new ClassConstantPoolParser(methods);
|
||||
|
||||
}
|
||||
|
||||
private boolean isTileEntity(String className) {
|
||||
return className != null && (className.startsWith(TILE_ENTITY) || tileEntities.contains(className));
|
||||
}
|
||||
|
||||
public void track(String className, String superClassName) {
|
||||
if (className != null && isTileEntity(superClassName)) tileEntities.add(className);
|
||||
}
|
||||
|
||||
public int markersFor(String className, byte[] classBytes) {
|
||||
if (TILE_ENTITY.equals(className) || !isTileEntity(className) || !prefilter.find(classBytes)) return 0;
|
||||
|
||||
final MarkerScanner scanner = new MarkerScanner();
|
||||
new ClassReader(classBytes).accept(scanner, SCAN_FLAGS);
|
||||
return scanner.declared & ~scanner.alreadyPresent;
|
||||
}
|
||||
|
||||
public byte[] addMarkers(byte[] classBytes, int markers) {
|
||||
final ClassReader cr = new ClassReader(classBytes);
|
||||
final ClassWriter cw = new ClassWriter(cr, 0);
|
||||
cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String sig, String superName, String[] interfaces) {
|
||||
final String[] added = interfacesFor(markers);
|
||||
if (interfaces == null) {
|
||||
super.visit(version, access, name, sig, superName, added);
|
||||
return;
|
||||
}
|
||||
final String[] merged = Arrays.copyOf(interfaces, interfaces.length + added.length);
|
||||
System.arraycopy(added, 0, merged, interfaces.length, added.length);
|
||||
super.visit(version, access, name, sig, superName, merged);
|
||||
}
|
||||
}, 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
public void addMarkers(ClassNode cn, int markers) {
|
||||
Collections.addAll(cn.interfaces, interfacesFor(markers));
|
||||
}
|
||||
|
||||
private int bitOf(int access, String name, String desc) {
|
||||
if ((access & Opcodes.ACC_PUBLIC) == 0 || (access & Opcodes.ACC_STATIC) != 0) return 0;
|
||||
for (Marker m : markers) if (m.method().equals(name) && m.desc().equals(desc)) return m.bit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int bitOf(String interfaceName) {
|
||||
for (Marker m : markers) if (m.iface().equals(interfaceName)) return m.bit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String[] interfacesFor(int wanted) {
|
||||
final String[] names = new String[Integer.bitCount(wanted)];
|
||||
int next = 0;
|
||||
for (Marker m : markers) if ((wanted & m.bit()) != 0) names[next++] = m.iface();
|
||||
return names;
|
||||
}
|
||||
|
||||
private final class MarkerScanner extends ClassVisitor {
|
||||
|
||||
private int declared;
|
||||
private int alreadyPresent;
|
||||
|
||||
MarkerScanner() {
|
||||
super(Opcodes.ASM5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String sig, String superName, String[] interfaces) {
|
||||
if (interfaces == null) return;
|
||||
for (String iface : interfaces) alreadyPresent |= bitOf(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] exceptions) {
|
||||
declared |= bitOf(access, name, desc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -6,6 +6,4 @@ public interface ITileEntityBoundingBoxCache {
|
||||
AxisAlignedBB angelica$getCachedRenderBoundingBox();
|
||||
|
||||
byte angelica$boundsClass();
|
||||
|
||||
byte angelica$passClass();
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package com.gtnewhorizons.angelica.mixins.interfaces;
|
||||
|
||||
public interface OverridesGetDistanceFrom {}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package com.gtnewhorizons.angelica.mixins.interfaces;
|
||||
|
||||
public interface OverridesShouldRenderInPass {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.gtnewhorizons.angelica.mixins.interfaces;
|
||||
|
||||
public interface SendsDescriptionPacket {}
|
||||
-82
@@ -1,7 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.rendering;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ByteOpenHashMap;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
@@ -17,25 +16,12 @@ public final class TileEntityRenderBoundsRegistry {
|
||||
public static final byte INFINITE = 2;
|
||||
public static final byte DYNAMIC = 3;
|
||||
|
||||
public static final byte PASS0_ONLY = 1;
|
||||
public static final byte PASS_OVERRIDES = 2;
|
||||
|
||||
private static final byte NOT_OVERRIDDEN = 1;
|
||||
private static final byte OVERRIDDEN = 2;
|
||||
|
||||
private static final Reference2ByteOpenHashMap<Class<? extends TileEntity>> classRegistry = new Reference2ByteOpenHashMap<>();
|
||||
private static final Reference2ByteOpenHashMap<Class<? extends TileEntity>> passClassRegistry = new Reference2ByteOpenHashMap<>();
|
||||
private static final Reference2ByteOpenHashMap<Class<? extends TileEntity>> distanceOverrideRegistry = new Reference2ByteOpenHashMap<>();
|
||||
|
||||
private static final Set<String> dynamicClassNames = ConcurrentHashMap.newKeySet();
|
||||
|
||||
private static final String[] SHOULD_RENDER_IN_PASS_NAMES = { "shouldRenderInPass" };
|
||||
private static String[] distanceFromNames;
|
||||
|
||||
static {
|
||||
classRegistry.defaultReturnValue(UNKNOWN);
|
||||
passClassRegistry.defaultReturnValue(UNKNOWN);
|
||||
distanceOverrideRegistry.defaultReturnValue(UNKNOWN);
|
||||
}
|
||||
|
||||
private TileEntityRenderBoundsRegistry() {}
|
||||
@@ -73,72 +59,4 @@ public final class TileEntityRenderBoundsRegistry {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean overridesMethod(Class<?> clazz, Class<?> base, String[] candidateNames, Class<?>... params) {
|
||||
for (String name : candidateNames) {
|
||||
try {
|
||||
return clazz.getMethod(name, params).getDeclaringClass() != base;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
} catch (Throwable t) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String[] distanceFromNames() {
|
||||
String[] names = distanceFromNames;
|
||||
if (names == null) {
|
||||
String resolved;
|
||||
try {
|
||||
resolved = Boolean.TRUE.equals(Launch.blackboard.get("fml.deobfuscatedEnvironment")) ? "getDistanceFrom" : "func_145835_a";
|
||||
} catch (Throwable t) {
|
||||
resolved = "getDistanceFrom";
|
||||
}
|
||||
distanceFromNames = names = new String[] { resolved };
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public static byte classifyPass(TileEntity te) {
|
||||
final Class<? extends TileEntity> clazz = te.getClass();
|
||||
synchronized (passClassRegistry) {
|
||||
final byte cached = passClassRegistry.getByte(clazz);
|
||||
if (cached != UNKNOWN) return cached;
|
||||
}
|
||||
|
||||
final byte result = overridesMethod(clazz, TileEntity.class, SHOULD_RENDER_IN_PASS_NAMES, int.class)
|
||||
? PASS_OVERRIDES : PASS0_ONLY;
|
||||
|
||||
synchronized (passClassRegistry) {
|
||||
passClassRegistry.put(clazz, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean overridesGetDistanceFrom(Class<? extends TileEntity> clazz) {
|
||||
synchronized (distanceOverrideRegistry) {
|
||||
final byte cached = distanceOverrideRegistry.getByte(clazz);
|
||||
if (cached != UNKNOWN) return cached == OVERRIDDEN;
|
||||
}
|
||||
|
||||
final boolean overrides = overridesMethod(clazz, TileEntity.class, distanceFromNames(), double.class, double.class, double.class);
|
||||
|
||||
synchronized (distanceOverrideRegistry) {
|
||||
distanceOverrideRegistry.put(clazz, overrides ? OVERRIDDEN : NOT_OVERRIDDEN);
|
||||
}
|
||||
return overrides;
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
synchronized (classRegistry) {
|
||||
classRegistry.clear();
|
||||
}
|
||||
synchronized (passClassRegistry) {
|
||||
passClassRegistry.clear();
|
||||
}
|
||||
synchronized (distanceOverrideRegistry) {
|
||||
distanceOverrideRegistry.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -4,6 +4,7 @@ import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import com.gtnewhorizons.angelica.rendering.AngelicaRenderQueue;
|
||||
import com.gtnewhorizons.angelica.rendering.StateAwareTessellator;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.OverridesGetDistanceFrom;
|
||||
import com.gtnewhorizons.angelica.rendering.TileEntityRenderBoundsRegistry;
|
||||
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProvider;
|
||||
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
|
||||
@@ -190,7 +191,7 @@ public abstract class AngelicaChunkBuilderMeshingTask extends ChunkBuilderTask<C
|
||||
renderData.culledBlockEntities.add(tileEntity);
|
||||
AngelicaBuiltRenderSectionData.packSectionLocalBounds(culledBounds, aabb, minX, minY, minZ);
|
||||
double teDistSq;
|
||||
if (TileEntityRenderBoundsRegistry.overridesGetDistanceFrom(tileEntity.getClass())) {
|
||||
if (tileEntity instanceof OverridesGetDistanceFrom) {
|
||||
teDistSq = Double.POSITIVE_INFINITY;
|
||||
} else {
|
||||
try {
|
||||
|
||||
+2
-1
@@ -45,6 +45,7 @@ import com.gtnewhorizons.angelica.dynamiclights.IDynamicLightWorldRenderer;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ITileEntityBoundingBoxCache;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.OverridesShouldRenderInPass;
|
||||
import com.gtnewhorizons.angelica.profiling.RenderClassTimings;
|
||||
import com.gtnewhorizons.angelica.proxy.ClientProxy;
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
@@ -405,7 +406,7 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
|
||||
try {
|
||||
for (int i = 0; i < frameTEs.size(); i++) {
|
||||
final TileEntity te = frameTEs.get(i);
|
||||
if (((ITileEntityBoundingBoxCache) te).angelica$passClass() == TileEntityRenderBoundsRegistry.PASS0_ONLY) {
|
||||
if (!(te instanceof OverridesShouldRenderInPass)) {
|
||||
dispatchTE(te, partialTicks);
|
||||
count++;
|
||||
continue;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
@@ -9,6 +10,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.AwaitingDescriptorTE;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.SendsDescriptionPacket;
|
||||
|
||||
public final class AwaitingDescriptor {
|
||||
|
||||
@@ -16,12 +18,12 @@ public final class AwaitingDescriptor {
|
||||
|
||||
private static final int WAIT_TICKS = 100;
|
||||
|
||||
private static final Map<Class<?>, Boolean> SENDS_DESCRIPTOR = new ConcurrentHashMap<>();
|
||||
private static final Set<Class<?>> NEVER_SENT = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
|
||||
private AwaitingDescriptor() {}
|
||||
|
||||
public static void begin(TileEntity te) {
|
||||
if (!SENDS_DESCRIPTOR.computeIfAbsent(te.getClass(), AwaitingDescriptor::sendsDescriptor)) return;
|
||||
if (!(te instanceof SendsDescriptionPacket) || NEVER_SENT.contains(te.getClass())) return;
|
||||
|
||||
final AwaitingDescriptorTE tile = (AwaitingDescriptorTE) te;
|
||||
tile.angelica$setAwaitingDescriptor(true);
|
||||
@@ -43,16 +45,9 @@ public final class AwaitingDescriptor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean sendsDescriptor(Class<?> cls) {
|
||||
try {
|
||||
return cls.getMethod("getDescriptionPacket").getDeclaringClass() != TileEntity.class;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
private static void stopWaitingOn(Class<?> cls) {
|
||||
if (NEVER_SENT.add(cls)) {
|
||||
LOGGER.warn("{} declares getDescriptionPacket() but never sent one", cls.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void stopWaitingOn(Class<?> cls) {
|
||||
if (!Boolean.TRUE.equals(SENDS_DESCRIPTOR.put(cls, Boolean.FALSE))) return;
|
||||
LOGGER.warn("{} declares getDescriptionPacket() but never sent one", cls.getName());
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,6 @@ public abstract class MixinTileEntity implements ITileEntityBoundingBoxCache {
|
||||
@Unique private Block angelica$cachedBBBlockType = null;
|
||||
@Unique private AxisAlignedBB angelica$cachedRenderBB = null;
|
||||
@Unique private byte angelica$boundsClassCached = 0; // 0 = unchecked, otherwise STATIC/INFINITE/DYNAMIC
|
||||
@Unique private byte angelica$passClassCached = 0; // 0 = unchecked, otherwise PASS0_ONLY/PASS_OVERRIDES
|
||||
|
||||
/**
|
||||
* @author mitchej123
|
||||
@@ -122,11 +121,4 @@ public abstract class MixinTileEntity implements ITileEntityBoundingBoxCache {
|
||||
return angelica$boundsClassCached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte angelica$passClass() {
|
||||
if (angelica$passClassCached == 0) {
|
||||
angelica$passClassCached = TileEntityRenderBoundsRegistry.classifyPass((TileEntity) (Object) this);
|
||||
}
|
||||
return angelica$passClassCached;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.rendering;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class OverridesMethodTest {
|
||||
|
||||
static class Base {
|
||||
public double dist(double x, double y, double z) { return 0; }
|
||||
public boolean pass(int p) { return p == 0; }
|
||||
}
|
||||
|
||||
static class Plain extends Base {}
|
||||
|
||||
static class Direct extends Base {
|
||||
@Override public double dist(double x, double y, double z) { return 1; }
|
||||
}
|
||||
|
||||
static class Inherited extends Direct {}
|
||||
|
||||
interface DefaultDist {
|
||||
default double dist(double x, double y, double z) { return 2; }
|
||||
}
|
||||
|
||||
static class WithInterfaceDefault extends Base implements DefaultDist {}
|
||||
|
||||
private static final String[] DIST = { "dist" };
|
||||
private static final String[] PASS = { "pass" };
|
||||
private static final Class<?>[] DIST_PARAMS = { double.class, double.class, double.class };
|
||||
|
||||
@Test
|
||||
void baseDeclarationIsNotAnOverride() {
|
||||
assertFalse(TileEntityRenderBoundsRegistry.overridesMethod(Base.class, Base.class, DIST, DIST_PARAMS));
|
||||
assertFalse(TileEntityRenderBoundsRegistry.overridesMethod(Plain.class, Base.class, DIST, DIST_PARAMS));
|
||||
assertFalse(TileEntityRenderBoundsRegistry.overridesMethod(Plain.class, Base.class, PASS, int.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void directOverrideDetected() {
|
||||
assertTrue(TileEntityRenderBoundsRegistry.overridesMethod(Direct.class, Base.class, DIST, DIST_PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void inheritedOverrideDetected() {
|
||||
assertTrue(TileEntityRenderBoundsRegistry.overridesMethod(Inherited.class, Base.class, DIST, DIST_PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void classMethodBeatsInterfaceDefault() {
|
||||
assertFalse(TileEntityRenderBoundsRegistry.overridesMethod(WithInterfaceDefault.class, Base.class, DIST, DIST_PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unresolvableNameTreatedAsOverriding() {
|
||||
assertTrue(TileEntityRenderBoundsRegistry.overridesMethod(Plain.class, Base.class, new String[] { "func_145835_a" }, DIST_PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongParametersTreatedAsOverriding() {
|
||||
assertTrue(TileEntityRenderBoundsRegistry.overridesMethod(Plain.class, Base.class, DIST, double.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void firstMatchingCandidateNameWins() {
|
||||
assertTrue(TileEntityRenderBoundsRegistry.overridesMethod(Direct.class, Base.class, new String[] { "func_145835_a", "dist" }, DIST_PARAMS));
|
||||
assertFalse(TileEntityRenderBoundsRegistry.overridesMethod(Plain.class, Base.class, new String[] { "func_145835_a", "dist" }, DIST_PARAMS));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user