Initial commit
This commit is contained in:
58
Utils/BlockingListener.cs
Normal file
58
Utils/BlockingListener.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
namespace MoniteurBaie.Utils;
|
||||
|
||||
public sealed class BlockingListener<T> : IObserver<T>, IDisposable
|
||||
{
|
||||
private readonly AutoResetEvent _waitHandle = new(false);
|
||||
private T? _data;
|
||||
|
||||
public T Next()
|
||||
{
|
||||
_waitHandle.WaitOne();
|
||||
var data = _data!;
|
||||
_data = default;
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Push(T value)
|
||||
{
|
||||
_data = value;
|
||||
_waitHandle.Set();
|
||||
}
|
||||
|
||||
void IObserver<T>.OnCompleted()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void IObserver<T>.OnError(Exception error)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void IObserver<T>.OnNext(T value) => Push(value);
|
||||
|
||||
#region IDisposable
|
||||
|
||||
private bool _disposedValue;
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_waitHandle.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
19
Utils/Disposer.cs
Normal file
19
Utils/Disposer.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace MoniteurBaie.Utils;
|
||||
|
||||
public sealed class Disposer : IDisposable
|
||||
{
|
||||
private Action? _callback;
|
||||
|
||||
public Disposer(Action callback) => _callback = callback;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_callback is not null)
|
||||
{
|
||||
_callback();
|
||||
_callback = default;
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
10
Utils/Extensions.cs
Normal file
10
Utils/Extensions.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace MoniteurBaie.Utils;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static char ToChar(this bool b) => b ? 'O' : 'N';
|
||||
|
||||
public static string ToEmoji(this bool b) => b ? "✔️" : "❌";
|
||||
|
||||
public static string ToAnsi(this bool b) => $"{(b ? "\u001b[32m" : "\u001b[31m")}{ToChar(b)}\u001b[0m";
|
||||
}
|
||||
31
Utils/Listener.cs
Normal file
31
Utils/Listener.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace MoniteurBaie.Utils;
|
||||
|
||||
public static class Listener
|
||||
{
|
||||
public static Listener<T> Create<T>(Action<T> callback) => new(callback);
|
||||
}
|
||||
|
||||
public class Listener<T> : IObserver<T>
|
||||
{
|
||||
private readonly Action<T> _callback;
|
||||
|
||||
public Listener(Action<T> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
_callback(value);
|
||||
}
|
||||
}
|
||||
38
Utils/Splitter.cs
Normal file
38
Utils/Splitter.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace MoniteurBaie.Utils;
|
||||
|
||||
public class Splitter
|
||||
{
|
||||
const char DELIMITER = ',';
|
||||
|
||||
public delegate T ValueReader<T>(ReadOnlySpan<char> s);
|
||||
|
||||
private readonly string _str;
|
||||
private int _pos = 0, _charCount = 0, _nextPos = 0;
|
||||
|
||||
public Splitter(string str) => _str = str;
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
_pos = _nextPos;
|
||||
var i = _str.IndexOf(DELIMITER, _pos);
|
||||
(_charCount, _nextPos) = i < 0 ? (_str.Length - _pos, _str.Length) : (i - _pos, i + 1);
|
||||
|
||||
return HasNext;
|
||||
}
|
||||
|
||||
public bool HasNext => _pos < _str.Length;
|
||||
|
||||
public T Read<T>(ValueReader<T> reader) => MoveNext() ? reader(_str.AsSpan(_pos, _charCount)) : throw new InvalidOperationException();
|
||||
|
||||
public string? ReadString() => Read(static s => new string(s));
|
||||
|
||||
public bool ReadBool() => Read(static s => s.Length == 1 ? s[0] switch { '0' => false, '1' => true, _ => throw new InvalidDataException() } : throw new InvalidDataException());
|
||||
|
||||
public int ReadInt() => Read(static s => int.Parse(s, provider: CultureInfo.InvariantCulture));
|
||||
|
||||
public uint ReadUInt() => Read(static s => uint.Parse(s, provider: CultureInfo.InvariantCulture));
|
||||
|
||||
public float ReadFloat() => Read(static s => float.Parse(s, provider: CultureInfo.InvariantCulture));
|
||||
}
|
||||
10
Utils/Utils.csproj
Normal file
10
Utils/Utils.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>$(SolutionName.Replace(" ", "_")).$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user