using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace TechbloxModdingAPI.Utility { public class WeakDictionary : IDictionary where TValue : class { private Dictionary> _dictionary = new Dictionary>(); public IEnumerator> GetEnumerator() { using var enumerator = _dictionary.GetEnumerator(); while (enumerator.MoveNext()) { if (enumerator.Current.Value.TryGetTarget(out var value)) yield return new KeyValuePair(enumerator.Current.Key, value); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(KeyValuePair item) { Add(item.Key, item.Value); } public void Clear() { _dictionary.Clear(); } public bool Contains(KeyValuePair item) { return TryGetValue(item.Key, out var value) && item.Value == value; } public void CopyTo(KeyValuePair[] array, int arrayIndex) { throw new System.NotImplementedException(); } public bool Remove(KeyValuePair item) { return Contains(item) && Remove(item.Key); } public int Count => _dictionary.Count; public bool IsReadOnly => false; public bool ContainsKey(TKey key) { return _dictionary.ContainsKey(key); } public void Add(TKey key, TValue value) { _dictionary.Add(key, new WeakReference(value)); } public bool Remove(TKey key) { return _dictionary.Remove(key); } public bool TryGetValue(TKey key, out TValue value) { value = null; return _dictionary.TryGetValue(key, out var reference) && reference.TryGetTarget(out value); } public TValue this[TKey key] { get => TryGetValue(key, out var value) ? value : throw new KeyNotFoundException($"Key {key} not found in WeakDictionary."); set => _dictionary[key] = new WeakReference(value); } public ICollection Keys => _dictionary.Keys; public ICollection Values => new ValueCollection(this); public class ValueCollection : ICollection, IReadOnlyCollection { private WeakDictionary _dictionary; internal ValueCollection(WeakDictionary dictionary) { _dictionary = dictionary; } public IEnumerator GetEnumerator() { using var enumerator = _dictionary.GetEnumerator(); while (enumerator.MoveNext()) { yield return enumerator.Current.Value; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(TValue item) { throw new NotSupportedException("The value collection is read only."); } public void Clear() { throw new NotSupportedException("The value collection is read only."); } public bool Contains(TValue item) { return _dictionary.Any(kv => kv.Value == item); } public void CopyTo(TValue[] array, int arrayIndex) { throw new NotImplementedException(); } public bool Remove(TValue item) { throw new NotSupportedException("The value collection is read only."); } public int Count => _dictionary.Count; public bool IsReadOnly => true; } } }