Class NxAdapter

java.lang.Object
app.l2nx.gs.adapter.core.NxAdapter

public final class NxAdapter extends Object
Adapter entry point — singleton-style facade exposing the lifecycle to the host JVM.

Usage:

   NxAdapter.onStateChange(s -> log.info("adapter state: {}", s)); // optional
   NxAdapter.start();                                                 // fire-and-forget
 

start() never propagates an exception to the host JVM. Any failure during config resolution is caught here, logged via NxLog, and reflected in state() as AdapterState.FAILED.

  • Method Details

    • onStateChange

      public static void onStateChange(Consumer<AdapterState> callback)
      Register a state-transition callback. May be called before or after start(). Replaces any previously registered callback.
    • hostExecutor

      public static void hostExecutor(Executor executor)
      Register the host's game-side Executor for command-handler ctx.host().sync(...) / .async(...) hops. MUST be called before start() when commandsTopic is configured.

      Typical host wiring:

         NxAdapter.hostExecutor(task -> ThreadPoolManager.getInstance().executeGeneral(task));
         NxAdapter.start();
       

      Calling without an executor when commandsTopic is configured surfaces as a startup WARN; the first ctx.host().sync(...) call from any handler then throws IllegalStateException. Read-only handlers (no game state mutation) keep working unaffected.

      May be called more than once — last write wins. Replacing while the adapter is already running is permitted but discouraged; the new executor takes effect on the next ctx.host() call.

    • state

      public static AdapterState state()
      Current adapter state.
    • start

      public static NxAdapter start()
      Resolve config and (if enabled) initiate the connect flow on a daemon scheduler. Non-blocking — returns immediately. Never throws into the host JVM.
    • shutdown

      public void shutdown()
      Idempotent shutdown — cancel heartbeat, cancel connect scheduler, shut down the Kafka client if alive, and transition to AdapterState.CLOSED. Safe to call from any thread; safe to call repeatedly.

      Blocking-idempotent: a concurrent second caller does not return early — it waits until the in-flight shutdown completes. This lets a host drive shutdown synchronously before a hard Runtime.halt() (which skips the auto-registered JVM hook) and rely on the event queue being drained and the Kafka producer flushed by the time this returns, even if the auto hook is running the shutdown on another thread.