using System.Collections; using System.Drawing; using System.Numerics; namespace WebmrAPI.Utils.Sequences { public abstract class ConsistentGenerator : ISequenceGenerator { private Queue> _seq = new(); private Queue> _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 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 Reset() { while (_seq.Count > 0) { _mem.Enqueue(_seq.Dequeue().Reset()); } _seq = _mem; _mem = new(); _index = 0; return this; } public IEnumerator GetEnumerator() { while (HasValues) { yield return Next(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public ConsistentGenerator(ISequenceGenerator generator) { Min = generator.Min; Max = generator.Max; _count = (int)(1.0 / generator.Step); } } public sealed class ConsistentNumberGenerator : ConsistentGenerator, INumberGenerator where T : struct, INumber { public INumberGenerator Self { get => this; } public ConsistentNumberGenerator Add(ISequenceGenerator generator) { AddGenerator(generator); return this; } public ConsistentNumberGenerator(ISequenceGenerator generator) : base(generator) { } } public sealed class ConsistentPointGenerator : ConsistentGenerator, IPointGenerator { public IPointGenerator Self { get => this; } public ConsistentPointGenerator Add(ISequenceGenerator generator) { AddGenerator(generator); return this; } public ConsistentPointGenerator(ISequenceGenerator generator) : base(generator) { } } }