From 8efe765529e57e974a9786c8d1a7741f3edc709d Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Thu, 5 Oct 2017 22:47:08 +0100 Subject: [PATCH] Skip null entries when enumerating DeviceCollection Fixes #656. DeviceCollection used the underlying List's enumerator. But we replace entries in the list with nulls to save memory movement. This commit adds a custom enumerator that skips nulls in the list. --- src/OpenTK/Platform/DeviceCollection.cs | 58 ++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/OpenTK/Platform/DeviceCollection.cs b/src/OpenTK/Platform/DeviceCollection.cs index 76bada03..6a489948 100644 --- a/src/OpenTK/Platform/DeviceCollection.cs +++ b/src/OpenTK/Platform/DeviceCollection.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. // +using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -38,23 +39,70 @@ namespace OpenTK.Platform // that is added. internal class DeviceCollection : IEnumerable { + internal struct Enumerator : IEnumerator + { + private int Index; + private DeviceCollection Collection; + + internal Enumerator(DeviceCollection collection) + { + Collection = collection; + Index = -1; + Current = default(T); + } + + public T Current { get; private set; } + + object IEnumerator.Current + { + get + { + return Current; + } + } + + public void Dispose() + { + } + + public bool MoveNext() + { + do + { + ++Index; + if (Index < Collection.Devices.Count) + { + Current = Collection.Devices[Index]; + } + } while (Index < Collection.Devices.Count && Collection.Devices[Index] == null); + + return Index < Collection.Devices.Count; + } + + public void Reset() + { + Index = -1; + Current = default(T); + } + } + private readonly Dictionary Map = new Dictionary(); private readonly List Devices = new List(); IEnumerator IEnumerable.GetEnumerator() { - return Devices.GetEnumerator(); + return new Enumerator(this); } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + IEnumerator IEnumerable.GetEnumerator() { - return GetEnumerator(); + return new Enumerator(this); } // This avoids boxing when using foreach loops - public List.Enumerator GetEnumerator() + public Enumerator GetEnumerator() { - return Devices.GetEnumerator(); + return new Enumerator(this); } public T this[int index]