mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-29 16:47:56 +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