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; } }