From fdd1e22c3ee9ae498d638b6772bb8b15be82917c Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 20 Oct 2020 14:56:07 +0200 Subject: [PATCH] RAM-powered Minecarts - Fixed critical memory leak from minecart controller listeners - Made JEI heat conditions a little more readable --- .../compat/jei/category/BasinCategory.java | 4 +- .../CapabilityMinecartController.java | 50 +++++++++++++++++-- .../train/capability/MinecartController.java | 5 +- .../processing/HeatCondition.java | 2 +- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java index 3f82a09a3..41165913a 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java @@ -177,8 +177,8 @@ public class BasinCategory extends CreateRecipeCategory { AllGuiTextures heatBar = noHeat ? AllGuiTextures.JEI_NO_HEAT_BAR : AllGuiTextures.JEI_HEAT_BAR; heatBar.draw(4, 80); - Minecraft.getInstance().fontRenderer.drawStringWithShadow(Lang.translate(requiredHeat.getTranslationKey()), 9, - 85, requiredHeat.getColor()); + Minecraft.getInstance().fontRenderer.drawString(Lang.translate(requiredHeat.getTranslationKey()), 9, + 86, requiredHeat.getColor()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/CapabilityMinecartController.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/CapabilityMinecartController.java index 3120a64c6..19bd2ef7f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/CapabilityMinecartController.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/CapabilityMinecartController.java @@ -25,6 +25,7 @@ import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.INBT; import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -33,6 +34,7 @@ import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.common.util.NonNullConsumer; import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.world.ChunkEvent; @@ -45,6 +47,37 @@ public class CapabilityMinecartController implements ICapabilitySerializable> queuedAdditions; static WorldAttached> queuedUnloads; + /** + * This callback wrapper ensures that the listeners map in the controller + * capability only ever contains one instance + */ + public static class MinecartRemovalListener implements NonNullConsumer> { + + private World world; + private AbstractMinecartEntity cart; + + public MinecartRemovalListener(World world, AbstractMinecartEntity cart) { + this.world = world; + this.cart = cart; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MinecartRemovalListener; + } + + @Override + public int hashCode() { + return 100; + } + + @Override + public void accept(LazyOptional t) { + onCartRemoved(world, cart); + } + + } + static { loadedMinecartsByUUID = new WorldAttached<>(HashMap::new); loadedMinecartsWithCoupling = new WorldAttached<>(HashSet::new); @@ -66,10 +99,12 @@ public class CapabilityMinecartController implements ICapabilitySerializable capability = cart.getCapability(MINECART_CONTROLLER_CAPABILITY); MinecartController controller = capability.orElse(null); - capability.addListener(cap -> onCartRemoved(world, cart)); + capability.addListener(new MinecartRemovalListener(world, cart)); carts.put(uniqueID, controller); + capability.ifPresent(mc -> { if (mc.isLeadingCoupling()) cartsWithCoupling.add(uniqueID); @@ -128,14 +163,14 @@ public class CapabilityMinecartController implements ICapabilitySerializable { + if (capability.cap.isPresent()) + capability.cap.invalidate(); + }); queuedAdditions.get(entity.getEntityWorld()) .add((AbstractMinecartEntity) entity); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/MinecartController.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/MinecartController.java index bc3828495..7d0c87a91 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/MinecartController.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/capability/MinecartController.java @@ -62,9 +62,8 @@ public class MinecartController implements INBTSerializable { World world = getWorld(); if (needsEntryRefresh) { - List list = CapabilityMinecartController.queuedAdditions.get(world); - if (list != null) - list.add(cart); + CapabilityMinecartController.queuedAdditions.get(world).add(cart); + needsEntryRefresh = false; } stallData.forEach(opt -> opt.ifPresent(sd -> sd.tick(cart))); diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeatCondition.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeatCondition.java index 3e733f696..0f84596cd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeatCondition.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeatCondition.java @@ -7,7 +7,7 @@ import com.simibubi.create.foundation.utility.Lang; public enum HeatCondition { - NONE(0xffffff), HEATED(0xFFD528), SUPERHEATED(0xA2DFFF), + NONE(0xffffff), HEATED(0xE88300), SUPERHEATED(0x5C93E8), ;