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.
This commit is contained in:
2026-04-23 14:55:24 +02:00
parent 99b9072b78
commit 3511493687
2 changed files with 24 additions and 2 deletions
@@ -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