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:
@@ -11,6 +11,7 @@ import com.mythlane.gravityflip.physics.FallDamageSuppressorSystem;
|
|||||||
import com.mythlane.gravityflip.physics.GravityApplier;
|
import com.mythlane.gravityflip.physics.GravityApplier;
|
||||||
import com.mythlane.gravityflip.region.RegionRegistry;
|
import com.mythlane.gravityflip.region.RegionRegistry;
|
||||||
import com.mythlane.gravityflip.tick.RegionTickLoop;
|
import com.mythlane.gravityflip.tick.RegionTickLoop;
|
||||||
|
import com.mythlane.gravityflip.viz.RegionVisualizer;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -41,6 +42,7 @@ public class GravityFlipPlugin extends JavaPlugin {
|
|||||||
private RegionTickLoop tickLoop;
|
private RegionTickLoop tickLoop;
|
||||||
private GravityApplier gravityApplier;
|
private GravityApplier gravityApplier;
|
||||||
private FallDamageGuard fallDamageGuard;
|
private FallDamageGuard fallDamageGuard;
|
||||||
|
private RegionVisualizer regionVisualizer;
|
||||||
|
|
||||||
public GravityFlipPlugin(JavaPluginInit init) {
|
public GravityFlipPlugin(JavaPluginInit init) {
|
||||||
super(init);
|
super(init);
|
||||||
@@ -77,7 +79,9 @@ public class GravityFlipPlugin extends JavaPlugin {
|
|||||||
th -> getLogger().at(Level.WARNING).withCause(th).log("gravityApply failed"),
|
th -> getLogger().at(Level.WARNING).withCause(th).log("gravityApply failed"),
|
||||||
msg -> getLogger().at(Level.INFO).log("%s", msg),
|
msg -> getLogger().at(Level.INFO).log("%s", msg),
|
||||||
fallDamageGuard);
|
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"));
|
getLogger().at(Level.WARNING).withCause(th).log("detectTick failed"));
|
||||||
|
|
||||||
// Lazy world resolution — see setup() comment.
|
// Lazy world resolution — see setup() comment.
|
||||||
@@ -103,6 +107,13 @@ public class GravityFlipPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutdown() {
|
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.
|
// Stop the detector BEFORE super.shutdown() so no tick races plugin teardown.
|
||||||
if (tickLoop != null) tickLoop.stop();
|
if (tickLoop != null) tickLoop.stop();
|
||||||
// No auto-save contract: any mutation made during the session must already
|
// No auto-save contract: any mutation made during the session must already
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.mythlane.gravityflip.tick;
|
|||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
import com.mythlane.gravityflip.physics.GravityApplier;
|
import com.mythlane.gravityflip.physics.GravityApplier;
|
||||||
import com.mythlane.gravityflip.region.RegionRegistry;
|
import com.mythlane.gravityflip.region.RegionRegistry;
|
||||||
|
import com.mythlane.gravityflip.viz.RegionVisualizer;
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
@@ -34,14 +35,21 @@ public final class RegionTickLoop {
|
|||||||
private final Consumer<Throwable> errorHandler;
|
private final Consumer<Throwable> errorHandler;
|
||||||
private final RegionRegistry registry;
|
private final RegionRegistry registry;
|
||||||
private final GravityApplier gravityApplier;
|
private final GravityApplier gravityApplier;
|
||||||
|
private final RegionVisualizer regionVisualizer;
|
||||||
|
|
||||||
public RegionTickLoop(RegionRegistry registry, Consumer<Throwable> errorHandler) {
|
public RegionTickLoop(RegionRegistry registry, Consumer<Throwable> errorHandler) {
|
||||||
this(registry, null, errorHandler);
|
this(registry, null, null, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionTickLoop(RegionRegistry registry, GravityApplier gravityApplier, Consumer<Throwable> errorHandler) {
|
public RegionTickLoop(RegionRegistry registry, GravityApplier gravityApplier, Consumer<Throwable> errorHandler) {
|
||||||
|
this(registry, gravityApplier, null, errorHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionTickLoop(RegionRegistry registry, GravityApplier gravityApplier,
|
||||||
|
RegionVisualizer regionVisualizer, Consumer<Throwable> errorHandler) {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.gravityApplier = gravityApplier;
|
this.gravityApplier = gravityApplier;
|
||||||
|
this.regionVisualizer = regionVisualizer;
|
||||||
this.errorHandler = errorHandler == null ? t -> {} : errorHandler;
|
this.errorHandler = errorHandler == null ? t -> {} : errorHandler;
|
||||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
|
this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
|
||||||
Thread t = new Thread(r, "GravityFlip-Detect");
|
Thread t = new Thread(r, "GravityFlip-Detect");
|
||||||
@@ -75,6 +83,9 @@ public final class RegionTickLoop {
|
|||||||
if (gravityApplier != null) {
|
if (gravityApplier != null) {
|
||||||
gravityApplier.apply(w, registry.currentSnapshot(w));
|
gravityApplier.apply(w, registry.currentSnapshot(w));
|
||||||
}
|
}
|
||||||
|
if (regionVisualizer != null) {
|
||||||
|
regionVisualizer.visualize(w, registry.currentSnapshot(w));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
scheduleGuarded(initialDelayMs, tick);
|
scheduleGuarded(initialDelayMs, tick);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user