You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
5.9 KiB
204 lines
5.9 KiB
using Mirle.Component.MPLC.DataBlocks;
|
|
using Mirle.Component.MPLC.DataBlocks.Interfaces;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Mirle.Component.MPLC.SharedMemory
|
|
{
|
|
/// <summary>
|
|
/// 共享記憶體快取讀取
|
|
/// </summary>
|
|
public class SMReadOnlyCachedReader : SMReadWriter, IDisposable
|
|
{
|
|
/// <summary>
|
|
/// 建構式
|
|
/// </summary>
|
|
public SMReadOnlyCachedReader()
|
|
{
|
|
_cacheWorker = new ThreadWorker(CacheProc, 200);
|
|
}
|
|
/// <summary>
|
|
/// 快取區塊對應
|
|
/// </summary>
|
|
private class CacheBlockMapping
|
|
{
|
|
/// <summary>
|
|
/// 來源區塊
|
|
/// </summary>
|
|
public IDataBlock SourceBlock { get; set; }
|
|
/// <summary>
|
|
/// 快取區塊
|
|
/// </summary>
|
|
public IDataBlock CacheBlock { get; set; }
|
|
}
|
|
/// <summary>
|
|
/// 快取區塊對應
|
|
/// </summary>
|
|
private readonly List<CacheBlockMapping> _cacheBlockMappings = new List<CacheBlockMapping>();
|
|
/// <summary>
|
|
/// 快取區塊
|
|
/// </summary>
|
|
private readonly List<DataBlock> _cachedBlocks = new List<DataBlock>();
|
|
/// <summary>
|
|
/// 快取執行續
|
|
/// </summary>
|
|
private readonly ThreadWorker _cacheWorker;
|
|
/// <summary>
|
|
/// 時間間隔
|
|
/// </summary>
|
|
public int Interval
|
|
{
|
|
get => _cacheWorker.Interval;
|
|
set => _cacheWorker.Interval = value;
|
|
}
|
|
/// <summary>
|
|
/// 快取處理
|
|
/// </summary>
|
|
private void CacheProc()
|
|
{
|
|
foreach (CacheBlockMapping cacheBlockMapping in _cacheBlockMappings)
|
|
{
|
|
cacheBlockMapping.CacheBlock.SetRawData(cacheBlockMapping.SourceBlock.GetRawData());
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 開始
|
|
/// </summary>
|
|
public void Start()
|
|
{
|
|
_cacheWorker.Start();
|
|
}
|
|
/// <summary>
|
|
/// 新增資料區塊
|
|
/// </summary>
|
|
/// <param name="newDataBlock">資料區塊</param>
|
|
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,
|
|
});
|
|
}
|
|
/// <summary>
|
|
/// 取得位元
|
|
/// </summary>
|
|
/// <param name="address">位置</param>
|
|
/// <returns>True/False</returns>
|
|
public override bool GetBit(string address)
|
|
{
|
|
foreach (DataBlock block in _cachedBlocks)
|
|
{
|
|
if (block.TryGetBit(address, out bool value))
|
|
return value;
|
|
}
|
|
return false;
|
|
}
|
|
/// <summary>
|
|
/// 設置位元開啟
|
|
/// </summary>
|
|
/// <param name="address">位置</param>
|
|
public override void SetBitOn(string address)
|
|
{
|
|
return;
|
|
}
|
|
/// <summary>
|
|
/// 設置位元關閉
|
|
/// </summary>
|
|
/// <param name="address">位置</param>
|
|
public override void SetBitOff(string address)
|
|
{
|
|
return;
|
|
}
|
|
/// <summary>
|
|
/// 讀取字元
|
|
/// </summary>
|
|
/// <param name="address">位置</param>
|
|
/// <returns></returns>
|
|
public override int ReadWord(string address)
|
|
{
|
|
foreach (DataBlock block in _cachedBlocks)
|
|
{
|
|
if (block.TryGetWord(address, out int value))
|
|
return value;
|
|
}
|
|
return 0;
|
|
}
|
|
/// <summary>
|
|
/// 寫入字元
|
|
/// </summary>
|
|
/// <param name="address">位置</param>
|
|
/// <param name="data">位元</param>
|
|
public override void WriteWord(string address, int data)
|
|
{
|
|
return;
|
|
}
|
|
/// <summary>
|
|
/// 讀取多個字元
|
|
/// </summary>
|
|
/// <param name="startAddress">起始位置</param>
|
|
/// <param name="length">長度</param>
|
|
/// <returns>字元陣列</returns>
|
|
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];
|
|
}
|
|
/// <summary>
|
|
/// 寫入多個字元
|
|
/// </summary>
|
|
/// <param name="startAddress">起始位置</param>
|
|
/// <param name="data">字元陣列</param>
|
|
public override void WriteWords(string startAddress, int[] data)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#region IDisposable Support
|
|
|
|
private bool disposedValue = false; // 偵測多餘的呼叫
|
|
/// <summary>
|
|
/// 釋放資源
|
|
/// </summary>
|
|
/// <param name="disposing"></param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!disposedValue)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (_cacheWorker != null)
|
|
{
|
|
_cacheWorker.Pause();
|
|
_cacheWorker.Dispose();
|
|
}
|
|
}
|
|
disposedValue = true;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 解構式
|
|
/// </summary>
|
|
~SMReadOnlyCachedReader()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
/// <summary>
|
|
/// 釋放資源
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|