using Mirle.Component.MPLC.DataBlocks; using Mirle.Component.MPLC.DataBlocks.Interfaces; using System; using System.Collections.Generic; namespace Mirle.Component.MPLC.SharedMemory { /// /// 共享記憶體快取讀取 /// public class SMReadOnlyCachedReader : SMReadWriter, IDisposable { /// /// 建構式 /// public SMReadOnlyCachedReader() { _cacheWorker = new ThreadWorker(CacheProc, 200); } /// /// 快取區塊對應 /// private class CacheBlockMapping { /// /// 來源區塊 /// public IDataBlock SourceBlock { get; set; } /// /// 快取區塊 /// public IDataBlock CacheBlock { get; set; } } /// /// 快取區塊對應 /// private readonly List _cacheBlockMappings = new List(); /// /// 快取區塊 /// private readonly List _cachedBlocks = new List(); /// /// 快取執行續 /// private readonly ThreadWorker _cacheWorker; /// /// 時間間隔 /// public int Interval { get => _cacheWorker.Interval; set => _cacheWorker.Interval = value; } /// /// 快取處理 /// private void CacheProc() { foreach (CacheBlockMapping cacheBlockMapping in _cacheBlockMappings) { cacheBlockMapping.CacheBlock.SetRawData(cacheBlockMapping.SourceBlock.GetRawData()); } } /// /// 開始 /// public void Start() { _cacheWorker.Start(); } /// /// 新增資料區塊 /// /// 資料區塊 public override void AddDataBlock(SMDataBlock newDataBlock) { _dataBlocks.Add(newDataBlock); DataBlock cacheBlock = new DataBlock(newDataBlock.DeviceRange); _cachedBlocks.Add(cacheBlock); _cacheBlockMappings.Add(new CacheBlockMapping() { SourceBlock = newDataBlock, CacheBlock = cacheBlock, }); } /// /// 取得位元 /// /// 位置 /// True/False public override bool GetBit(string address) { foreach (DataBlock block in _cachedBlocks) { if (block.TryGetBit(address, out bool value)) return value; } return false; } /// /// 設置位元開啟 /// /// 位置 public override void SetBitOn(string address) { return; } /// /// 設置位元關閉 /// /// 位置 public override void SetBitOff(string address) { return; } /// /// 讀取字元 /// /// 位置 /// public override int ReadWord(string address) { foreach (DataBlock block in _cachedBlocks) { if (block.TryGetWord(address, out int value)) return value; } return 0; } /// /// 寫入字元 /// /// 位置 /// 位元 public override void WriteWord(string address, int data) { return; } /// /// 讀取多個字元 /// /// 起始位置 /// 長度 /// 字元陣列 public override int[] ReadWords(string startAddress, int length) { foreach (DataBlock block in _cachedBlocks) { if (block.TryGetWords(startAddress, out int[] data, length)) return data; } return new int[length]; } /// /// 寫入多個字元 /// /// 起始位置 /// 字元陣列 public override void WriteWords(string startAddress, int[] data) { return; } #region IDisposable Support private bool disposedValue = false; // 偵測多餘的呼叫 /// /// 釋放資源 /// /// protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { if (_cacheWorker != null) { _cacheWorker.Pause(); _cacheWorker.Dispose(); } } disposedValue = true; } } /// /// 解構式 /// ~SMReadOnlyCachedReader() { Dispose(false); } /// /// 釋放資源 /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } }