Rasagar/Library/PackageCache/com.unity.collections/Unity.Collections/DoubleRewindableAllocators.cs

115 lines
4.4 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using System;
using System.Diagnostics;
using UnityEngine.Assertions;
using Unity.Collections.LowLevel.Unsafe;
namespace Unity.Collections
{
/// <summary>
/// A double rewindable allocators <see cref="RewindableAllocator"/>.
/// </summary>
unsafe public struct DoubleRewindableAllocators : IDisposable
{
RewindableAllocator* Pointer;
AllocatorHelper<RewindableAllocator> UpdateAllocatorHelper0;
AllocatorHelper<RewindableAllocator> UpdateAllocatorHelper1;
/// <summary>
/// Update the double rewindable allocators, switch Pointer to another allocator and rewind the newly switched allocator.
/// </summary>
public void Update()
{
var UpdateAllocator0 = (RewindableAllocator*)UnsafeUtility.AddressOf(ref UpdateAllocatorHelper0.Allocator);
var UpdateAllocator1 = (RewindableAllocator*)UnsafeUtility.AddressOf(ref UpdateAllocatorHelper1.Allocator);
Pointer = (Pointer == UpdateAllocator0) ? UpdateAllocator1 : UpdateAllocator0;
CheckIsCreated();
Allocator.Rewind();
}
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")]
void CheckIsCreated()
{
if (!IsCreated)
{
throw new InvalidOperationException($"DoubleRewindableAllocators is not created.");
}
}
/// <summary>
/// Retrieve the current rewindable allocator.
/// </summary>
/// <value>The Allocator retrieved.</value>
public ref RewindableAllocator Allocator
{
get
{
CheckIsCreated();
return ref UnsafeUtility.AsRef<RewindableAllocator>(Pointer);
}
}
/// <summary>
/// Check whether the double rewindable allocators is created.
/// </summary>
/// <value>True if current allocator is not null, otherwise false.</value>
public bool IsCreated => Pointer != null;
/// <summary>
/// Construct a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
/// </summary>
/// <param name="backingAllocator">Allocator used to allocate the double rewindable allocators.</param>
/// <param name="initialSizeInBytes">The initial capacity of the allocators, in bytes</param>
public DoubleRewindableAllocators(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
{
this = default;
Initialize(backingAllocator, initialSizeInBytes);
}
/// <summary>
/// Initialize a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
/// </summary>
/// <param name="backingAllocator">Allocator used to allocate the double rewindable allocators.</param>
/// <param name="initialSizeInBytes">The initial capacity of the allocators, in bytes</param>
public void Initialize(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
{
UpdateAllocatorHelper0 = new AllocatorHelper<RewindableAllocator>(backingAllocator);
UpdateAllocatorHelper1 = new AllocatorHelper<RewindableAllocator>(backingAllocator);
UpdateAllocatorHelper0.Allocator.Initialize(initialSizeInBytes);
UpdateAllocatorHelper1.Allocator.Initialize(initialSizeInBytes);
Pointer = null;
Update();
}
/// <summary>
/// the double rewindable allocators and unregister it.
/// </summary>
public void Dispose()
{
if (!IsCreated)
{
return;
}
UpdateAllocatorHelper0.Allocator.Dispose();
UpdateAllocatorHelper1.Allocator.Dispose();
UpdateAllocatorHelper0.Dispose();
UpdateAllocatorHelper1.Dispose();
}
internal bool EnableBlockFree
{
get
{
Assert.IsTrue(UpdateAllocatorHelper0.Allocator.EnableBlockFree == UpdateAllocatorHelper1.Allocator.EnableBlockFree);
return UpdateAllocatorHelper0.Allocator.EnableBlockFree;
}
set
{
UpdateAllocatorHelper0.Allocator.EnableBlockFree = value;
UpdateAllocatorHelper1.Allocator.EnableBlockFree = value;
}
}
}
}