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
{
// ReSharper disable 4 times MemberCanBePrivate.Global external use
public readonly IntensityRange IntensityRange ;
public readonly DurationRange DurationRange ;
protected ILogger ? Logger ;
public readonly DeviceApi ApiType ;
2024-02-01 23:03:28 +01:00
private readonly Queue < ValueTuple < ControlAction , Shocker , int , int > > _queue = new ( ) ;
2024-01-29 15:37:19 +01:00
private bool _workQueue = true ;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly Thread _workQueueThread ;
private const short CommandDelay = 50 ;
2024-02-01 23:03:28 +01:00
internal void Control ( ControlAction action , int? intensity = null , int? duration = null , params Shocker [ ] shockers )
2024-01-29 15:37:19 +01:00
{
int i = intensity ? ? IntensityRange . GetRandomRangeValue ( ) ;
int d = duration ? ? DurationRange . GetRandomRangeValue ( ) ;
if ( action is ControlAction . Nothing )
{
this . Logger ? . Log ( LogLevel . Information , "Doing nothing" ) ;
return ;
}
2024-02-01 23:03:28 +01:00
foreach ( Shocker shocker in shockers )
2024-01-29 15:37:19 +01:00
{
this . Logger ? . Log ( LogLevel . Debug , $"Enqueueing {action} {(intensity is not null ? $" Overwrite { i } " : $" { i } ")} {(duration is not null ? $" Overwrite { d } " : $" { d } ")}" ) ;
_queue . Enqueue ( new ( action , shocker , i , d ) ) ;
}
}
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-01 23:03:28 +01:00
protected Api ( IntensityRange intensityRange , DurationRange durationRange , DeviceApi apiType , ILogger ? logger = null )
2024-01-29 15:37:19 +01:00
{
this . IntensityRange = intensityRange ;
this . DurationRange = durationRange ;
this . ApiType = apiType ;
this . Logger = logger ;
this . _workQueueThread = new Thread ( QueueThread ) ;
this . _workQueueThread . Start ( ) ;
}
private void QueueThread ( )
{
while ( _workQueue )
if ( _queue . Count > 0 & & _queue . Dequeue ( ) is { } action )
{
this . Logger ? . Log ( LogLevel . Information , $"{action.Item1} {action.Item2} {action.Item3} {action.Item4}" ) ;
ControlInternal ( action . Item1 , action . Item2 , action . Item3 , action . Item4 ) ;
Thread . Sleep ( action . Item4 + CommandDelay ) ;
}
}
public void SetLogger ( ILogger ? logger )
{
this . Logger = logger ;
}
public override string ToString ( )
{
return $"ShockerType: {Enum.GetName(typeof(DeviceApi), this.ApiType)}\n" +
$"IntensityRange: {IntensityRange}\n" +
$"DurationRange: {DurationRange}\n\r" ;
}
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
{
return IntensityRange . Equals ( other . IntensityRange ) & & DurationRange . Equals ( other . DurationRange ) & & ApiType = = other . ApiType ;
}
public override int GetHashCode ( )
{
return HashCode . Combine ( IntensityRange , DurationRange , ( int ) ApiType ) ;
}
2024-01-29 15:37:19 +01:00
public void Dispose ( )
{
_workQueue = false ;
}
}