winmr-api/Utils/Sequences/Consistent.cs
2026-01-08 21:35:06 +03:00

98 lines
2.8 KiB
C#

using System.Collections;
using System.Drawing;
using System.Numerics;
namespace WebmrAPI.Utils.Sequences
{
public abstract class ConsistentGenerator<T> : ISequenceGenerator<T>
{
private Queue<ISequenceGenerator<T>> _seq = new();
private Queue<ISequenceGenerator<T>> _mem = new();
private int _count = 0;
private int _index = 0;
public T Min { get; protected set; }
public T Max { get; protected set; }
public virtual double Progress { get => (double)_index / _count; }
public double Step { get => 1.0 / _count; }
public bool HasValues { get => _seq.Count > 0; }
protected void AddGenerator(ISequenceGenerator<T> generator)
{
Max = generator.Max;
_count += (int)(1.0 / generator.Step);
}
public T Next()
{
if (HasValues)
{
if (_seq.Peek().HasValues)
{
_index++;
return _seq.Peek().Next();
}
_mem.Enqueue(_seq.Dequeue().Reset());
return Next();
}
return Max;
}
public ISequenceGenerator<T> Reset()
{
while (_seq.Count > 0)
{
_mem.Enqueue(_seq.Dequeue().Reset());
}
_seq = _mem;
_mem = new();
_index = 0;
return this;
}
public IEnumerator<T> GetEnumerator()
{
while (HasValues)
{
yield return Next();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public ConsistentGenerator(ISequenceGenerator<T> generator)
{
Min = generator.Min;
Max = generator.Max;
_count = (int)(1.0 / generator.Step);
}
}
public sealed class ConsistentNumberGenerator<T> : ConsistentGenerator<T>, INumberGenerator<T> where T : struct, INumber<T>
{
public INumberGenerator<T> Self { get => this; }
public ConsistentNumberGenerator<T> Add(ISequenceGenerator<T> generator)
{
AddGenerator(generator);
return this;
}
public ConsistentNumberGenerator(ISequenceGenerator<T> generator)
: base(generator) { }
}
public sealed class ConsistentPointGenerator : ConsistentGenerator<Point>, IPointGenerator
{
public IPointGenerator Self { get => this; }
public ConsistentPointGenerator Add(ISequenceGenerator<Point> generator)
{
AddGenerator(generator);
return this;
}
public ConsistentPointGenerator(ISequenceGenerator<Point> generator)
: base(generator) { }
}
}