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; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |