csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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.
70 lines
1.8 KiB
70 lines
1.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Avalonia.Utilities;
|
|
|
|
/// <summary>
|
|
/// Maintains a set of objects with reference counts
|
|
/// </summary>
|
|
internal class RefTrackingDictionary<TKey> : Dictionary<TKey, int> where TKey : class
|
|
{
|
|
/// <summary>
|
|
/// Increase reference count for a key by 1.
|
|
/// </summary>
|
|
/// <returns>true if key was added to the dictionary, false otherwise</returns>
|
|
public bool AddRef(TKey key)
|
|
{
|
|
#if NET5_0_OR_GREATER
|
|
ref var count = ref CollectionsMarshal.GetValueRefOrAddDefault(this, key, out var _);
|
|
count++;
|
|
#else
|
|
TryGetValue(key, out var count);
|
|
count++;
|
|
this[key] = count;
|
|
#endif
|
|
return count == 1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decrease reference count for a key by 1.
|
|
/// </summary>
|
|
/// <returns>true if key was removed to the dictionary, false otherwise</returns>
|
|
public bool ReleaseRef(TKey key)
|
|
{
|
|
#if NET5_0_OR_GREATER
|
|
ref var count = ref CollectionsMarshal.GetValueRefOrNullRef(this, key);
|
|
if (Unsafe.IsNullRef(ref count))
|
|
#if DEBUG
|
|
throw new InvalidOperationException("Attempting to release a non-referenced object");
|
|
#else
|
|
return false;
|
|
#endif // DEBUG
|
|
count--;
|
|
if (count == 0)
|
|
{
|
|
Remove(key);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
#else
|
|
if (!TryGetValue(key, out var count))
|
|
#if DEBUG
|
|
throw new InvalidOperationException("Attempting to release a non-referenced object");
|
|
#else
|
|
return false;
|
|
#endif // DEBUG
|
|
count--;
|
|
if (count == 0)
|
|
{
|
|
Remove(key);
|
|
return true;
|
|
}
|
|
|
|
this[key] = count;
|
|
return false;
|
|
#endif
|
|
}
|
|
}
|