Skip to content

Commit 9496be1

Browse files
committed
Fix usage of FluidStack as keys in maps or sets not properly comparing
1 parent 531f779 commit 9496be1

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

src/main/java/mekanism/client/render/tileentity/RenderFluidTank.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import com.mojang.blaze3d.vertex.VertexConsumer;
55
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
66
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
7-
import java.util.HashMap;
7+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
88
import java.util.Map;
99
import mekanism.api.annotations.NothingNullByDefault;
1010
import mekanism.client.render.MekanismRenderer;
@@ -13,6 +13,7 @@
1313
import mekanism.client.render.ModelRenderer;
1414
import mekanism.client.render.RenderResizableCuboid.FaceDisplay;
1515
import mekanism.common.base.ProfilerConstants;
16+
import mekanism.common.lib.collection.FluidHashStrategy;
1617
import mekanism.common.tile.TileEntityFluidTank;
1718
import mekanism.common.util.MekanismUtils;
1819
import net.minecraft.client.renderer.MultiBufferSource;
@@ -26,8 +27,8 @@
2627
@NothingNullByDefault
2728
public class RenderFluidTank extends MekanismTileEntityRenderer<TileEntityFluidTank> {
2829

29-
private static final Map<FluidStack, Int2ObjectMap<Model3D>> cachedCenterFluids = new HashMap<>();
30-
private static final Map<FluidStack, Int2ObjectMap<Model3D>> cachedValveFluids = new HashMap<>();
30+
private static final Map<FluidStack, Int2ObjectMap<Model3D>> cachedCenterFluids = new Object2ObjectOpenCustomHashMap<>(FluidHashStrategy.INSTANCE);
31+
private static final Map<FluidStack, Int2ObjectMap<Model3D>> cachedValveFluids = new Object2ObjectOpenCustomHashMap<>(FluidHashStrategy.INSTANCE);
3132

3233
private static final int stages = 1_400;
3334

src/main/java/mekanism/client/render/transmitter/RenderMechanicalPipe.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
66
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
77
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
8+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
89
import java.util.ArrayList;
9-
import java.util.HashMap;
1010
import java.util.List;
1111
import java.util.Locale;
1212
import java.util.Map;
@@ -20,6 +20,7 @@
2020
import mekanism.common.base.ProfilerConstants;
2121
import mekanism.common.content.network.FluidNetwork;
2222
import mekanism.common.content.network.transmitter.MechanicalPipe;
23+
import mekanism.common.lib.collection.FluidHashStrategy;
2324
import mekanism.common.lib.transmitter.ConnectionType;
2425
import mekanism.common.tile.transmitter.TileEntityMechanicalPipe;
2526
import mekanism.common.util.EnumUtils;
@@ -43,7 +44,6 @@ public class RenderMechanicalPipe extends RenderTransmitterBase<TileEntityMechan
4344
private static final float offset = 0.02F;
4445
//Note: this is basically used as an enum map (Direction), but null key is possible, which EnumMap doesn't support.
4546
// 6 is used for null side, and 7 is used for null side but flowing vertically
46-
//TODO - 1.20.5: Look at all maps and sets that use FluidStacks as keys as they no longer are hashed
4747
private static final Int2ObjectMap<Map<FluidStack, Int2ObjectMap<Model3D>>> cachedLiquids = new Int2ObjectArrayMap<>(8);
4848

4949
public RenderMechanicalPipe(BlockEntityRendererProvider.Context context) {
@@ -142,7 +142,7 @@ private Model3D getModel(@Nullable Direction side, FluidStack fluid, int stage,
142142
} else {
143143
sideOrdinal = side.ordinal();
144144
}
145-
Int2ObjectMap<Model3D> modelMap = cachedLiquids.computeIfAbsent(sideOrdinal, s -> new HashMap<>())
145+
Int2ObjectMap<Model3D> modelMap = cachedLiquids.computeIfAbsent(sideOrdinal, s -> new Object2ObjectOpenCustomHashMap<>(FluidHashStrategy.INSTANCE))
146146
.computeIfAbsent(fluid, f -> new Int2ObjectOpenHashMap<>());
147147
Model3D model = modelMap.get(stage);
148148
if (model == null) {

src/main/java/mekanism/common/inventory/slot/IFluidHandlerSlot.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
package mekanism.common.inventory.slot;
22

3-
import java.util.HashMap;
3+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
4+
import java.util.Collection;
45
import java.util.Map;
5-
import java.util.Set;
66
import mekanism.api.Action;
77
import mekanism.api.AutomationType;
88
import mekanism.api.fluid.IExtendedFluidTank;
99
import mekanism.api.inventory.IInventorySlot;
1010
import mekanism.common.capabilities.Capabilities;
11+
import mekanism.common.lib.collection.FluidHashStrategy;
1112
import mekanism.common.tile.interfaces.IFluidContainerManager.ContainerEditMode;
1213
import mekanism.common.util.MekanismUtils;
1314
import net.minecraft.world.item.ItemStack;
1415
import net.neoforged.neoforge.fluids.FluidStack;
1516
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
1617
import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
1718
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
18-
import net.neoforged.neoforge.items.ItemHandlerHelper;
1919

2020
public interface IFluidHandlerSlot extends IInventorySlot {
2121

@@ -88,9 +88,8 @@ default void fillTank(IInventorySlot outputSlot) {
8888
//If we have more than one tank in our item then handle calculating the different drains that will occur for filling our fluid handler
8989
// We start by gathering all the fluids in the item that we are able to drain and are valid for the tank,
9090
// combining same fluid types into a single fluid stack
91-
Set<FluidStack> knownFluids = gatherKnownFluids(itemFluidHandler, itemTanks);
9291
//If we found any fluids that we can drain, attempt to drain them into our item
93-
for (FluidStack knownFluid : knownFluids) {
92+
for (FluidStack knownFluid : gatherKnownFluids(itemFluidHandler, itemTanks)) {
9493
if (drainItemAndMove(outputSlot, knownFluid) && isEmpty()) {
9594
//If we moved the item after draining it and we now don't have an item to try and fill
9695
// then just exit instead of checking the other types of fluids
@@ -261,7 +260,7 @@ default boolean fillTank() {
261260
//If we have more than one tank in our item then handle calculating the different drains that will occur for filling our fluid handler
262261
// We start by gathering all the fluids in the item that we are able to drain and are valid for the tank,
263262
// combining same fluid types into a single fluid stack
264-
Set<FluidStack> knownFluids = gatherKnownFluids(itemFluidHandler, tanks);
263+
Collection<FluidStack> knownFluids = gatherKnownFluids(itemFluidHandler, tanks);
265264
if (!knownFluids.isEmpty()) {
266265
//If we found any fluids that we can drain, attempt to drain them into our item
267266
boolean changed = false;
@@ -282,8 +281,8 @@ default boolean fillTank() {
282281
return false;
283282
}
284283

285-
private Set<FluidStack> gatherKnownFluids(IFluidHandlerItem itemFluidHandler, int tanks) {
286-
Map<FluidStack, FluidStack> knownFluids = new HashMap<>();
284+
private Collection<FluidStack> gatherKnownFluids(IFluidHandlerItem itemFluidHandler, int tanks) {
285+
Map<FluidStack, FluidStack> knownFluids = new Object2ObjectOpenCustomHashMap<>(FluidHashStrategy.INSTANCE);
287286
for (int tank = 0; tank < tanks; tank++) {
288287
FluidStack fluidInItem = itemFluidHandler.getFluidInTank(tank);
289288
if (!fluidInItem.isEmpty()) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package mekanism.common.lib.collection;
2+
3+
import it.unimi.dsi.fastutil.Hash.Strategy;
4+
import net.neoforged.neoforge.fluids.FluidStack;
5+
6+
public class FluidHashStrategy implements Strategy<FluidStack> {
7+
8+
public static final FluidHashStrategy INSTANCE = new FluidHashStrategy();
9+
10+
private FluidHashStrategy() {
11+
}
12+
13+
@Override
14+
public int hashCode(FluidStack stack) {
15+
return FluidStack.hashFluidAndComponents(stack);
16+
}
17+
18+
@Override
19+
public boolean equals(FluidStack a, FluidStack b) {
20+
return FluidStack.isSameFluidSameComponents(a, b);
21+
}
22+
}

0 commit comments

Comments
 (0)