From b8754617d4be6e600a729cadc42630eb56cb550e Mon Sep 17 00:00:00 2001 From: kayjaydee Date: Fri, 24 Apr 2026 17:11:54 +0200 Subject: [PATCH] refactor: clean GSD references + shrink comments in wand/ --- .../wand/GravityFlipWandInteraction.java | 45 ++----------------- .../gravityflip/wand/WandSelectionStore.java | 32 +++---------- .../wand/WandSelectionStoreTest.java | 6 +-- 3 files changed, 10 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/mythlane/gravityflip/wand/GravityFlipWandInteraction.java b/src/main/java/com/mythlane/gravityflip/wand/GravityFlipWandInteraction.java index 2fe4f7b..c76d5e1 100644 --- a/src/main/java/com/mythlane/gravityflip/wand/GravityFlipWandInteraction.java +++ b/src/main/java/com/mythlane/gravityflip/wand/GravityFlipWandInteraction.java @@ -15,38 +15,7 @@ import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import javax.annotation.Nonnull; import java.util.UUID; -/** - * Gravity Flip wand interaction — reads Primary / Secondary clicks and pushes - * the targeted block position into a {@link WandSelectionStore} keyed by the - * clicker's player UUID. - * - *

Binding : registered at {@code setup()} time via - * {@code getCodecRegistry(Interaction.CODEC).register("GravityFlipWand", …)} — - * same pattern as {@code ExitInstanceInteraction} (cf. 04-00 SPIKE-RESULT, - * Finding 3). The matching {@code "Type": "GravityFlipWand"} reference in - * {@code Items/gravityflip_wand.json} wires the click packet to this class. - * - *

One class for both click types : {@link #firstRun} receives the - * {@link InteractionType}. Primary → {@code setPos1}, Secondary → {@code setPos2}. - * Centralising both in one class keeps a single registration entry and a - * single CODEC — any other split would duplicate wiring for no gain. - * - *

Store injection : the Hytale CODEC instantiates interactions via a - * no-arg constructor, so we cannot inject the store through the constructor. - * Instead, {@link #bindStore(WandSelectionStore)} installs a {@code volatile} - * reference at plugin start. If the store is not bound (mis-wired plugin), - * {@link #firstRun} is a safe no-op — fail-silent. - * - *

Threat surface : - *

- */ +/** Wand interaction: Primary click sets pos1, Secondary click sets pos2 in the shared selection store. */ public final class GravityFlipWandInteraction extends SimpleInstantInteraction { @Nonnull @@ -60,19 +29,14 @@ public final class GravityFlipWandInteraction extends SimpleInstantInteraction { + "Secondary click sets pos2, for the clicker's selection.")) .build(); - /** - * Store shared by every instance of this interaction — injected at plugin - * start via {@link #bindStore}. Volatile so the writer thread ({@code setup()}) - * publishes a safe reference to the reader threads (interaction dispatch). - */ + // Volatile: writer (setup thread) must publish safely to reader threads (interaction dispatch). private static volatile WandSelectionStore STORE; - /** Wire the selection store before any click can be processed. Call once at {@code setup()}. */ + /** Wire the selection store before any click can be processed. */ public static void bindStore(WandSelectionStore store) { STORE = store; } - /** Required no-arg constructor used by the CODEC factory. */ public GravityFlipWandInteraction() { } @@ -82,7 +46,6 @@ public final class GravityFlipWandInteraction extends SimpleInstantInteraction { @Nonnull CooldownHandler cooldownHandler) { WandSelectionStore store = STORE; if (store == null) { - // Plugin mis-wired (bindStore never called). Silent no-op — don't crash the click. return; } @@ -94,7 +57,6 @@ public final class GravityFlipWandInteraction extends SimpleInstantInteraction { PlayerRef playerRef = commandBuffer.getComponent(entityRef, PlayerRef.getComponentType()); if (playerRef == null) { - // Clicker is not a player (mob, arrow, …) — ignore. return; } @@ -114,6 +76,5 @@ public final class GravityFlipWandInteraction extends SimpleInstantInteraction { playerRef.sendMessage(Message.raw( "[gravityflip] pos2 set: (%d, %d, %d)".formatted(bp.x, bp.y, bp.z))); } - // Any other InteractionType (Ability1, Pick, Equipped, …) is ignored. } } diff --git a/src/main/java/com/mythlane/gravityflip/wand/WandSelectionStore.java b/src/main/java/com/mythlane/gravityflip/wand/WandSelectionStore.java index 0b99f17..3a1ecf5 100644 --- a/src/main/java/com/mythlane/gravityflip/wand/WandSelectionStore.java +++ b/src/main/java/com/mythlane/gravityflip/wand/WandSelectionStore.java @@ -3,29 +3,12 @@ package com.mythlane.gravityflip.wand; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -/** - * Thread-safe per-player wand selection store. Tracks the two corner positions - * ({@code pos1} = Primary click, {@code pos2} = Secondary click) of each - * builder's current selection, keyed by player {@link UUID}. - * - *

Pure-data : no Hytale runtime dependency — same philosophy as - * {@code FallDamageGuard}. Testable with JUnit alone, reusable by future - * {@code /gravityflip define} command (Phase 04-02+) without runtime coupling. - * - *

Thread-safety : backed by a {@link ConcurrentHashMap} whose - * {@code compute(...)} mutations are atomic. Safe for concurrent - * {@link #setPos1}/{@link #setPos2} calls on the same UUID (STRIDE T-04-01-04). - * - *

Lifecycle : in-memory only — selections are discarded on plugin - * shutdown. Conscious design : a builder will not quit mid-{@code define}. - */ +/** Thread-safe per-player wand selection store (pos1/pos2 keyed by player UUID). */ public final class WandSelectionStore { /** Immutable holder for a (possibly partial) selection. */ public static final class Selection { - /** {@code {x,y,z}} of the Primary click, or {@code null} if unset. */ public final int[] pos1; - /** {@code {x,y,z}} of the Secondary click, or {@code null} if unset. */ public final int[] pos2; Selection(int[] pos1, int[] pos2) { @@ -43,7 +26,7 @@ public final class WandSelectionStore { private final ConcurrentHashMap byUuid = new ConcurrentHashMap<>(); - /** Record the Primary-click corner for {@code uuid}. Keeps any existing pos2. */ + /** Record the Primary-click corner for the given player. */ public void setPos1(UUID uuid, int x, int y, int z) { if (uuid == null) return; byUuid.compute(uuid, (k, prev) -> new Selection( @@ -51,7 +34,7 @@ public final class WandSelectionStore { prev != null ? prev.pos2 : null)); } - /** Record the Secondary-click corner for {@code uuid}. Keeps any existing pos1. */ + /** Record the Secondary-click corner for the given player. */ public void setPos2(UUID uuid, int x, int y, int z) { if (uuid == null) return; byUuid.compute(uuid, (k, prev) -> new Selection( @@ -59,23 +42,20 @@ public final class WandSelectionStore { new int[]{x, y, z})); } - /** - * Return the current selection for {@code uuid}. Never returns {@code null} : - * an unknown UUID yields a {@link Selection} with both corners {@code null}. - */ + /** Return the current selection for the given player (never null). */ public Selection get(UUID uuid) { if (uuid == null) return EMPTY; Selection s = byUuid.get(uuid); return s != null ? s : EMPTY; } - /** Forget the selection for {@code uuid} (e.g. after {@code /gravityflip define}). */ + /** Forget the selection for the given player. */ public void clear(UUID uuid) { if (uuid == null) return; byUuid.remove(uuid); } - /** Diagnostic : number of players with an in-flight selection. */ + /** Number of players with an in-flight selection. */ public int size() { return byUuid.size(); } diff --git a/src/test/java/com/mythlane/gravityflip/wand/WandSelectionStoreTest.java b/src/test/java/com/mythlane/gravityflip/wand/WandSelectionStoreTest.java index d9d7eae..c25ee8f 100644 --- a/src/test/java/com/mythlane/gravityflip/wand/WandSelectionStoreTest.java +++ b/src/test/java/com/mythlane/gravityflip/wand/WandSelectionStoreTest.java @@ -12,11 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -/** - * Pure-data tests for {@link WandSelectionStore} — no Hytale runtime dependency. - * Covers set/get per UUID, overwrite semantics, unknown UUID default, clear, - * and concurrent writes. - */ +/** Tests for {@link WandSelectionStore}: set/get per UUID, overwrite, clear, concurrency. */ class WandSelectionStoreTest { @Test