-
Notifications
You must be signed in to change notification settings - Fork 0
/
NativeHashSet.cs
129 lines (114 loc) · 4.08 KB
/
NativeHashSet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace NativeContainers {
[StructLayout(LayoutKind.Sequential)]
[NativeContainer]
public unsafe struct NativeHashSet<T> : IDisposable where T : struct, IEquatable<T> {
[NativeDisableUnsafePtrRestriction] NativeHashSetData* buffer;
Allocator allocator;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle m_Safety;
[NativeSetClassTypeToNullOnSchedule] DisposeSentinel m_DisposeSentinel;
#endif
public NativeHashSet(int capacity, Allocator allocator) {
NativeHashSetData.AllocateHashSet<T>(capacity, allocator, out buffer);
this.allocator = allocator;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
DisposeSentinel.Create(
out m_Safety, out m_DisposeSentinel, callSiteStackDepth:8, allocator:allocator);
#endif
Clear();
}
[NativeContainer]
[NativeContainerIsAtomicWriteOnly]
public struct Concurrent {
[NativeDisableUnsafePtrRestriction] public NativeHashSetData* buffer;
[NativeSetThreadIndex] public int threadIndex;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
public AtomicSafetyHandle m_Safety;
#endif
public int Capacity {
get {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
return buffer->Capacity;
}
}
public bool TryAdd(T value) {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
return buffer->TryAddThreaded(ref value, threadIndex);
}
}
public int Capacity {
get {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
return buffer->Capacity;
}
}
public int Length {
get {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
return buffer->Length;
}
}
public bool IsCreated => buffer != null;
public void Dispose() {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckDeallocateAndThrow(m_Safety);
DisposeSentinel.Dispose(ref m_Safety, ref m_DisposeSentinel);
#endif
NativeHashSetData.DeallocateHashSet(buffer, allocator);
buffer = null;
}
public void Clear() {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
buffer->Clear<T>();
}
public Concurrent ToConcurrent() {
Concurrent concurrent;
concurrent.threadIndex = 0;
concurrent.buffer = buffer;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
concurrent.m_Safety = m_Safety;
#endif
return concurrent;
}
public bool TryAdd(T value) {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
return buffer->TryAdd(ref value, allocator);
}
public bool TryRemove(T value) {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
return buffer->TryRemove(value);
}
public bool Contains(T value) {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
return buffer->Contains(ref value);
}
public NativeArray<T> GetValueArray(Allocator allocator) {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
var result = new NativeArray<T>(Length, allocator, NativeArrayOptions.UninitializedMemory);
buffer->GetValueArray(result);
return result;
}
}
}