Skip to content

Instantly share code, notes, and snippets.

@INTERNALINTERFERENCE
Created November 29, 2022 23:12
Show Gist options
  • Save INTERNALINTERFERENCE/f2f67fd9a2bc3fa17a5301d97b63b10e to your computer and use it in GitHub Desktop.
Save INTERNALINTERFERENCE/f2f67fd9a2bc3fa17a5301d97b63b10e to your computer and use it in GitHub Desktop.
proccs
public class LedStateTimedProcessor
: Disposable
{
private readonly Timer _timer;
private readonly object _sync = new();
private OutputLedColorType _color;
public LedStateTimedProcessor( OutputLedColorType color )
{
_color = color;
_timer = new Timer( OnTimer );
}
protected override void Dispose( bool disposing )
{
if ( disposing )
_timer.Dispose();
base.Dispose( disposing );
}
public OutputLedColorType State
{
get => _color;
private set
{
if ( _color == value )
return;
_color = value;
StateChanged?.Invoke( _color );
}
}
public Action<OutputLedColorType> StateChanged { get; set; }
private TimeSpan _cycles;
private TimeSpan _repeatCount;
private TimeSpan _durationPrimary;
private TimeSpan _durationAlternating;
private OutputLedColorType _primaryColor;
private OutputLedColorType _alternatingColor;
private bool _isAlternating;
public void SetStateOn( OutputLedOnArguments arguments )
{
lock ( _sync )
{
_cycles = TimeSpan.Zero;
_repeatCount = arguments.Duration ?? TimeSpan.MaxValue;
_primaryColor = arguments.Color ?? OutputLedColorType.Default;
_isAlternating = arguments.Alternating.IsNotNull();
if ( _isAlternating )
{
_durationAlternating = arguments.Alternating.DurationAlternating;
_durationPrimary = arguments.Alternating.DurationPrimary;
_alternatingColor = arguments.Alternating.Color;
}
OnTimer( null );
}
}
public void SetStateOff( OutputLedOffArguments arguments )
{
var stateOld = State;
lock ( _sync )
{
State = OutputLedColorType.None;
_cycles += arguments.Duration ?? Timeout.InfiniteTimeSpan;
_timer.Change( arguments.Duration ?? Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan );
}
if ( stateOld != State )
StateChanged?.Invoke( State );
}
private void OnTimer( object state )
{
var stateOld = State;
lock ( _sync )
if ( _isAlternating )
{
if ( State != _primaryColor )
{
State = _primaryColor;
_timer.Change( _durationPrimary, Timeout.InfiniteTimeSpan );
}
else
{
if ( _cycles >= _repeatCount )
{
_timer.Change( Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan );
return;
}
State = _alternatingColor;
_timer.Change( _durationAlternating, Timeout.InfiniteTimeSpan );
_cycles += _durationPrimary + _durationAlternating;
}
}
else
{
if ( _repeatCount == TimeSpan.MaxValue )
{
State = _primaryColor;
_timer.Change( Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan );
}
else
{
if ( State != _primaryColor )
{
State = _primaryColor;
_timer.Change( _repeatCount, Timeout.InfiniteTimeSpan );
}
else
State = OutputLedColorType.None;
}
}
if ( stateOld != State )
StateChanged?.Invoke( State );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment