2024-01-29 15:37:19 +01:00
|
|
|
|
using CShocker.Devices.Additional;
|
|
|
|
|
using CShocker.Ranges;
|
|
|
|
|
using CShocker.Shockers.Abstract;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
|
|
|
|
namespace CShocker.Devices.Abstract;
|
|
|
|
|
|
2024-02-01 23:03:28 +01:00
|
|
|
|
public abstract class Api : IDisposable
|
2024-01-29 15:37:19 +01:00
|
|
|
|
{
|
2024-02-12 02:01:31 +01:00
|
|
|
|
// ReSharper disable 4 times MemberCanBePrivate.Global -> Exposed
|
2024-01-29 15:37:19 +01:00
|
|
|
|
protected ILogger? Logger;
|
|
|
|
|
public readonly DeviceApi ApiType;
|
2025-01-16 22:36:52 +01:00
|
|
|
|
private Queue<DateTime> order = new();
|
|
|
|
|
private Dictionary<DateTime, Task> tasks = new();
|
2024-01-29 15:37:19 +01:00
|
|
|
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
|
|
|
private const short CommandDelay = 50;
|
2024-02-11 23:24:25 +01:00
|
|
|
|
internal readonly IntegerRange ValidIntensityRange, ValidDurationRange;
|
2024-01-29 15:37:19 +01:00
|
|
|
|
|
2024-02-11 22:24:53 +01:00
|
|
|
|
internal void Control(ControlAction action, int intensity, int duration, params Shocker[] shockers)
|
2024-01-29 15:37:19 +01:00
|
|
|
|
{
|
2024-02-11 22:24:53 +01:00
|
|
|
|
bool enqueueItem = true;
|
2024-02-12 02:02:30 +01:00
|
|
|
|
if (!ValidIntensityRange.IsValueWithinLimits(intensity))
|
2024-02-11 22:24:53 +01:00
|
|
|
|
{
|
|
|
|
|
this.Logger?.Log(LogLevel.Information, $"Value not within allowed {nameof(intensity)}-Range ({ValidIntensityRange.RangeString()}): {intensity}");
|
|
|
|
|
enqueueItem = false;
|
|
|
|
|
}
|
2024-02-12 02:02:30 +01:00
|
|
|
|
if (!ValidDurationRange.IsValueWithinLimits(duration))
|
2024-02-11 22:24:53 +01:00
|
|
|
|
{
|
|
|
|
|
this.Logger?.Log(LogLevel.Information, $"Value not within allowed {nameof(duration)}-Range ({ValidIntensityRange.RangeString()}): {duration}");
|
|
|
|
|
enqueueItem = false;
|
|
|
|
|
}
|
|
|
|
|
if (!enqueueItem)
|
|
|
|
|
{
|
|
|
|
|
this.Logger?.Log(LogLevel.Information, "Doing nothing.");
|
2024-01-29 15:37:19 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
2024-02-01 23:03:28 +01:00
|
|
|
|
foreach (Shocker shocker in shockers)
|
2024-01-29 15:37:19 +01:00
|
|
|
|
{
|
2024-02-12 03:06:28 +01:00
|
|
|
|
this.Logger?.Log(LogLevel.Debug, $"Enqueueing {action} Intensity: {intensity} Duration: {duration}\nShocker:\n{shocker}");
|
2025-01-16 22:36:52 +01:00
|
|
|
|
ValueTuple<ControlAction, Shocker, int, int> tuple = new(action, shocker, intensity, duration);
|
|
|
|
|
DateTime now = DateTime.Now;
|
|
|
|
|
Task t = new (() => ExecuteTask(now, tuple));
|
|
|
|
|
order.Enqueue(now);
|
|
|
|
|
tasks.Add(now, t);
|
|
|
|
|
t.Start();
|
2024-01-29 15:37:19 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-01 23:03:28 +01:00
|
|
|
|
protected abstract void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration);
|
2024-01-29 15:37:19 +01:00
|
|
|
|
|
2024-02-11 22:24:53 +01:00
|
|
|
|
protected Api(DeviceApi apiType, IntegerRange validIntensityRange, IntegerRange validDurationRange, ILogger? logger = null)
|
2024-01-29 15:37:19 +01:00
|
|
|
|
{
|
|
|
|
|
this.ApiType = apiType;
|
|
|
|
|
this.Logger = logger;
|
2024-02-11 22:24:53 +01:00
|
|
|
|
this.ValidIntensityRange = validIntensityRange;
|
|
|
|
|
this.ValidDurationRange = validDurationRange;
|
2024-01-29 15:37:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-16 22:36:52 +01:00
|
|
|
|
private void ExecuteTask(DateTime when, ValueTuple<ControlAction, Shocker, int, int> tuple)
|
2024-01-29 15:37:19 +01:00
|
|
|
|
{
|
2025-01-16 22:36:52 +01:00
|
|
|
|
while (order.First() != when)
|
|
|
|
|
Thread.Sleep(CommandDelay);
|
|
|
|
|
this.Logger?.Log(LogLevel.Information, $"Executing: {Enum.GetName(tuple.Item1)} Intensity: {tuple.Item3} Duration: {tuple.Item4}\nShocker:\n{tuple.Item2}");
|
|
|
|
|
ControlInternal(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4);
|
|
|
|
|
Thread.Sleep(tuple.Item4);
|
|
|
|
|
tasks.Remove(when);
|
|
|
|
|
order.Dequeue();
|
2024-01-29 15:37:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetLogger(ILogger? logger)
|
|
|
|
|
{
|
|
|
|
|
this.Logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2024-02-11 22:24:53 +01:00
|
|
|
|
return $"ShockerType: {Enum.GetName(typeof(DeviceApi), this.ApiType)}\n\r";
|
2024-01-29 15:37:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 17:05:13 +01:00
|
|
|
|
public override bool Equals(object? obj)
|
|
|
|
|
{
|
2024-02-01 23:03:28 +01:00
|
|
|
|
return obj is Api d && Equals(d);
|
2024-01-29 17:05:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-01 23:03:28 +01:00
|
|
|
|
protected bool Equals(Api other)
|
2024-01-29 17:05:13 +01:00
|
|
|
|
{
|
2024-02-11 22:24:53 +01:00
|
|
|
|
return ApiType == other.ApiType;
|
2024-01-29 17:05:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
2024-02-12 02:04:45 +01:00
|
|
|
|
return ApiType.GetHashCode();
|
2024-01-29 17:05:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 15:37:19 +01:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2025-01-16 22:36:52 +01:00
|
|
|
|
foreach ((DateTime when, Task? task) in tasks)
|
|
|
|
|
task?.Dispose();
|
2024-01-29 15:37:19 +01:00
|
|
|
|
}
|
|
|
|
|
}
|