115 lines
4.4 KiB
C#
115 lines
4.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|