A game about forced loneliness, made by TACStudios
1using System;
2using System.Diagnostics;
3using UnityEngine.Assertions;
4using Unity.Collections.LowLevel.Unsafe;
5
6namespace Unity.Collections
7{
8 /// <summary>
9 /// A double rewindable allocators <see cref="RewindableAllocator"/>.
10 /// </summary>
11 unsafe public struct DoubleRewindableAllocators : IDisposable
12 {
13 RewindableAllocator* Pointer;
14 AllocatorHelper<RewindableAllocator> UpdateAllocatorHelper0;
15 AllocatorHelper<RewindableAllocator> UpdateAllocatorHelper1;
16
17 /// <summary>
18 /// Update the double rewindable allocators, switch Pointer to another allocator and rewind the newly switched allocator.
19 /// </summary>
20 public void Update()
21 {
22 var UpdateAllocator0 = (RewindableAllocator*)UnsafeUtility.AddressOf(ref UpdateAllocatorHelper0.Allocator);
23 var UpdateAllocator1 = (RewindableAllocator*)UnsafeUtility.AddressOf(ref UpdateAllocatorHelper1.Allocator);
24 Pointer = (Pointer == UpdateAllocator0) ? UpdateAllocator1 : UpdateAllocator0;
25 CheckIsCreated();
26 Allocator.Rewind();
27 }
28
29 [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")]
30 void CheckIsCreated()
31 {
32 if (!IsCreated)
33 {
34 throw new InvalidOperationException($"DoubleRewindableAllocators is not created.");
35 }
36 }
37
38 /// <summary>
39 /// Retrieve the current rewindable allocator.
40 /// </summary>
41 /// <value>The Allocator retrieved.</value>
42 public ref RewindableAllocator Allocator
43 {
44 get
45 {
46 CheckIsCreated();
47 return ref UnsafeUtility.AsRef<RewindableAllocator>(Pointer);
48 }
49 }
50
51 /// <summary>
52 /// Check whether the double rewindable allocators is created.
53 /// </summary>
54 /// <value>True if current allocator is not null, otherwise false.</value>
55 public bool IsCreated => Pointer != null;
56
57 /// <summary>
58 /// Construct a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
59 /// </summary>
60 /// <param name="backingAllocator">Allocator used to allocate the double rewindable allocators.</param>
61 /// <param name="initialSizeInBytes">The initial capacity of the allocators, in bytes</param>
62 public DoubleRewindableAllocators(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
63 {
64 this = default;
65 Initialize(backingAllocator, initialSizeInBytes);
66 }
67
68 /// <summary>
69 /// Initialize a double rewindable allocators by allocating the allocators from backingAllocator and registering them.
70 /// </summary>
71 /// <param name="backingAllocator">Allocator used to allocate the double rewindable allocators.</param>
72 /// <param name="initialSizeInBytes">The initial capacity of the allocators, in bytes</param>
73 public void Initialize(AllocatorManager.AllocatorHandle backingAllocator, int initialSizeInBytes)
74 {
75 UpdateAllocatorHelper0 = new AllocatorHelper<RewindableAllocator>(backingAllocator);
76 UpdateAllocatorHelper1 = new AllocatorHelper<RewindableAllocator>(backingAllocator);
77 UpdateAllocatorHelper0.Allocator.Initialize(initialSizeInBytes);
78 UpdateAllocatorHelper1.Allocator.Initialize(initialSizeInBytes);
79 Pointer = null;
80 Update();
81 }
82
83 /// <summary>
84 /// the double rewindable allocators and unregister it.
85 /// </summary>
86 public void Dispose()
87 {
88 if (!IsCreated)
89 {
90 return;
91 }
92
93 UpdateAllocatorHelper0.Allocator.Dispose();
94 UpdateAllocatorHelper1.Allocator.Dispose();
95
96 UpdateAllocatorHelper0.Dispose();
97 UpdateAllocatorHelper1.Dispose();
98 }
99
100 internal bool EnableBlockFree
101 {
102 get
103 {
104 Assert.IsTrue(UpdateAllocatorHelper0.Allocator.EnableBlockFree == UpdateAllocatorHelper1.Allocator.EnableBlockFree);
105 return UpdateAllocatorHelper0.Allocator.EnableBlockFree;
106 }
107 set
108 {
109 UpdateAllocatorHelper0.Allocator.EnableBlockFree = value;
110 UpdateAllocatorHelper1.Allocator.EnableBlockFree = value;
111 }
112 }
113 }
114}