From ab785a090698e6972caac95691393428c6f8370b Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 3 Oct 2023 18:20:44 +0100 Subject: [PATCH] Fix monitors being warped after a resize Oh, this was a really nasty bug to reproduce. I'm not sure why - it's very simple - I guess I've only just seen screenshots of it, and never sat down to try myself. Reminder to actually report your bugs folks! In this case: 1. Place down three down three monitors and then a computer. 2. Display something on the monitor (monitor left paint a) is my go-to. 3. Break the middle monitor. We'd expect the left most monitor to be cleared, however it actually preserves the monitor contents, resizing (and skewing it) to fit on its new size! This is because we clear the server monitor, but never sync that over to the client, so the client monitor retains the old contents. To fix that, instead of nulling out the server monitor, we null out the underlying Terminal. This causes the change to be synced, fixing the bug. --- .../peripheral/monitor/MonitorBlockEntity.java | 14 ++++++++------ .../shared/peripheral/monitor/ServerMonitor.java | 6 ++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java index 3f89c17cd..fbd451bf5 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java @@ -349,13 +349,15 @@ void resize(int width, int height) { // Either delete the current monitor or sync a new one. if (needsTerminal) { if (serverMonitor == null) serverMonitor = new ServerMonitor(advanced, this); - } else { - serverMonitor = null; - } - // Update the terminal's width and height and rebuild it. This ensures the monitor - // is consistent when syncing it to other monitors. - if (serverMonitor != null) serverMonitor.rebuild(); + // Update the terminal's width and height and rebuild it. This ensures the monitor + // is consistent when syncing it to other monitors. + serverMonitor.rebuild(); + } else { + // Remove the terminal from the serverMonitor, but keep it around - this ensures that we sync + // the (now blank) monitor to the client. + if (serverMonitor != null) serverMonitor.reset(); + } // Update the other monitors, setting coordinates, dimensions and the server terminal var pos = getBlockPos(); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java index 7de81be87..b7d43b8db 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java @@ -55,6 +55,12 @@ synchronized void rebuild() { } } + synchronized void reset() { + if (terminal == null) return; + terminal = null; + markChanged(); + } + private void markChanged() { if (!changed.getAndSet(true)) TickScheduler.schedule(origin.tickToken); }