using System.Threading; using System.Threading.Tasks; using Aitex.Core.RT.DataCollection.HighPerformance; using Aitex.Core.RT.Event; using Aitex.Core.Util; using MECF.Framework.RT.Core.IoProviders; namespace Aitex.Core.RT.IOCore { public class DOAccessor : IOAccessor { private Task _tPulseGen; public DOAccessor(string name, int index, string address, bool isSimulator = false, bool disImmCache = false) : base(name, index, address, IOType.DO, isSimulator, disImmCache) { } /// protected override void SetValue(int index, bool value) { SetValue(value, out _); } public bool SetValue(bool value, out string reason) { if (IO.CanSetDO(Name, value, out reason)) { var provider = Singleton.Instance.GetProvider(base.Provider); if (provider != null && !provider.SetValue(this, value)) { reason = "Write DO[" + Name + "] failed"; return false; } var oldValue = Buffer[Index]; Buffer[Index] = value; // Check if immediate cache needed var needImmCache = oldValue != value & !IsSimulator & !DisableImmediatelyCache; if (needImmCache) DataTraceManager.Instance.ImmediateCache(this, new CacheDiagnosisInfo("", Name, Type, Index, value.ToString())); return true; } return false; } public bool SetPulseValue(bool value, out string reason, bool holdValue, int delayMillisecond) { //Debug.Assert(_tPulseGen == null || _tPulseGen.IsCompleted, $"DO {name} The last pulse is not finished."); if (IO.CanSetDO(Name, value, out reason)) { if (_tPulseGen is { IsCompleted: false }) { // reason = $"{name} is busy generating pulse"; return true; } // Check if immediate cache needed var needImmCache = !IsSimulator & !DisableImmediatelyCache; _tPulseGen = Task.Run(() => { var oldValue = Value; Value = value; // Check if immediate cache needed needImmCache &= oldValue != value; if (needImmCache) DataTraceManager.Instance.ImmediateCache(this, new CacheDiagnosisInfo("", Name, Type, Index, value.ToString())); Thread.Sleep(delayMillisecond); if (IO.CanSetDO(Name, holdValue, out var reason)) { oldValue = Value; Value = holdValue; // Check if immediate cache needed needImmCache &= oldValue != value; if (needImmCache) DataTraceManager.Instance.ImmediateCache(this, new CacheDiagnosisInfo("", Name, Type, Index, value.ToString())); } else EV.PostAlarmLog("", $"Unable to restore level of {Name}, {reason}"); }); return true; } return false; } public bool Check(bool value, out string reason) { return IO.CanSetDO(Name, value, out reason); } } }