diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 5c61ce131..3b9a24962 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -4509,8 +4509,8 @@ static void RequireSectorMapZoneDetailsUseEveSurface(string root) ".Details", ".LatestZone(zoneIndex)", ".Settings", - ".LatestCatalog()", - ".LatestPlayer()", + ".ReactiveCatalog()", + ".ReactivePlayer()", "AetheriaClient", "AetheriaRuntimeZoneDetailsSurfaceCommands.TryRead(request, out var command)", "AetheriaRuntimeZoneDetailsCommandKind.Close" @@ -7197,6 +7197,36 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) string.Join(", ", missingInventoryPanelSharedDocumentSymbols)); } + var sectorRenderer = File.ReadAllText(Path.Combine( + root, + "Assets", + "Scripts", + "UI", + "Menu", + "SectorRenderer.cs")); + var requiredSectorRendererSharedDocumentSymbols = new[] + { + "CultMeshReactiveDocument _catalog", + "CultMeshReactiveDocument _playerSettings", + "ResolveClient().Aetheria().ReactiveCatalog()", + ".Settings", + ".ReactivePlayer()", + "_catalog?.Dispose()", + "_playerSettings?.Dispose()", + "_catalog?.Current", + "_playerSettings?.Current", + "private void OnDestroy()" + }; + var missingSectorRendererSharedDocumentSymbols = requiredSectorRendererSharedDocumentSymbols + .Where(symbol => !sectorRenderer.Contains(symbol, StringComparison.Ordinal)) + .ToArray(); + if (missingSectorRendererSharedDocumentSymbols.Length > 0) + { + throw new InvalidOperationException( + "SectorRenderer should bind shared catalog/settings through managed reactive Aetheria documents with renderer lifetime disposal: " + + string.Join(", ", missingSectorRendererSharedDocumentSymbols)); + } + var volumeCloudRenderer = File.ReadAllText(Path.Combine( root, "Assets", @@ -12795,9 +12825,9 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root) !sectorRenderer.Contains(".LatestSectorMap()", StringComparison.Ordinal) || !sectorRenderer.Contains(".Details", StringComparison.Ordinal) || !sectorRenderer.Contains(".LatestZone(zoneIndex)", StringComparison.Ordinal) || - !sectorRenderer.Contains(".LatestCatalog()", StringComparison.Ordinal) || !sectorRenderer.Contains(".Settings", StringComparison.Ordinal) || - !sectorRenderer.Contains(".LatestPlayer()", StringComparison.Ordinal) || + !sectorRenderer.Contains(".ReactiveCatalog()", StringComparison.Ordinal) || + !sectorRenderer.Contains(".ReactivePlayer()", StringComparison.Ordinal) || !sectorMap.Contains("AetheriaUnityRuntimeClientProvider.ResolveClient(", StringComparison.Ordinal) || !sectorMap.Contains(".Aetheria()", StringComparison.Ordinal) || !sectorMap.Contains(".LatestSectorMap()", StringComparison.Ordinal) || diff --git a/Assets/Scripts/UI/Menu/SectorRenderer.cs b/Assets/Scripts/UI/Menu/SectorRenderer.cs index 48ecdc1f7..eb969f0bc 100644 --- a/Assets/Scripts/UI/Menu/SectorRenderer.cs +++ b/Assets/Scripts/UI/Menu/SectorRenderer.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; +using GameCult.Mesh; using GameCult.Aetheria.EveRuntime; using GameCult.Aetheria.State.Verse; using GameCult.Eve.Surface; @@ -46,8 +47,8 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS private float _sectorCameraDepth; private UIDocument _zoneDetailsSurfaceDocument; private string _clientStatePath = ""; - private AetheriaRuntimeCatalogSnapshot _catalog; - private AetheriaRuntimePlayerSettingsDocument _playerSettings; + private CultMeshReactiveDocument _catalog; + private CultMeshReactiveDocument _playerSettings; private readonly AetheriaEveUnitySurfaceChrome _zoneDetailsSurfaceChrome = new AetheriaEveUnitySurfaceChrome { RootAlignItems = Align.FlexEnd, @@ -215,38 +216,38 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS private AetheriaRuntimeCatalogSnapshot ResolveCatalog() { if (_catalog != null) - return _catalog; + return _catalog.Current; try { - _catalog = ResolveClient().Aetheria().LatestCatalog(); + _catalog = ResolveClient().Aetheria().ReactiveCatalog(); } catch (Exception ex) { - Debug.LogWarning($"Failed to read Aetheria sector catalog from local Verse state: {ex.Message}"); + Debug.LogWarning($"Failed to bind Aetheria sector catalog from local Verse state: {ex.Message}"); } - return _catalog; + return _catalog?.Current; } private AetheriaRuntimePlayerSettingsDocument ResolvePlayerSettings() { if (_playerSettings != null) - return _playerSettings; + return _playerSettings.Current; try { _playerSettings = ResolveClient() .Aetheria() .Settings - .LatestPlayer(); + .ReactivePlayer(); } catch (Exception ex) { - Debug.LogWarning($"Failed to read Aetheria sector player settings from local Verse state: {ex.Message}"); + Debug.LogWarning($"Failed to bind Aetheria sector player settings from local Verse state: {ex.Message}"); } - return _playerSettings; + return _playerSettings?.Current; } private string FormatValue(float value) @@ -278,6 +279,8 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS private void ClearClientCaches() { + _catalog?.Dispose(); + _playerSettings?.Dispose(); _catalog = null; _playerSettings = null; } @@ -325,6 +328,8 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS private void OnDestroy() { + ClearClientCaches(); + if (_zoneDetailsSurfaceDocument != null) { AetheriaEveUnitySurfaceHost.DestroyDocument(_zoneDetailsSurfaceDocument);