98 lines
2.8 KiB
C#
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) { }
|
|
}
|
|
}
|