mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	Fix: Release monitor buffers on *client* thread
These buffers were being released on the server thread, causing the logical server in a single player session to crash just before shutting down. It seems the crash happened late enough to not cause world corruption issues, and so went unnoticed. It was however causing a memory leak when quitting/rejoining worlds, and it left the save file lock in limbo.
This commit is contained in:
		| @@ -20,6 +20,7 @@ import dan200.computercraft.client.render.TileEntityMonitorRenderer; | |||||||
| import dan200.computercraft.client.render.TileEntityTurtleRenderer; | import dan200.computercraft.client.render.TileEntityTurtleRenderer; | ||||||
| import dan200.computercraft.client.render.TurtleModelLoader; | import dan200.computercraft.client.render.TurtleModelLoader; | ||||||
| import dan200.computercraft.client.render.TurtlePlayerRenderer; | import dan200.computercraft.client.render.TurtlePlayerRenderer; | ||||||
|  | import dan200.computercraft.events.ClientUnloadWorldEvent; | ||||||
| import dan200.computercraft.shared.ComputerCraftRegistry; | import dan200.computercraft.shared.ComputerCraftRegistry; | ||||||
| import dan200.computercraft.shared.common.ContainerHeldItem; | import dan200.computercraft.shared.common.ContainerHeldItem; | ||||||
| import dan200.computercraft.shared.common.IColouredItem; | import dan200.computercraft.shared.common.IColouredItem; | ||||||
| @@ -47,14 +48,13 @@ import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegi | |||||||
| import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; | import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; | ||||||
| import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry; | import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry; | ||||||
| import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; | import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; | ||||||
| import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; |  | ||||||
| import net.fabricmc.fabric.mixin.object.builder.ModelPredicateProviderRegistrySpecificAccessor; | import net.fabricmc.fabric.mixin.object.builder.ModelPredicateProviderRegistrySpecificAccessor; | ||||||
|  |  | ||||||
| @Environment (EnvType.CLIENT) | @Environment (EnvType.CLIENT) | ||||||
| public final class ComputerCraftProxyClient implements ClientModInitializer { | public final class ComputerCraftProxyClient implements ClientModInitializer { | ||||||
|  |  | ||||||
|     public static void initEvents() { |     private static void initEvents() { | ||||||
|  |         ClientUnloadWorldEvent.EVENT.register( () -> ClientMonitor.destroyAll() ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -96,13 +96,9 @@ public final class ComputerCraftProxyClient implements ClientModInitializer { | |||||||
|                              () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED); |                              () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED); | ||||||
|         ClientRegistry.onItemColours(); |         ClientRegistry.onItemColours(); | ||||||
|  |  | ||||||
|         // TODO Verify this does things properly |         initEvents(); | ||||||
|         ServerWorldEvents.UNLOAD.register(((minecraftServer, serverWorld) -> { |  | ||||||
|             ClientMonitor.destroyAll(); |  | ||||||
|         })); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     // My IDE doesn't think so, but we do actually need these generics. |     // My IDE doesn't think so, but we do actually need these generics. | ||||||
|     private static void registerContainers() { |     private static void registerContainers() { | ||||||
|         ScreenRegistry.<ContainerComputer, GuiComputer<ContainerComputer>>register(ComputerCraftRegistry.ModContainers.COMPUTER, GuiComputer::create); |         ScreenRegistry.<ContainerComputer, GuiComputer<ContainerComputer>>register(ComputerCraftRegistry.ModContainers.COMPUTER, GuiComputer::create); | ||||||
| @@ -125,15 +121,4 @@ public final class ComputerCraftProxyClient implements ClientModInitializer { | |||||||
|             ModelPredicateProviderRegistrySpecificAccessor.callRegister(item.get(), id, getter); |             ModelPredicateProviderRegistrySpecificAccessor.callRegister(item.get(), id, getter); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //    @Mod.EventBusSubscriber (modid = ComputerCraft.MOD_ID, value = Dist.CLIENT) |  | ||||||
|     //    public static final class ForgeHandlers { |  | ||||||
|     //        @SubscribeEvent |  | ||||||
|     //        public static void onWorldUnload(WorldEvent.Unload event) { |  | ||||||
|     //            if (event.getWorld() |  | ||||||
|     //                     .isClient()) { |  | ||||||
|     //                ClientMonitor.destroyAll(); |  | ||||||
|     //            } |  | ||||||
|     //        } |  | ||||||
|     //    } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package dan200.computercraft.events; | ||||||
|  |  | ||||||
|  | import net.fabricmc.fabric.api.event.Event; | ||||||
|  | import net.fabricmc.fabric.api.event.EventFactory; | ||||||
|  |  | ||||||
|  | @FunctionalInterface | ||||||
|  | public interface ClientUnloadWorldEvent | ||||||
|  | { | ||||||
|  |     Event<ClientUnloadWorldEvent> EVENT = EventFactory.createArrayBacked( ClientUnloadWorldEvent.class, | ||||||
|  |         callbacks -> () -> { | ||||||
|  |             for( ClientUnloadWorldEvent callback : callbacks) { | ||||||
|  |                 callback.onClientUnloadWorld(); | ||||||
|  |             } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     void onClientUnloadWorld(); | ||||||
|  | } | ||||||
| @@ -7,6 +7,9 @@ | |||||||
| package dan200.computercraft.mixin; | package dan200.computercraft.mixin; | ||||||
| 
 | 
 | ||||||
| import dan200.computercraft.client.FrameInfo; | import dan200.computercraft.client.FrameInfo; | ||||||
|  | import dan200.computercraft.events.ClientUnloadWorldEvent; | ||||||
|  | import net.minecraft.client.gui.screen.Screen; | ||||||
|  | import net.minecraft.client.world.ClientWorld; | ||||||
| import org.spongepowered.asm.mixin.Mixin; | import org.spongepowered.asm.mixin.Mixin; | ||||||
| import org.spongepowered.asm.mixin.injection.At; | import org.spongepowered.asm.mixin.injection.At; | ||||||
| import org.spongepowered.asm.mixin.injection.Inject; | import org.spongepowered.asm.mixin.injection.Inject; | ||||||
| @@ -15,9 +18,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | |||||||
| import net.minecraft.client.MinecraftClient; | import net.minecraft.client.MinecraftClient; | ||||||
| 
 | 
 | ||||||
| @Mixin (MinecraftClient.class) | @Mixin (MinecraftClient.class) | ||||||
| public abstract class MixinMinecraftGame { | public abstract class MixinMinecraftClient | ||||||
|  | { | ||||||
|     @Inject (method = "render", at = @At ("HEAD")) |     @Inject (method = "render", at = @At ("HEAD")) | ||||||
|     private void onRender(CallbackInfo info) { |     private void onRender(CallbackInfo info) { | ||||||
|         FrameInfo.onRenderFrame(); |         FrameInfo.onRenderFrame(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At ("RETURN")) | ||||||
|  |     private void disconnectAfter(Screen screen, CallbackInfo info) { | ||||||
|  |         ClientUnloadWorldEvent.EVENT.invoker().onClientUnloadWorld(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Inject(method = "joinWorld", at = @At("RETURN")) | ||||||
|  |     private void joinWorldAfter(ClientWorld world, CallbackInfo info) { | ||||||
|  |         ClientUnloadWorldEvent.EVENT.invoker().onClientUnloadWorld(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -20,7 +20,7 @@ | |||||||
|         "HeldItemRendererAccess", |         "HeldItemRendererAccess", | ||||||
|         "MixinHeldItemRenderer", |         "MixinHeldItemRenderer", | ||||||
|         "MixinItemFrameEntityRenderer", |         "MixinItemFrameEntityRenderer", | ||||||
|         "MixinMinecraftGame", |         "MixinMinecraftClient", | ||||||
|         "MixinScreen", |         "MixinScreen", | ||||||
|         "MixinWorldRenderer" |         "MixinWorldRenderer" | ||||||
|     ], |     ], | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ToadDev
					ToadDev