using GameKit.Dependencies.Utilities.Types;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace GameKit.Dependencies.Utilities
{
///
/// Implement to use type with Caches.
///
public interface IResettable
{
///
/// Resets values when being placed in a cache.
///
void ResetState();
///
/// Initializes values after being retrieved from a cache.
///
void InitializeState();
}
#region Resettable caches.
///
/// Caches collections of multiple generics.
///
public static class ResettableCollectionCaches where T1 : IResettable, new() where T2 : IResettable, new()
{
///
/// Retrieves a collection.
///
///
public static Dictionary RetrieveDictionary() => CollectionCaches.RetrieveDictionary();
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Dictionary value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Dictionary value)
{
if (value == null)
return;
foreach (KeyValuePair kvp in value)
{
ResettableObjectCaches.Store(kvp.Key);
ResettableObjectCaches.Store(kvp.Value);
}
value.Clear();
CollectionCaches.Store(value);
}
}
///
/// Caches collections of multiple generics.
///
public static class ResettableT1CollectionCaches where T1 : IResettable, new()
{
///
/// Retrieves a collection.
///
///
public static Dictionary RetrieveDictionary() => CollectionCaches.RetrieveDictionary();
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Dictionary value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Dictionary value)
{
if (value == null)
return;
foreach (T1 item in value.Keys)
ResettableObjectCaches.Store(item);
value.Clear();
CollectionCaches.Store(value);
}
}
///
/// Caches collections of multiple generics.
///
public static class ResettableT2CollectionCaches where T2 : IResettable, new()
{
///
/// Retrieves a collection.
///
///
public static Dictionary RetrieveDictionary() => CollectionCaches.RetrieveDictionary();
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Dictionary value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Dictionary value)
{
if (value == null)
return;
foreach (T2 item in value.Values)
ResettableObjectCaches.Store(item);
value.Clear();
CollectionCaches.Store(value);
}
}
///
/// Caches collections of a single generic.
///
public static class ResettableCollectionCaches where T : IResettable, new()
{
///
/// Cache for ResettableRingBuffer.
///
private readonly static Stack> _resettableRingBufferCache = new();
///
/// Retrieves a collection.
///
public static ResettableRingBuffer RetrieveRingBuffer()
{
ResettableRingBuffer result;
if (!_resettableRingBufferCache.TryPop(out result))
result = new();
return result;
}
///
/// Retrieves a collection.
///
///
public static T[] RetrieveArray() => CollectionCaches.RetrieveArray();
///
/// Retrieves a collection.
///
///
public static List RetrieveList() => CollectionCaches.RetrieveList();
///
/// Retrieves a collection.
///
///
public static HashSet RetrieveHashSet() => CollectionCaches.RetrieveHashSet();
///
/// Retrieves a collection.
///
///
public static Queue RetrieveQueue() => CollectionCaches.RetrieveQueue();
///
/// Retrieves a collection.
///
///
public static BasicQueue RetrieveBasicQueue() => CollectionCaches.RetrieveBasicQueue();
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
/// Number of entries in the array from the beginning.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref ResettableRingBuffer value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
/// Number of entries in the array from the beginning.
public static void Store(ResettableRingBuffer value)
{
if (value == null)
return;
value.ResetState();
_resettableRingBufferCache.Push(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
/// Number of entries in the array from the beginning.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref T[] value, int count)
{
Store(value, count);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
/// Number of entries in the array from the beginning.
public static void Store(T[] value, int count)
{
if (value == null)
return;
for (int i = 0; i < count; i++)
ResettableObjectCaches.Store(value[i]);
CollectionCaches.Store(value, count);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref List value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(List value)
{
if (value == null)
return;
for (int i = 0; i < value.Count; i++)
ResettableObjectCaches.Store(value[i]);
value.Clear();
CollectionCaches.Store(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref HashSet value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(HashSet value)
{
if (value == null)
return;
foreach (T item in value)
ResettableObjectCaches.Store(item);
value.Clear();
CollectionCaches.Store(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Queue value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Queue value)
{
if (value == null)
return;
foreach (T item in value)
ResettableObjectCaches.Store(item);
value.Clear();
CollectionCaches.Store(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref BasicQueue value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(BasicQueue value)
{
if (value == null)
return;
while (value.TryDequeue(out T result))
ResettableObjectCaches.Store(result);
value.Clear();
CollectionCaches.Store(value);
}
}
///
/// Caches objects of a single generic.
///
public static class ResettableObjectCaches where T : IResettable, new()
{
///
/// Retrieves an instance of T.
///
public static T Retrieve()
{
T result = ObjectCaches.Retrieve();
result.InitializeState();
return result;
}
///
/// Stores an instance of T and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref T value)
{
Store(value);
value = default;
}
///
/// Stores an instance of T.
///
/// Value to store.
public static void Store(T value)
{
if (value == null)
return;
value.ResetState();
ObjectCaches.Store(value);
}
}
#endregion
#region NonResettable caches.
///
/// Caches collections of multiple generics.
///
public static class CollectionCaches
{
///
/// Cache for dictionaries.
///
private static readonly Stack> _dictionaryCache = new();
///
/// Retrieves a collection.
///
///
public static Dictionary RetrieveDictionary()
{
Dictionary result;
if (!_dictionaryCache.TryPop(out result))
result = new();
return result;
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Dictionary value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Dictionary value)
{
if (value == null)
return;
value.Clear();
_dictionaryCache.Push(value);
}
}
///
/// Caches collections of a single generic.
///
public static class CollectionCaches
{
///
/// Cache for arrays.
///
private readonly static Stack _arrayCache = new();
///
/// Cache for lists.
///
private readonly static Stack> _listCache = new();
///
/// Cache for queues.
///
private readonly static Stack> _queueCache = new();
///
/// Cache for queues.
///
private readonly static Stack> _basicQueueCache = new();
///
/// Cache for hashset.
///
private readonly static Stack> _hashsetCache = new();
///
/// Retrieves a collection.
///
///
public static T[] RetrieveArray()
{
T[] result;
if (!_arrayCache.TryPop(out result))
result = new T[0];
return result;
}
///
/// Retrieves a collection.
///
///
public static List RetrieveList()
{
List result;
if (!_listCache.TryPop(out result))
result = new();
return result;
}
///
/// Retrieves a collection.
///
///
public static Queue RetrieveQueue()
{
Queue result;
if (!_queueCache.TryPop(out result))
result = new();
return result;
}
///
/// Retrieves a collection.
///
///
public static BasicQueue RetrieveBasicQueue()
{
BasicQueue result;
if (!_basicQueueCache.TryPop(out result))
result = new();
return result;
}
///
/// Retrieves a collection adding one entry.
///
///
public static Queue RetrieveQueue(T entry)
{
Queue result;
if (!_queueCache.TryPop(out result))
result = new();
result.Enqueue(entry);
return result;
}
///
/// Retrieves a collection adding one entry.
///
///
public static List RetrieveList(T entry)
{
List result;
if (!_listCache.TryPop(out result))
result = new();
result.Add(entry);
return result;
}
///
/// Retrieves a HashSet.
///
///
public static HashSet RetrieveHashSet()
{
HashSet result;
if (!_hashsetCache.TryPop(out result))
result = new();
return result;
}
///
/// Retrieves a collection adding one entry.
///
///
public static HashSet RetrieveHashSet(T entry)
{
HashSet result;
if (!_hashsetCache.TryPop(out result))
return new();
result.Add(entry);
return result;
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
/// Number of entries in the array set default, from the beginning.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref T[] value, int count)
{
Store(value, count);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
/// Number of entries in the array from the beginning.
public static void Store(T[] value, int count)
{
if (value == null)
return;
for (int i = 0; i < count; i++)
value[i] = default;
_arrayCache.Push(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref List value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(List value)
{
if (value == null)
return;
value.Clear();
_listCache.Push(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Queue value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(Queue value)
{
if (value == null)
return;
value.Clear();
_queueCache.Push(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref BasicQueue value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(BasicQueue value)
{
if (value == null)
return;
value.Clear();
_basicQueueCache.Push(value);
}
///
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref HashSet value)
{
Store(value);
value = default;
}
///
/// Stores a collection.
///
/// Value to store.
public static void Store(HashSet value)
{
if (value == null)
return;
value.Clear();
_hashsetCache.Push(value);
}
}
///
/// Caches objects of a single generic.
///
public static class ObjectCaches where T : new()
{
///
/// Stack to use.
///
private static readonly Stack _stack = new();
///
/// Returns a value from the stack or creates an instance when the stack is empty.
///
///
public static T Retrieve()
{
T result;
if (!_stack.TryPop(out result))
result = new(); // Activator.CreateInstance();
return result;
}
///
/// Stores an instance of T and sets the original reference to default.
/// Method will not execute if value is null.
///
/// Value to store.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref T value)
{
Store(value);
value = default;
}
///
/// Stores a value to the stack.
///
///
public static void Store(T value)
{
if (value == null)
return;
_stack.Push(value);
}
}
#endregion
}