namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared;
///
/// Caches a DynamicComponent parameter dictionary (R04 H2) and rebuilds it only when one of the
/// values it carries changed. The modals used to build a new dictionary, and new
/// EventCallbacks, on every render. A plain build-once cache is wrong: it would pin the JSON
/// captured at first render and silently strand every later edit — so the cache is keyed on the
/// current values, and the callbacks it hands out are created once by the caller and reused.
/// Note the limit: Blazor's change detection treats any EventCallback parameter as
/// possibly changed, so a hosted form still sees SetParametersAsync on each parent render. The
/// per-form _lastParsed guards remain load-bearing; this removes the per-render allocations and
/// gives the child a stable dictionary and callback identity.
///
public sealed class ParameterDictionaryCache
{
private object?[]? _keyValues;
private Dictionary? _cached;
/// Returns the cached dictionary when equal the previous call's,
/// otherwise builds, caches and returns a new one.
/// The values the dictionary carries (compared with ).
/// Builds the dictionary from the current state.
/// The parameter dictionary.
public Dictionary Get(object?[] keyValues, Func> build)
{
if (_cached is not null && _keyValues is not null && Same(_keyValues, keyValues)) return _cached;
_cached = build();
_keyValues = (object?[])keyValues.Clone();
return _cached;
}
/// Drops the cached dictionary (e.g. on modal close) so the next rebuilds.
public void Reset()
{
_cached = null;
_keyValues = null;
}
private static bool Same(object?[] a, object?[] b)
{
if (a.Length != b.Length) return false;
for (var i = 0; i < a.Length; i++)
{
if (!Equals(a[i], b[i])) return false;
}
return true;
}
}