Files
laatzen/Common/Hardware/Common.Hardware.SIRT/SIRTTask.Public.cs
T

127 lines
3.5 KiB
C#

namespace Common.Hardware.SIRT
{
using System;
using System.Collections.Concurrent;
using System.Timers;
public partial class SIRTTask
{
public readonly ConcurrentStack<SIRTMessage> responses;
public readonly SIRTMessage request;
protected readonly Timer timeoutTimer;
public SIRTTask(int frequency, int timeout = 5_000)
{
this.Timeout = timeout;
this.Frequency = frequency;
this.responses = new ConcurrentStack<SIRTMessage>();
this.request = new SIRTMessage();
this.timeoutTimer = new Timer
{
AutoReset = false,
Enabled = false,
Interval = this.Timeout
};
this.timeoutTimer.Elapsed += this.OnTimeout;
}
public event Action<SIRTTask> Completed;
public event Action<SIRTTask> Cancelled;
public event Action<SIRTTask> Timeouted;
public byte Cmd
{
get => this.request.Cmd;
set => this.request.Cmd = value;
}
public byte P1
{
get => this.request.P1;
set => this.request.P1 = value;
}
public byte P2
{
get => this.request.P2;
set => this.request.P2 = value;
}
public uint RequestAddress
{
get => this.request.Address;
set
{
this.request.Address = value;
this.ResponseAddress = value;
}
}
public uint ResponseAddress { get; set; }
public byte[] Data
{
get => this.request.Data;
set => this.request.Data = value;
}
public int Timeout { get; }
public int Frequency { get; }
public SIRTTaskState State { get; protected set; }
public void PushResponse(SIRTMessage response)
{
if (this.State == SIRTTaskState.Cancelled)
{
this.NotifyCancelled();
}
else
{
this.responses.Push(response);
this.ProcessResponse(response);
}
}
public virtual byte[] ToByteArray() => this.request.ToByteArray();
public override string ToString() => BitConverter.ToString(this.ToByteArray());
protected void NotifyCancelled() => this.Cancelled?.Invoke(this);
protected void NotifyCompleted() => this.Completed?.Invoke(this);
protected void NotifyTimeouted() => this.Timeouted?.Invoke(this);
protected virtual void OnTimeout(object sender, ElapsedEventArgs e)
{
this.State = SIRTTaskState.Cancelled;
this.NotifyCancelled();
}
protected virtual void ProcessResponse(SIRTMessage response)
{
if (this.State == SIRTTaskState.Running)
{
if (response.Cmd == SIRTMessage.ACKNANSW || (response.Data.Length > 0 && response.Data[0] == SIRTMessage.SEMI))
{
this.State = SIRTTaskState.Completed;
}
}
if (this.State == SIRTTaskState.Completed)
{
this.timeoutTimer.Stop();
this.NotifyCompleted();
}
else if (this.State == SIRTTaskState.Cancelled)
{
this.timeoutTimer.Stop();
this.NotifyCancelled();
}
}
}
}