using System;
using System.Diagnostics;
using UnityEngine.Assertions;
using Unity.Collections.LowLevel.Unsafe;
namespace Unity.Collections
{
///
/// A double rewindable allocators .
///
unsafe public struct DoubleRewindableAllocators : IDisposable
{
RewindableAllocator* Pointer;
AllocatorHelper UpdateAllocatorHelper0;
AllocatorHelper UpdateAllocatorHelper1;
///
/// Update the double rewindable allocators, switch Pointer to another allocator and rewind the newly switched allocator.
///
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.");
}
}
///
/// Retrieve the current rewindable allocator.
///
/// The Allocator retrieved.
public ref RewindableAllocator Allocator
{
get
{
CheckIsCreated();
return ref UnsafeUtility.AsRef(Pointer);
}
}
///
/// Check whether the double rewindable allocators is created.
///
/// True if current allocator is not null, otherwise false.
public bool IsCreated => Pointer != null;
///
/// Construct a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
///
/// Allocator used to allocate the double rewindable allocators.
/// The initial capacity of the allocators, in bytes
public DoubleRewindableAllocators(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
{
this = default;
Initialize(backingAllocator, initialSizeInBytes);
}
///
/// Initialize a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
///
/// Allocator used to allocate the double rewindable allocators.
/// The initial capacity of the allocators, in bytes
public void Initialize(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
{
UpdateAllocatorHelper0 = new AllocatorHelper(backingAllocator);
UpdateAllocatorHelper1 = new AllocatorHelper(backingAllocator);
UpdateAllocatorHelper0.Allocator.Initialize(initialSizeInBytes);
UpdateAllocatorHelper1.Allocator.Initialize(initialSizeInBytes);
Pointer = null;
Update();
}
///
/// the double rewindable allocators and unregister it.
///
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;
}
}
}
}