TechbloxModdingAPI/TechbloxModdingAPI/Utility/WeakDictionary.cs
NorbiPeti d27bcee8d5 Update to Techblox 2022.01.25.15.52
- Fixed compilation errors
- Fixed patching errors and added missing anti-cheat patch
- Added check to verify that the init data has been removed from blocks once they are placed in game
- Removed block place event deduplication as it seems to be not needed anymore
- Fixed async tests not properly running
- Added Player.State
- Attempted to fix seat entering/leaving (we can only send inputs in client code)
- Fixed the weak dictionary ContainsKey returning true even if the item is no longer there
2022-01-30 04:32:10 +01:00

140 lines
No EOL
4.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace TechbloxModdingAPI.Utility
{
public class WeakDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TValue : class
{
private Dictionary<TKey, WeakReference<TValue>> _dictionary = new Dictionary<TKey, WeakReference<TValue>>();
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
using var enumerator = _dictionary.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Current.Value.TryGetTarget(out var value))
yield return new KeyValuePair<TKey, TValue>(enumerator.Current.Key, value);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
_dictionary.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return TryGetValue(item.Key, out var value) && item.Value == value;
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
throw new System.NotImplementedException();
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return Contains(item) && Remove(item.Key);
}
public int Count => _dictionary.Count;
public bool IsReadOnly => false;
public bool ContainsKey(TKey key)
{
return TryGetValue(key, out _);
}
public void Add(TKey key, TValue value)
{
_dictionary.Add(key, new WeakReference<TValue>(value));
}
public bool Remove(TKey key)
{
return _dictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
value = null;
bool ret = _dictionary.TryGetValue(key, out var reference) && reference.TryGetTarget(out value);
if (!ret) _dictionary.Remove(key);
return ret;
}
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<TValue>(value);
}
public ICollection<TKey> Keys => _dictionary.Keys;
public ICollection<TValue> Values => new ValueCollection(this);
public class ValueCollection : ICollection<TValue>, IReadOnlyCollection<TValue>
{
private WeakDictionary<TKey, TValue> _dictionary;
internal ValueCollection(WeakDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
public IEnumerator<TValue> 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;
}
}
}