com.wallstop-studios.unity-helpers 2.0.0-rc23 → 2.0.0-rc24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
# A Grab-Bag
|
|
2
2
|
Various Unity Helpers. Includes many deterministic, seedable random number generators.
|
|
3
|
+
|
|
4
|
+
# To Install as Unity Package
|
|
5
|
+
1. Open Unity Package Manager
|
|
6
|
+
2. (Optional) Enable Pre-release packages to get the latest, cutting-edge builds
|
|
7
|
+
3. Open the Advanced Package Settings
|
|
8
|
+
4. Add an entry for a new "Scoped Registry"
|
|
9
|
+
- Name: `NPM`
|
|
10
|
+
- URL: `https://registry.npmjs.org`
|
|
11
|
+
- Scope(s): `com.wallstop-studios.unity-helpers`
|
|
12
|
+
5. Resolve the latest `com.wallstop-studios.unity-helpers`
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
public sealed class CyclicBuffer<T> : IReadOnlyList<T>
|
|
11
11
|
{
|
|
12
12
|
public int Count { get; private set; }
|
|
13
|
+
public bool IsReadOnly => false;
|
|
14
|
+
|
|
13
15
|
public readonly int capacity;
|
|
14
16
|
|
|
15
17
|
private readonly List<T> _buffer;
|
|
@@ -88,28 +90,24 @@
|
|
|
88
90
|
/* Simply reset state */
|
|
89
91
|
Count = 0;
|
|
90
92
|
_position = 0;
|
|
93
|
+
_buffer.Clear();
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
public bool
|
|
96
|
+
public bool Contains(T item)
|
|
94
97
|
{
|
|
95
|
-
|
|
96
|
-
if (InBounds(firstIndex))
|
|
97
|
-
{
|
|
98
|
-
value = _buffer[AdjustedIndexFor(firstIndex)];
|
|
99
|
-
return true;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
value = default;
|
|
103
|
-
return false;
|
|
98
|
+
return _buffer.Contains(item);
|
|
104
99
|
}
|
|
105
100
|
|
|
106
101
|
private int AdjustedIndexFor(int index)
|
|
107
102
|
{
|
|
108
|
-
|
|
103
|
+
long longCapacity = capacity;
|
|
104
|
+
unchecked
|
|
109
105
|
{
|
|
110
|
-
|
|
106
|
+
int adjustedIndex = (int)(
|
|
107
|
+
(_position - 1L + longCapacity - (_buffer.Count - 1 - index)) % longCapacity
|
|
108
|
+
);
|
|
109
|
+
return adjustedIndex;
|
|
111
110
|
}
|
|
112
|
-
return (_position - 1 + capacity - index) % capacity;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
private void BoundsCheck(int index)
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
Used to cache strings, meant to be used in place of strings as keys for when a Dictionary
|
|
8
8
|
has a known set of values
|
|
9
9
|
*/
|
|
10
|
+
[Serializable]
|
|
10
11
|
public sealed class StringWrapper : IEquatable<StringWrapper>, IComparable<StringWrapper>
|
|
11
12
|
{
|
|
12
13
|
private static readonly ConcurrentDictionary<string, StringWrapper> Cache = new();
|
|
@@ -25,6 +25,28 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
[Test]
|
|
29
|
+
public void CapacityInitializedOk()
|
|
30
|
+
{
|
|
31
|
+
for (int i = 0; i < NumTries; i++)
|
|
32
|
+
{
|
|
33
|
+
int capacity = PRNG.Instance.Next(1, int.MaxValue);
|
|
34
|
+
CyclicBuffer<int> buffer = new(capacity);
|
|
35
|
+
Assert.AreEqual(capacity, buffer.capacity);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[Test]
|
|
40
|
+
public void CountInitializedOk()
|
|
41
|
+
{
|
|
42
|
+
for (int i = 0; i < NumTries; i++)
|
|
43
|
+
{
|
|
44
|
+
int capacity = PRNG.Instance.Next(1, int.MaxValue);
|
|
45
|
+
CyclicBuffer<int> buffer = new(capacity);
|
|
46
|
+
Assert.AreEqual(0, buffer.Count);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
28
50
|
[Test]
|
|
29
51
|
public void ZeroCapacityOk()
|
|
30
52
|
{
|
|
@@ -49,7 +71,14 @@
|
|
|
49
71
|
int value = PRNG.Instance.Next();
|
|
50
72
|
buffer.Add(value);
|
|
51
73
|
expected.Add(value);
|
|
52
|
-
|
|
74
|
+
if (!expected.SequenceEqual(buffer))
|
|
75
|
+
{
|
|
76
|
+
Assert.Fail(
|
|
77
|
+
$"Failure at iteration {i}, capacity={buffer.capacity}, "
|
|
78
|
+
+ $"capacityMultiplier={CapacityMultiplier}\n"
|
|
79
|
+
+ $"Expected: [{string.Join(",", expected)}], Actual: [{string.Join(",", buffer)}]"
|
|
80
|
+
);
|
|
81
|
+
}
|
|
53
82
|
}
|
|
54
83
|
}
|
|
55
84
|
|
|
@@ -68,10 +97,58 @@
|
|
|
68
97
|
}
|
|
69
98
|
}
|
|
70
99
|
|
|
100
|
+
[Test]
|
|
101
|
+
public void InitialElementsVariableSize()
|
|
102
|
+
{
|
|
103
|
+
for (int i = 0; i < NumTries; ++i)
|
|
104
|
+
{
|
|
105
|
+
int capacity = PRNG.Instance.Next(100, 1_000);
|
|
106
|
+
int[] elements = Enumerable
|
|
107
|
+
.Range(0, (int)(capacity * PRNG.Instance.NextFloat(0.5f, 1.5f)))
|
|
108
|
+
.Select(_ => PRNG.Instance.Next())
|
|
109
|
+
.ToArray();
|
|
110
|
+
CyclicBuffer<int> buffer = new(capacity, elements);
|
|
111
|
+
if (capacity < elements.Length)
|
|
112
|
+
{
|
|
113
|
+
Assert.IsTrue(elements.Skip(elements.Length - capacity).SequenceEqual(buffer));
|
|
114
|
+
}
|
|
115
|
+
else
|
|
116
|
+
{
|
|
117
|
+
Assert.IsTrue(elements.SequenceEqual(buffer));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
[Test]
|
|
123
|
+
public void InitialElementsSizeSameAsCapacity()
|
|
124
|
+
{
|
|
125
|
+
for (int i = 0; i < NumTries; ++i)
|
|
126
|
+
{
|
|
127
|
+
int capacity = PRNG.Instance.Next(100, 1_000);
|
|
128
|
+
int[] elements = Enumerable
|
|
129
|
+
.Range(0, capacity)
|
|
130
|
+
.Select(_ => PRNG.Instance.Next())
|
|
131
|
+
.ToArray();
|
|
132
|
+
CyclicBuffer<int> buffer = new(capacity, elements);
|
|
133
|
+
Assert.IsTrue(elements.SequenceEqual(buffer));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
[Test]
|
|
138
|
+
public void InitialElementsEmptyInput()
|
|
139
|
+
{
|
|
140
|
+
for (int i = 0; i < NumTries; ++i)
|
|
141
|
+
{
|
|
142
|
+
int capacity = PRNG.Instance.Next(100, 1_000);
|
|
143
|
+
CyclicBuffer<int> buffer = new(capacity, Array.Empty<int>());
|
|
144
|
+
Assert.IsTrue(Array.Empty<int>().SequenceEqual(buffer));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
71
148
|
[Test]
|
|
72
149
|
public void NormalAndWrappingBehavior()
|
|
73
150
|
{
|
|
74
|
-
|
|
151
|
+
LinkedList<int> expected = new();
|
|
75
152
|
for (int i = 0; i < NumTries; ++i)
|
|
76
153
|
{
|
|
77
154
|
int capacity = PRNG.Instance.Next(100, 1_000);
|
|
@@ -81,20 +158,55 @@
|
|
|
81
158
|
for (int j = 0; j < capacity * CapacityMultiplier; ++j)
|
|
82
159
|
{
|
|
83
160
|
int newValue = PRNG.Instance.Next();
|
|
84
|
-
|
|
161
|
+
expected.AddLast(newValue);
|
|
162
|
+
while (capacity < expected.Count)
|
|
85
163
|
{
|
|
86
|
-
expected
|
|
164
|
+
expected.RemoveFirst();
|
|
87
165
|
}
|
|
88
|
-
|
|
166
|
+
buffer.Add(newValue);
|
|
167
|
+
Assert.AreEqual(expected.Count, buffer.Count);
|
|
168
|
+
if (!expected.SequenceEqual(buffer))
|
|
89
169
|
{
|
|
90
|
-
|
|
170
|
+
Assert.Fail(
|
|
171
|
+
$"Failure at iteration {i}, j={j}, capacity={buffer.capacity}, "
|
|
172
|
+
+ $"capacityMultiplier={CapacityMultiplier}\n"
|
|
173
|
+
+ $"Expected: [{string.Join(",", expected)}], Actual: [{string.Join(",", buffer)}]"
|
|
174
|
+
);
|
|
91
175
|
}
|
|
92
|
-
buffer.Add(newValue);
|
|
93
|
-
Assert.IsTrue(
|
|
94
|
-
expected.SequenceEqual(buffer),
|
|
95
|
-
$"Failure at iteration {i}, j={j}, capacity={capacity}, capacityMultiplier={CapacityMultiplier}"
|
|
96
|
-
);
|
|
97
176
|
}
|
|
177
|
+
|
|
178
|
+
foreach (int item in expected)
|
|
179
|
+
{
|
|
180
|
+
Assert.IsTrue(buffer.Contains(item));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
for (int j = 0; j < NumTries; ++j)
|
|
184
|
+
{
|
|
185
|
+
Assert.IsFalse(buffer.Contains(PRNG.Instance.Next(int.MinValue, -1)));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
[Test]
|
|
191
|
+
public void ClearOk()
|
|
192
|
+
{
|
|
193
|
+
for (int i = 0; i < NumTries; ++i)
|
|
194
|
+
{
|
|
195
|
+
int capacity = PRNG.Instance.Next(100, 1_000);
|
|
196
|
+
CyclicBuffer<int> buffer = new(capacity);
|
|
197
|
+
float fillPercent = PRNG.Instance.NextFloat(0.5f, 1.5f);
|
|
198
|
+
for (int j = 0; j < capacity * fillPercent; ++j)
|
|
199
|
+
{
|
|
200
|
+
buffer.Add(PRNG.Instance.Next());
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
Assert.AreNotEqual(0, buffer.Count);
|
|
204
|
+
Assert.IsFalse(Array.Empty<int>().SequenceEqual(buffer));
|
|
205
|
+
buffer.Clear();
|
|
206
|
+
|
|
207
|
+
Assert.AreEqual(0, buffer.Count);
|
|
208
|
+
Assert.AreEqual(capacity, buffer.capacity);
|
|
209
|
+
Assert.IsTrue(Array.Empty<int>().SequenceEqual(buffer));
|
|
98
210
|
}
|
|
99
211
|
}
|
|
100
212
|
}
|