Fix 2 (Gitea #12): gauge tree survives the in-session mech re-stream

The pre-launch host drop/rejoin re-stream re-creates every mech at mission
launch; the LOBBY-built gauge tree kept attribute pointers into the freed
first-stream mechs, every widget Execute AV'd, and the BT_DEV_GAUGES SEH
guard (Gauge::GuardedExecute, GAUGE.cpp:618) disabled each one PERMANENTLY
(rate=0, no rebind) -- the frozen dev-gauges window of incident #12.  The
authentic engine flow only tears the tree down at mission transitions
(Application::Shutdown -> gaugeRenderer->Shutdown() -> ShutdownImplementation
-> Remove(0), APP.cpp:787 / GAUGREND.cpp:3264); the re-stream bypassed it.

Fix: BTL4GaugeRenderer::TearDownForViewpointRestream() performs the
ENTITY-BOUND half of that same ShutdownImplementation sequence, in order
(gaugeAlarmManager->RemoveAllAlarms() -> Remove(0) -> moving/static entity
grid Clear), keeping the mission-scoped state (warehouse, graphics ports,
interpreter, controls-owned L4Lamps -- RemoveAllLamps would delete them
behind the buttonGroup's &lamp->automaticValue registrations).  Called from
BTL4Application::MakeViewpointEntity before ConfigureForModel("Init") on any
viewpoint RE-make -- that handler runs once per stream (the incident log's
[ctrlmap] installing x2) -- so the tree rebuilds bound to the NEW mech via
the renderer's existing lazy build.  Sentinel: "[gauge] viewpoint re-stream:
tearing the gauge tree down for rebuild".

Verified with the 2-instance relay harness (port 15600, MP_RELAY.EGG,
the incident sequence): join A (dev gauges) + B, kill B by exact PID at
WAITING FOR OPERATOR LAUNCH, rejoin B, operator launch.  Pod A re-streamed
(2x ctrlmap install, 4x zonebuild), logged the sentinel, and post-launch the
docked composite is fully live (mission clock/heading/radar advancing between
BT_SHOT frames) with ZERO [gauge-fault] DISABLED lines (the incident had 11).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-19 23:30:43 -05:00
co-authored by Claude Fable 5
parent 2edde29671
commit 0d032029a0
5 changed files with 124 additions and 23 deletions
+25
View File
@@ -697,6 +697,31 @@ BTL4Application::SharedData
<< (int)(gauge_renderer != NULL) << " -> ConfigureForModel(Init)\n" << std::flush;
if (gauge_renderer != NULL)
{
//
// GAUGE-TREE SURVIVAL ACROSS THE IN-SESSION RE-STREAM (Gitea #12 fix):
// when the mechs are RE-CREATED pre-launch (host drop/rejoin re-stream),
// this handler runs AGAIN for the new viewpoint mech -- but the
// lobby-built gauge tree still holds attribute pointers into the FREED
// first-stream mech; every widget then faults and the BT_DEV_GAUGES SEH
// guard disables it permanently (GAUGE.cpp:618) = the frozen dev-gauges
// window. The engine's own transition path is the Shutdown teardown
// (Application::Shutdown -> gaugeRenderer->Shutdown() -> Remove(0),
// APP.cpp:787 / GAUGREND.cpp:3264) followed by a lazy rebuild; the
// re-stream bypasses it. So: tear the entity-bound tree down HERE
// (alarms + gauges + entity grids -- see TearDownForViewpointRestream)
// and let the ConfigureForModel below rebuild it against THIS mech.
// A no-op on the first (lobby) build.
//
static int s_gaugeTreeBuilt = 0;
if (s_gaugeTreeBuilt)
{
DEBUG_STREAM << "[gauge] viewpoint re-stream: tearing the gauge tree "
"down for rebuild on entity " << (void *)viewing_entity
<< "\n" << std::flush;
gauge_renderer->TearDownForViewpointRestream();
}
s_gaugeTreeBuilt = 1;
gauge_renderer->ConfigureForModel("Init", viewing_entity); // FUN_0046ff64
}