using NModbus.Device; using NModbus.Unme.Common; using System; using System.Linq; namespace NModbus.Data { /// /// A simple implementation of the point source. Memory for all points is allocated the first time a point is accessed. /// This is useful for cases where many points are used. /// /// public class PointSource : IPointSource where T : struct { public event EventHandler BeforeRead; public event EventHandler> BeforeWrite; public event EventHandler AfterWrite; //Only create this if referenced. private readonly Lazy _points; private readonly object _syncRoot = new object(); private const int NumberOfPoints = ushort.MaxValue + 1; public PointSource() { _points = new Lazy(() => new T[NumberOfPoints]); } public T[] ReadPoints(ushort startAddress, ushort numberOfPoints) { lock (_syncRoot) { return _points.Value .Slice(startAddress, numberOfPoints) .ToArray(); } } T[] IPointSource.ReadPoints(ushort startAddress, ushort numberOfPoints) { BeforeRead?.Invoke(this, new PointEventArgs(startAddress, numberOfPoints)); return ReadPoints(startAddress, numberOfPoints); } public void WritePoints(ushort startAddress, T[] points) { lock (_syncRoot) { for (ushort index = 0; index < points.Length; index++) { _points.Value[startAddress + index] = points[index]; } } } void IPointSource.WritePoints(ushort startAddress, T[] points) { BeforeWrite?.Invoke(this, new PointEventArgs(startAddress, points)); WritePoints(startAddress, points); AfterWrite?.Invoke(this, new PointEventArgs(startAddress, (ushort)points.Length)); } } }