IdList.cs
1 using System; 2 using System.Collections.Generic; 3 4 namespace Ryujinx.Graphics.Vulkan 5 { 6 class IdList<T> where T : class 7 { 8 private readonly List<T> _list; 9 private int _freeMin; 10 11 public IdList() 12 { 13 _list = new List<T>(); 14 _freeMin = 0; 15 } 16 17 public int Add(T value) 18 { 19 int id; 20 int count = _list.Count; 21 id = _list.IndexOf(null, _freeMin); 22 23 if ((uint)id < (uint)count) 24 { 25 _list[id] = value; 26 } 27 else 28 { 29 id = count; 30 _freeMin = id + 1; 31 32 _list.Add(value); 33 } 34 35 return id + 1; 36 } 37 38 public void Remove(int id) 39 { 40 id--; 41 42 int count = _list.Count; 43 44 if ((uint)id >= (uint)count) 45 { 46 return; 47 } 48 49 if (id + 1 == count) 50 { 51 // Trim unused items. 52 int removeIndex = id; 53 54 while (removeIndex > 0 && _list[removeIndex - 1] == null) 55 { 56 removeIndex--; 57 } 58 59 _list.RemoveRange(removeIndex, count - removeIndex); 60 61 if (_freeMin > removeIndex) 62 { 63 _freeMin = removeIndex; 64 } 65 } 66 else 67 { 68 _list[id] = null; 69 70 if (_freeMin > id) 71 { 72 _freeMin = id; 73 } 74 } 75 } 76 77 public bool TryGetValue(int id, out T value) 78 { 79 id--; 80 81 try 82 { 83 if ((uint)id < (uint)_list.Count) 84 { 85 value = _list[id]; 86 return value != null; 87 } 88 89 value = null; 90 return false; 91 } 92 catch (ArgumentOutOfRangeException) 93 { 94 value = null; 95 return false; 96 } 97 catch (IndexOutOfRangeException) 98 { 99 value = null; 100 return false; 101 } 102 } 103 104 public void Clear() 105 { 106 _list.Clear(); 107 _freeMin = 0; 108 } 109 110 public IEnumerator<T> GetEnumerator() 111 { 112 for (int i = 0; i < _list.Count; i++) 113 { 114 if (_list[i] != null) 115 { 116 yield return _list[i]; 117 } 118 } 119 } 120 } 121 }