|
@@ -2,40 +2,35 @@ package malte0811.ferritecore.impl;
|
|
|
|
|
|
import com.mojang.datafixers.util.Pair;
|
|
import com.mojang.datafixers.util.Pair;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
|
-import malte0811.ferritecore.ModMain;
|
|
|
|
import malte0811.ferritecore.hash.VoxelShapeArrayHash;
|
|
import malte0811.ferritecore.hash.VoxelShapeArrayHash;
|
|
import malte0811.ferritecore.hash.VoxelShapeHash;
|
|
import malte0811.ferritecore.hash.VoxelShapeHash;
|
|
import malte0811.ferritecore.mixin.blockstatecache.VSArrayAccess;
|
|
import malte0811.ferritecore.mixin.blockstatecache.VSArrayAccess;
|
|
import malte0811.ferritecore.mixin.blockstatecache.VoxelShapeAccess;
|
|
import malte0811.ferritecore.mixin.blockstatecache.VoxelShapeAccess;
|
|
import malte0811.ferritecore.util.LastAccessedCache;
|
|
import malte0811.ferritecore.util.LastAccessedCache;
|
|
-import net.minecraft.block.Block;
|
|
|
|
-import net.minecraft.block.BlockState;
|
|
|
|
-import net.minecraft.util.Direction;
|
|
|
|
-import net.minecraft.util.math.BlockPos;
|
|
|
|
-import net.minecraft.util.math.shapes.ISelectionContext;
|
|
|
|
-import net.minecraft.util.math.shapes.VoxelShape;
|
|
|
|
-import net.minecraft.util.math.shapes.VoxelShapeArray;
|
|
|
|
-import net.minecraft.util.math.shapes.VoxelShapes;
|
|
|
|
-import net.minecraft.world.IBlockReader;
|
|
|
|
-import net.minecraftforge.event.TagsUpdatedEvent;
|
|
|
|
-import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
|
|
-import net.minecraftforge.fml.common.Mod;
|
|
|
|
-import net.minecraftforge.fml.event.lifecycle.FMLModIdMappingEvent;
|
|
|
|
|
|
+import net.minecraft.core.BlockPos;
|
|
|
|
+import net.minecraft.core.Direction;
|
|
|
|
+import net.minecraft.world.level.BlockGetter;
|
|
|
|
+import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
|
|
+import net.minecraft.world.level.block.state.BlockState;
|
|
|
|
+import net.minecraft.world.phys.shapes.ArrayVoxelShape;
|
|
|
|
+import net.minecraft.world.phys.shapes.CollisionContext;
|
|
|
|
+import net.minecraft.world.phys.shapes.Shapes;
|
|
|
|
+import net.minecraft.world.phys.shapes.VoxelShape;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
|
import java.util.function.Function;
|
|
import java.util.function.Function;
|
|
|
|
|
|
-@Mod.EventBusSubscriber(modid = ModMain.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
|
|
|
|
|
|
+//TODO @Mod.EventBusSubscriber(modid = ModMain.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
|
|
public class BlockStateCacheImpl {
|
|
public class BlockStateCacheImpl {
|
|
private static final Direction[] DIRECTIONS = Direction.values();
|
|
private static final Direction[] DIRECTIONS = Direction.values();
|
|
- public static final Object2ObjectOpenCustomHashMap<VoxelShapeArray, VoxelShapeArray> CACHE_COLLIDE =
|
|
|
|
|
|
+ public static final Object2ObjectOpenCustomHashMap<ArrayVoxelShape, ArrayVoxelShape> CACHE_COLLIDE =
|
|
new Object2ObjectOpenCustomHashMap<>(VoxelShapeArrayHash.INSTANCE);
|
|
new Object2ObjectOpenCustomHashMap<>(VoxelShapeArrayHash.INSTANCE);
|
|
public static final LastAccessedCache<VoxelShape, VoxelShape[]> CACHE_PROJECT = new LastAccessedCache<>(
|
|
public static final LastAccessedCache<VoxelShape, VoxelShape[]> CACHE_PROJECT = new LastAccessedCache<>(
|
|
VoxelShapeHash.INSTANCE, vs -> {
|
|
VoxelShapeHash.INSTANCE, vs -> {
|
|
VoxelShape[] result = new VoxelShape[DIRECTIONS.length];
|
|
VoxelShape[] result = new VoxelShape[DIRECTIONS.length];
|
|
for (Direction d : DIRECTIONS) {
|
|
for (Direction d : DIRECTIONS) {
|
|
- result[d.ordinal()] = VoxelShapes.getFaceShape(vs, d);
|
|
|
|
|
|
+ result[d.ordinal()] = Shapes.getFaceShape(vs, d);
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
@@ -43,17 +38,17 @@ public class BlockStateCacheImpl {
|
|
public static int collideCalls = 0;
|
|
public static int collideCalls = 0;
|
|
public static int projectCalls = 0;
|
|
public static int projectCalls = 0;
|
|
|
|
|
|
|
|
+ //TODO
|
|
// Caches are populated in two places: a) In ITagCollectionSupplier#updateTags (which triggers this event)
|
|
// Caches are populated in two places: a) In ITagCollectionSupplier#updateTags (which triggers this event)
|
|
- @SubscribeEvent
|
|
|
|
- public static void onTagReloadVanilla(TagsUpdatedEvent.VanillaTagTypes ignored) {
|
|
|
|
- resetCaches();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ //@SubscribeEvent
|
|
|
|
+ //public static void onTagReloadVanilla(TagsUpdatedEvent.VanillaTagTypes ignored) {
|
|
|
|
+ // resetCaches();
|
|
|
|
+ //}
|
|
// b) Via ForgeRegistry#bake, which usually triggers this event
|
|
// b) Via ForgeRegistry#bake, which usually triggers this event
|
|
- @SubscribeEvent
|
|
|
|
- public static void onModIdMapping(FMLModIdMappingEvent ignored) {
|
|
|
|
- resetCaches();
|
|
|
|
- }
|
|
|
|
|
|
+ //@SubscribeEvent
|
|
|
|
+ //public static void onModIdMapping(FMLModIdMappingEvent ignored) {
|
|
|
|
+ // resetCaches();
|
|
|
|
+ //}
|
|
|
|
|
|
private static void resetCaches() {
|
|
private static void resetCaches() {
|
|
//TODO remove
|
|
//TODO remove
|
|
@@ -69,15 +64,15 @@ public class BlockStateCacheImpl {
|
|
}
|
|
}
|
|
|
|
|
|
public static VoxelShape redirectGetCollisionShape(
|
|
public static VoxelShape redirectGetCollisionShape(
|
|
- Block block, BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context
|
|
|
|
|
|
+ BlockBehaviour block, BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context
|
|
) {
|
|
) {
|
|
VoxelShape baseResult = block.getCollisionShape(state, worldIn, pos, context);
|
|
VoxelShape baseResult = block.getCollisionShape(state, worldIn, pos, context);
|
|
- if (!(baseResult instanceof VoxelShapeArray)) {
|
|
|
|
|
|
+ if (!(baseResult instanceof ArrayVoxelShape)) {
|
|
return baseResult;
|
|
return baseResult;
|
|
}
|
|
}
|
|
- VoxelShapeArray baseArray = (VoxelShapeArray) baseResult;
|
|
|
|
|
|
+ ArrayVoxelShape baseArray = (ArrayVoxelShape) baseResult;
|
|
++collideCalls;
|
|
++collideCalls;
|
|
- VoxelShapeArray resultArray = CACHE_COLLIDE.computeIfAbsent(baseArray, Function.identity());
|
|
|
|
|
|
+ ArrayVoxelShape resultArray = CACHE_COLLIDE.computeIfAbsent(baseArray, Function.identity());
|
|
replaceInternals(resultArray, baseArray);
|
|
replaceInternals(resultArray, baseArray);
|
|
return resultArray;
|
|
return resultArray;
|
|
}
|
|
}
|
|
@@ -85,13 +80,13 @@ public class BlockStateCacheImpl {
|
|
public static VoxelShape redirectFaceShape(VoxelShape shape, Direction face) {
|
|
public static VoxelShape redirectFaceShape(VoxelShape shape, Direction face) {
|
|
++projectCalls;
|
|
++projectCalls;
|
|
Pair<VoxelShape, VoxelShape[]> sides = CACHE_PROJECT.get(shape);
|
|
Pair<VoxelShape, VoxelShape[]> sides = CACHE_PROJECT.get(shape);
|
|
- if (sides.getFirst() instanceof VoxelShapeArray && shape instanceof VoxelShapeArray) {
|
|
|
|
- replaceInternals((VoxelShapeArray) sides.getFirst(), (VoxelShapeArray) shape);
|
|
|
|
|
|
+ if (sides.getFirst() instanceof ArrayVoxelShape && shape instanceof ArrayVoxelShape) {
|
|
|
|
+ replaceInternals((ArrayVoxelShape) sides.getFirst(), (ArrayVoxelShape) shape);
|
|
}
|
|
}
|
|
return sides.getSecond()[face.ordinal()];
|
|
return sides.getSecond()[face.ordinal()];
|
|
}
|
|
}
|
|
|
|
|
|
- public static void replaceInternals(VoxelShapeArray toKeep, VoxelShapeArray toReplace) {
|
|
|
|
|
|
+ public static void replaceInternals(ArrayVoxelShape toKeep, ArrayVoxelShape toReplace) {
|
|
if (toKeep == toReplace) {
|
|
if (toKeep == toReplace) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -101,15 +96,15 @@ public class BlockStateCacheImpl {
|
|
// that we can't do anything about shallow size and replace the internals with those used in the cache. This is
|
|
// that we can't do anything about shallow size and replace the internals with those used in the cache. This is
|
|
// not theoretically 100% safe since VSs can technically be modified after they are created, but handing out VSs
|
|
// not theoretically 100% safe since VSs can technically be modified after they are created, but handing out VSs
|
|
// that will be modified is unsafe in any case since a lot of vanilla code relies on VSs being immutable.
|
|
// that will be modified is unsafe in any case since a lot of vanilla code relies on VSs being immutable.
|
|
- access(toReplace).setXPoints(access(toKeep).getXPoints());
|
|
|
|
- access(toReplace).setYPoints(access(toKeep).getYPoints());
|
|
|
|
- access(toReplace).setZPoints(access(toKeep).getZPoints());
|
|
|
|
- accessVS(toReplace).setProjectionCache(accessVS(toKeep).getProjectionCache());
|
|
|
|
- accessVS(toReplace).setPart(accessVS(toKeep).getPart());
|
|
|
|
|
|
+ access(toReplace).setXs(access(toKeep).getXs());
|
|
|
|
+ access(toReplace).setYs(access(toKeep).getYs());
|
|
|
|
+ access(toReplace).setZs(access(toKeep).getZs());
|
|
|
|
+ accessVS(toReplace).setFaces(accessVS(toKeep).getFaces());
|
|
|
|
+ accessVS(toReplace).setShape(accessVS(toKeep).getShape());
|
|
}
|
|
}
|
|
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
@SuppressWarnings("ConstantConditions")
|
|
- private static VSArrayAccess access(VoxelShapeArray a) {
|
|
|
|
|
|
+ private static VSArrayAccess access(ArrayVoxelShape a) {
|
|
return (VSArrayAccess) (Object) a;
|
|
return (VSArrayAccess) (Object) a;
|
|
}
|
|
}
|
|
|
|
|