using System.Collections.Concurrent;
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
///
/// Cache of UDT shape descriptors keyed by (deviceHostAddress, templateInstanceId).
/// Populated on demand during discovery + whole-UDT reads; flushed via
/// and on device
/// ReinitializeAsync.
///
///
/// Template shape read (CIP Template Object class 0x6C, GetAttributeList +
/// Read Template) lands with PR 6. This class ships the cache surface so PR 6 can
/// drop the decoder in without reshaping any caller code.
///
public sealed class AbCipTemplateCache
{
private readonly ConcurrentDictionary<(string device, uint instanceId), AbCipUdtShape> _shapes = new();
///
/// Retrieve a cached UDT shape, or null if not yet read.
///
public AbCipUdtShape? TryGet(string deviceHostAddress, uint templateInstanceId) =>
_shapes.TryGetValue((deviceHostAddress, templateInstanceId), out var shape) ? shape : null;
/// Store a freshly-decoded UDT shape.
public void Put(string deviceHostAddress, uint templateInstanceId, AbCipUdtShape shape) =>
_shapes[(deviceHostAddress, templateInstanceId)] = shape;
/// Drop every cached shape — called on .
public void Clear() => _shapes.Clear();
/// Count of cached shapes — exposed for diagnostics + tests.
public int Count => _shapes.Count;
}
///
/// Decoded shape of one Logix UDT — member list + each member's offset + type. Populated
/// by PR 6's Template Object reader. At PR 5 time this is the cache's value type only;
/// no reader writes to it yet.
///
/// UDT name as reported by the Template Object.
/// Bytes the UDT occupies in a whole-UDT read buffer.
/// Ordered list of members, each with its byte offset + type.
public sealed record AbCipUdtShape(
string TypeName,
int TotalSize,
IReadOnlyList Members);
/// One member of a Logix UDT.
public sealed record AbCipUdtMember(
string Name,
int Offset,
AbCipDataType DataType,
int ArrayLength);