Skip to content

Commit

Permalink
Add caching to Block class analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
2No2Name committed Sep 24, 2023
1 parent af9fa98 commit a9a8051
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
import me.jellysquid.mods.lithium.common.ai.pathing.PathNodeCache;
import me.jellysquid.mods.lithium.common.entity.FluidCachingEntity;
import me.jellysquid.mods.lithium.common.reflection.ReflectionUtil;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ai.pathing.PathNodeType;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkSection;

import java.util.ArrayList;
Expand Down Expand Up @@ -114,13 +111,9 @@ public boolean test(BlockState operand) {
ArrayList<TrackedBlockStatePredicate> flags = new ArrayList<>(countingFlags);

ENTITY_TOUCHABLE = new TrackedBlockStatePredicate(countingFlags.size()) {
//How to find the remapped methods:
//1) Run in the debugger: System.out.println(FabricLoader.getInstance().getMappingResolver().getNamespaceData("intermediary").methodNames)
//2) Ctrl+F for the method name, in this case "onEntityCollision". Make sure to find the correct one.
private final String remapped_onEntityCollision = FabricLoader.getInstance().getMappingResolver().mapMethodName("intermediary", "net.minecraft.class_4970", "method_9548", "(Lnet/minecraft/class_2680;Lnet/minecraft/class_1937;Lnet/minecraft/class_2338;Lnet/minecraft/class_1297;)V");
@Override
public boolean test(BlockState operand) {
return ReflectionUtil.hasMethodOverride(operand.getBlock().getClass(), AbstractBlock.class, true, this.remapped_onEntityCollision, BlockState.class, World.class, BlockPos.class, Entity.class);
return ReflectionUtil.isBlockStateEntityTouchable(operand);
}
};
flags.add(ENTITY_TOUCHABLE);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
package me.jellysquid.mods.lithium.common.reflection;

import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.crash.CrashReportSection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.WeakHashMap;

public class ReflectionUtil {

public static boolean hasMethodOverride(Class<?> clazz, Class<?> superclass, boolean fallbackResult, String methodName, Class<?>... methodArgs) {
while (clazz != null && clazz != superclass && superclass.isAssignableFrom(clazz)) {
try {
Expand Down Expand Up @@ -38,4 +48,21 @@ public static boolean hasMethodOverride(Class<?> clazz, Class<?> superclass, boo
}
return false;
}

//How to find the remapped methods:
//1) Run in the debugger: System.out.println(FabricLoader.getInstance().getMappingResolver().getNamespaceData("intermediary").methodNames)
//2) Ctrl+F for the method name, in this case "onEntityCollision". Make sure to find the correct one.
private static final String REMAPPED_ON_ENTITY_COLLISION = FabricLoader.getInstance().getMappingResolver().mapMethodName("intermediary", "net.minecraft.class_4970", "method_9548", "(Lnet/minecraft/class_2680;Lnet/minecraft/class_1937;Lnet/minecraft/class_2338;Lnet/minecraft/class_1297;)V");
private static final WeakHashMap<Class<?>, Boolean> CACHED_IS_ENTITY_TOUCHABLE = new WeakHashMap<>();
public static boolean isBlockStateEntityTouchable(BlockState operand) {
Class<? extends Block> blockClazz = operand.getBlock().getClass();
//Caching results in hashmap as this calculation takes over a second for all blocks together
Boolean result = CACHED_IS_ENTITY_TOUCHABLE.get(blockClazz);
if (result != null) {
return result;
}
boolean res = ReflectionUtil.hasMethodOverride(blockClazz, AbstractBlock.class, true, REMAPPED_ON_ENTITY_COLLISION, BlockState.class, World.class, BlockPos.class, Entity.class);
CACHED_IS_ENTITY_TOUCHABLE.put(blockClazz, res);
return res;
}
}

0 comments on commit a9a8051

Please sign in to comment.