A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.1KB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace TechbloxModdingAPI.Utility
  6. {
  7. public class WeakDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TValue : class
  8. {
  9. private Dictionary<TKey, WeakReference<TValue>> _dictionary = new Dictionary<TKey, WeakReference<TValue>>();
  10. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  11. {
  12. using var enumerator = _dictionary.GetEnumerator();
  13. while (enumerator.MoveNext())
  14. {
  15. if (enumerator.Current.Value.TryGetTarget(out var value))
  16. yield return new KeyValuePair<TKey, TValue>(enumerator.Current.Key, value);
  17. }
  18. }
  19. IEnumerator IEnumerable.GetEnumerator()
  20. {
  21. return GetEnumerator();
  22. }
  23. public void Add(KeyValuePair<TKey, TValue> item)
  24. {
  25. Add(item.Key, item.Value);
  26. }
  27. public void Clear()
  28. {
  29. _dictionary.Clear();
  30. }
  31. public bool Contains(KeyValuePair<TKey, TValue> item)
  32. {
  33. return TryGetValue(item.Key, out var value) && item.Value == value;
  34. }
  35. public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
  36. {
  37. throw new System.NotImplementedException();
  38. }
  39. public bool Remove(KeyValuePair<TKey, TValue> item)
  40. {
  41. return Contains(item) && Remove(item.Key);
  42. }
  43. public int Count => _dictionary.Count;
  44. public bool IsReadOnly => false;
  45. public bool ContainsKey(TKey key)
  46. {
  47. return _dictionary.ContainsKey(key);
  48. }
  49. public void Add(TKey key, TValue value)
  50. {
  51. _dictionary.Add(key, new WeakReference<TValue>(value));
  52. }
  53. public bool Remove(TKey key)
  54. {
  55. return _dictionary.Remove(key);
  56. }
  57. public bool TryGetValue(TKey key, out TValue value)
  58. {
  59. value = null;
  60. return _dictionary.TryGetValue(key, out var reference) && reference.TryGetTarget(out value);
  61. }
  62. public TValue this[TKey key]
  63. {
  64. get => TryGetValue(key, out var value)
  65. ? value
  66. : throw new KeyNotFoundException($"Key {key} not found in WeakDictionary.");
  67. set => _dictionary[key] = new WeakReference<TValue>(value);
  68. }
  69. public ICollection<TKey> Keys => _dictionary.Keys;
  70. public ICollection<TValue> Values => new ValueCollection(this);
  71. public class ValueCollection : ICollection<TValue>, IReadOnlyCollection<TValue>
  72. {
  73. private WeakDictionary<TKey, TValue> _dictionary;
  74. internal ValueCollection(WeakDictionary<TKey, TValue> dictionary)
  75. {
  76. _dictionary = dictionary;
  77. }
  78. public IEnumerator<TValue> GetEnumerator()
  79. {
  80. using var enumerator = _dictionary.GetEnumerator();
  81. while (enumerator.MoveNext())
  82. {
  83. yield return enumerator.Current.Value;
  84. }
  85. }
  86. IEnumerator IEnumerable.GetEnumerator()
  87. {
  88. return GetEnumerator();
  89. }
  90. public void Add(TValue item)
  91. {
  92. throw new NotSupportedException("The value collection is read only.");
  93. }
  94. public void Clear()
  95. {
  96. throw new NotSupportedException("The value collection is read only.");
  97. }
  98. public bool Contains(TValue item)
  99. {
  100. return _dictionary.Any(kv => kv.Value == item);
  101. }
  102. public void CopyTo(TValue[] array, int arrayIndex)
  103. {
  104. throw new NotImplementedException();
  105. }
  106. public bool Remove(TValue item)
  107. {
  108. throw new NotSupportedException("The value collection is read only.");
  109. }
  110. public int Count => _dictionary.Count;
  111. public bool IsReadOnly => true;
  112. }
  113. }
  114. }