From 3511493687a16c02eafe298007d37b17165ad712 Mon Sep 17 00:00:00 2001 From: kayjaydee Date: Thu, 23 Apr 2026 14:55:24 +0200 Subject: [PATCH] feat(03-05): cable RegionVisualizer dans RegionTickLoop + shutdown clearAll (Task 3) - RegionTickLoop: nouveau ctor 4-arg (registry, gravityApplier, regionVisualizer, errorHandler). Les ctors 2-arg et 3-arg existants delegent (back-compat tests). Tick appelle regionVisualizer.visualize(w, snapshot) apres gravityApplier.apply() avec null-safe gate (meme pattern que gravityApplier). - GravityFlipPlugin.start(): construit RegionVisualizer avec errorHandler log WARN, le passe au tickLoop. - GravityFlipPlugin.shutdown(): appelle regionVisualizer.clearAll(world) AVANT tickLoop.stop() (si Universe encore vivante), emet ClearDebugShapes a tous les PlayerRefs. Si universe null, fallback TTL expiration. - Aucun nouveau scheduler/thread cree. --- .../com/mythlane/gravityflip/GravityFlipPlugin.java | 13 ++++++++++++- .../mythlane/gravityflip/tick/RegionTickLoop.java | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mythlane/gravityflip/GravityFlipPlugin.java b/src/main/java/com/mythlane/gravityflip/GravityFlipPlugin.java index 591bfb8..fdfd486 100644 --- a/src/main/java/com/mythlane/gravityflip/GravityFlipPlugin.java +++ b/src/main/java/com/mythlane/gravityflip/GravityFlipPlugin.java @@ -11,6 +11,7 @@ import com.mythlane.gravityflip.physics.FallDamageSuppressorSystem; import com.mythlane.gravityflip.physics.GravityApplier; import com.mythlane.gravityflip.region.RegionRegistry; import com.mythlane.gravityflip.tick.RegionTickLoop; +import com.mythlane.gravityflip.viz.RegionVisualizer; import java.util.concurrent.ScheduledFuture; import java.util.logging.Level; @@ -41,6 +42,7 @@ public class GravityFlipPlugin extends JavaPlugin { private RegionTickLoop tickLoop; private GravityApplier gravityApplier; private FallDamageGuard fallDamageGuard; + private RegionVisualizer regionVisualizer; public GravityFlipPlugin(JavaPluginInit init) { super(init); @@ -77,7 +79,9 @@ public class GravityFlipPlugin extends JavaPlugin { th -> getLogger().at(Level.WARNING).withCause(th).log("gravityApply failed"), msg -> getLogger().at(Level.INFO).log("%s", msg), fallDamageGuard); - this.tickLoop = new RegionTickLoop(registry, gravityApplier, th -> + this.regionVisualizer = new RegionVisualizer( + th -> getLogger().at(Level.WARNING).withCause(th).log("regionVisualize failed")); + this.tickLoop = new RegionTickLoop(registry, gravityApplier, regionVisualizer, th -> getLogger().at(Level.WARNING).withCause(th).log("detectTick failed")); // Lazy world resolution — see setup() comment. @@ -103,6 +107,13 @@ public class GravityFlipPlugin extends JavaPlugin { @Override protected void shutdown() { + // Plan 03-05 : clear des debug shapes cote clients AVANT tickLoop.stop(). + // Si l'Universe est deja fermee, world==null => shapes expireront via TTL (acceptable). + if (regionVisualizer != null) { + Universe u = Universe.get(); + World w = (u == null) ? null : u.getDefaultWorld(); + if (w != null) regionVisualizer.clearAll(w); + } // Stop the detector BEFORE super.shutdown() so no tick races plugin teardown. if (tickLoop != null) tickLoop.stop(); // No auto-save contract: any mutation made during the session must already diff --git a/src/main/java/com/mythlane/gravityflip/tick/RegionTickLoop.java b/src/main/java/com/mythlane/gravityflip/tick/RegionTickLoop.java index aa8e748..a584607 100644 --- a/src/main/java/com/mythlane/gravityflip/tick/RegionTickLoop.java +++ b/src/main/java/com/mythlane/gravityflip/tick/RegionTickLoop.java @@ -3,6 +3,7 @@ package com.mythlane.gravityflip.tick; import com.hypixel.hytale.server.core.universe.world.World; import com.mythlane.gravityflip.physics.GravityApplier; import com.mythlane.gravityflip.region.RegionRegistry; +import com.mythlane.gravityflip.viz.RegionVisualizer; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -34,14 +35,21 @@ public final class RegionTickLoop { private final Consumer errorHandler; private final RegionRegistry registry; private final GravityApplier gravityApplier; + private final RegionVisualizer regionVisualizer; public RegionTickLoop(RegionRegistry registry, Consumer errorHandler) { - this(registry, null, errorHandler); + this(registry, null, null, errorHandler); } public RegionTickLoop(RegionRegistry registry, GravityApplier gravityApplier, Consumer errorHandler) { + this(registry, gravityApplier, null, errorHandler); + } + + public RegionTickLoop(RegionRegistry registry, GravityApplier gravityApplier, + RegionVisualizer regionVisualizer, Consumer errorHandler) { this.registry = registry; this.gravityApplier = gravityApplier; + this.regionVisualizer = regionVisualizer; this.errorHandler = errorHandler == null ? t -> {} : errorHandler; this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { Thread t = new Thread(r, "GravityFlip-Detect"); @@ -75,6 +83,9 @@ public final class RegionTickLoop { if (gravityApplier != null) { gravityApplier.apply(w, registry.currentSnapshot(w)); } + if (regionVisualizer != null) { + regionVisualizer.visualize(w, registry.currentSnapshot(w)); + } }; scheduleGuarded(initialDelayMs, tick); }