From 1f117b7c4733c823a7b6b6032bd0433a6c4e214c Mon Sep 17 00:00:00 2001 From: ToadDev <748280+Toad-Dev@users.noreply.github.com> Date: Thu, 27 May 2021 19:32:08 -0700 Subject: [PATCH] Fix: Inform block entities when chunk is unloaded. Forge's ITileEntity interface adds a onChunkUnloaded handler method into block entities. The fabric port doesn't have a re-implementation of this feature, which meant TileMonitors weren't releasing their buffers when unloaded. This commit adds that handler method back into TileGeneric, which all CC block entities inherit from. Handler logic for the four block entities that use this feature were copied over from the forge repo. --- .../proxy/ComputerCraftProxyClient.java | 8 ++++++ .../shared/common/TileGeneric.java | 3 +++ .../computer/blocks/TileComputerBase.java | 6 +++++ .../peripheral/modem/wired/TileCable.java | 7 +++++ .../modem/wired/TileWiredModemFull.java | 7 +++++ .../peripheral/monitor/TileMonitor.java | 26 ++++++++++++------- .../proxy/ComputerCraftProxyCommon.java | 8 ++++++ 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index 9983e6a08..da9b965b1 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -24,6 +24,7 @@ import dan200.computercraft.events.ClientUnloadWorldEvent; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.common.IColouredItem; +import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.computer.inventory.ContainerComputer; import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive; @@ -33,6 +34,7 @@ import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; import net.minecraft.client.item.ModelPredicateProvider; import net.minecraft.client.render.RenderLayer; import net.minecraft.item.Item; @@ -54,6 +56,12 @@ import net.fabricmc.fabric.mixin.object.builder.ModelPredicateProviderRegistrySp public final class ComputerCraftProxyClient implements ClientModInitializer { private static void initEvents() { + ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register( ( blockEntity, world ) -> { + if(blockEntity instanceof TileGeneric ) { + ((TileGeneric)blockEntity).onChunkUnloaded(); + } + }); + ClientUnloadWorldEvent.EVENT.register( () -> ClientMonitor.destroyAll() ); } diff --git a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java index 0514bbf61..a2d37e532 100644 --- a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java +++ b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java @@ -28,6 +28,9 @@ public abstract class TileGeneric extends BlockEntity implements BlockEntityClie public void destroy() { } + public void onChunkUnloaded() { + } + public final void updateBlock() { this.markDirty(); BlockPos pos = this.getPos(); diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java index 0aee4362b..c12d44bc4 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java @@ -77,6 +77,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT } } + @Override + public void onChunkUnloaded() + { + unload(); + } + protected void unload() { if (this.m_instanceID >= 0) { if (!this.getWorld().isClient) { diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java index e267c601d..9b23eaed7 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java @@ -83,6 +83,13 @@ public class TileCable extends TileGeneric implements IPeripheralTile { } } + @Override + public void onChunkUnloaded() + { + super.onChunkUnloaded(); + onRemove(); + } + private void onRemove() { if (this.world == null || !this.world.isClient) { this.m_node.remove(); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java index 47502b2dc..d258877ca 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java @@ -74,6 +74,13 @@ public class TileWiredModemFull extends TileGeneric implements IPeripheralTile { super.destroy(); } + @Override + public void onChunkUnloaded() + { + super.onChunkUnloaded(); + doRemove(); + } + private void doRemove() { if (this.world == null || !this.world.isClient) { this.m_node.remove(); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java index cddd4e3f5..d7331f5df 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java @@ -79,6 +79,23 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } } + @Override + public void markRemoved() { + super.markRemoved(); + if (this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0) { + this.m_clientMonitor.destroy(); + } + } + + @Override + public void onChunkUnloaded() { + super.onChunkUnloaded(); + if (this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0) { + this.m_clientMonitor.destroy(); + } + this.m_clientMonitor = null; + } + @Nonnull @Override public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { @@ -262,15 +279,6 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { return ComputerCraft.monitorDistanceSq; } - @Override - @Environment (EnvType.CLIENT) - public void markRemoved() { - super.markRemoved(); - if (this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0) { - this.m_clientMonitor.destroy(); - } - } - // Sizing and placement stuff @Override diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java index f7db6fe8a..325f82904 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java @@ -17,6 +17,7 @@ import dan200.computercraft.shared.TurtlePermissions; import dan200.computercraft.shared.command.CommandComputerCraft; import dan200.computercraft.shared.command.arguments.ArgumentSerializers; import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider; +import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.data.BlockNamedEntityLootCondition; import dan200.computercraft.shared.data.HasComputerIdLootCondition; import dan200.computercraft.shared.data.PlayerCreativeLootCondition; @@ -28,6 +29,7 @@ import dan200.computercraft.shared.turtle.FurnaceRefuelHandler; import dan200.computercraft.shared.turtle.SignInspectHandler; import dan200.computercraft.shared.util.TickScheduler; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.item.Item; @@ -106,6 +108,12 @@ public final class ComputerCraftProxyCommon { ComputerCraftProxyCommon.server = null; }); + ServerBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register( ( blockEntity, world ) -> { + if(blockEntity instanceof TileGeneric ) { + ((TileGeneric)blockEntity).onChunkUnloaded(); + } + }); + TurtleEvent.EVENT_BUS.register(FurnaceRefuelHandler.INSTANCE); TurtleEvent.EVENT_BUS.register(new TurtlePermissions()); TurtleEvent.EVENT_BUS.register(new SignInspectHandler());