Use reactive catalog for action bar bindings

This commit is contained in:
Meta Vens 2026-06-28 08:48:34 +01:00
commit 4d21ca8d76
3 changed files with 60 additions and 5 deletions

View file

@ -6978,6 +6978,8 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root)
var requiredClientSymbols = new[]
{
"public AetheriaRuntimeCatalogSnapshot LatestCatalog()",
"public Task<CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot>> ReactiveCatalogAsync(",
"public CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot> ReactiveCatalog(",
"public Task<AetheriaRuntimePlayerSettingsDocument> LatestPlayerAsync()",
"public AetheriaRuntimePlayerSettingsDocument LatestPlayer()",
"public Task<CultMeshReactiveDocument<AetheriaRuntimePlayerSettingsDocument>> ReactivePlayerAsync(",
@ -7047,6 +7049,31 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root)
string.Join(", ", offenders));
}
var actionBarSlot = File.ReadAllText(Path.Combine(
root,
"Assets",
"Scripts",
"Gameplay",
"ActionBarSlot.cs"));
var requiredActionBarSymbols = new[]
{
"public abstract class ActionBarBinding : IDisposable",
"CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot> _catalog",
"Client.Aetheria().ReactiveCatalog()",
"_catalog?.Current?.FindItem(item.ItemKey)",
"binding?.Dispose()",
"private void OnDestroy()"
};
var missingActionBarSymbols = requiredActionBarSymbols
.Where(symbol => !actionBarSlot.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingActionBarSymbols.Length > 0)
{
throw new InvalidOperationException(
"ActionBarSlot should resolve runtime catalog items through a managed reactive catalog document with binding lifetime disposal: " +
string.Join(", ", missingActionBarSymbols));
}
var volumeCloudRenderer = File.ReadAllText(Path.Combine(
root,
"Assets",

View file

@ -1,6 +1,7 @@
using System;
using System.Linq;
using GameCult.Aetheria.State.Verse;
using GameCult.Mesh;
using TMPro;
using UniRx.Triggers;
using UnityEngine;
@ -24,6 +25,10 @@ public class ActionBarSlot : MonoBehaviour
get => binding;
set
{
if (ReferenceEquals(binding, value))
return;
binding?.Dispose();
binding = value;
if (binding == null)
{
@ -35,6 +40,11 @@ public class ActionBarSlot : MonoBehaviour
}
}
private void OnDestroy()
{
Binding = null;
}
private void Update()
{
Binding?.Update();
@ -42,13 +52,13 @@ public class ActionBarSlot : MonoBehaviour
}
public abstract class ActionBarBinding
public abstract class ActionBarBinding : IDisposable
{
public Entity Entity { get; }
protected AetheriaClient Client { get; }
protected ActionBarSlot Slot { get; }
protected GameSettings Settings { get; }
private AetheriaRuntimeCatalogSnapshot _catalog;
private CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot> _catalog;
public abstract void Activate();
public abstract void Deactivate();
public abstract void Update();
@ -85,15 +95,21 @@ public abstract class ActionBarBinding
try
{
_catalog ??= Client.Aetheria().LatestCatalog();
return _catalog?.FindItem(item.ItemKey);
_catalog ??= Client.Aetheria().ReactiveCatalog();
return _catalog?.Current?.FindItem(item.ItemKey);
}
catch (Exception ex)
{
Debug.LogWarning($"Failed to read Aetheria runtime catalog for action-bar binding: {ex.Message}");
Debug.LogWarning($"Failed to bind Aetheria runtime catalog for action-bar binding: {ex.Message}");
return null;
}
}
public virtual void Dispose()
{
_catalog?.Dispose();
_catalog = null;
}
}
public class ActionBarConsumableBinding : ActionBarBinding

View file

@ -188,6 +188,18 @@ namespace GameCult.Aetheria.State.Verse
return Latest<AetheriaRuntimeCatalogSnapshot>();
}
public Task<CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot>> ReactiveCatalogAsync(
CultMeshReactiveDocumentOptions? options = null)
{
return Catalog.ReactiveAsync(options);
}
public CultMeshReactiveDocument<AetheriaRuntimeCatalogSnapshot> ReactiveCatalog(
CultMeshReactiveDocumentOptions? options = null)
{
return Catalog.Reactive(options);
}
public Task<AetheriaRuntimeDaemonFrameDocument> LatestDaemonFrameAsync()
{
return LatestFrame.LatestAsync();