com.wallstop-studios.unity-helpers 2.1.1 → 2.1.3

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.
Files changed (65) hide show
  1. package/AGENTS.md +1 -0
  2. package/Docs/ILIST_SORTING_PERFORMANCE.md +16 -16
  3. package/Docs/INDEX.md +1 -0
  4. package/Docs/RANDOM_PERFORMANCE.md +15 -15
  5. package/Docs/REFLECTION_HELPERS.md +84 -1
  6. package/Docs/REFLECTION_PERFORMANCE.md +169 -0
  7. package/{package-lock.json.meta → Docs/REFLECTION_PERFORMANCE.md.meta} +1 -1
  8. package/Docs/RELATIONAL_COMPONENTS.md +6 -0
  9. package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md +63 -0
  10. package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md.meta +7 -0
  11. package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +64 -64
  12. package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +64 -64
  13. package/Editor/Sprites/AnimationCopier.cs +1 -1
  14. package/Editor/Sprites/AnimationViewerWindow.cs +4 -4
  15. package/Editor/Sprites/SpriteSettingsApplierAPI.cs +2 -1
  16. package/Editor/Sprites/TextureResizerWizard.cs +4 -3
  17. package/Editor/Utils/ScriptableObjectSingletonCreator.cs +3 -3
  18. package/README.md +8 -3
  19. package/Runtime/Core/Attributes/BaseRelationalComponentAttribute.cs +147 -20
  20. package/Runtime/Core/Attributes/ChildComponentAttribute.cs +630 -117
  21. package/Runtime/Core/Attributes/NotNullAttribute.cs +5 -2
  22. package/Runtime/Core/Attributes/ParentComponentAttribute.cs +477 -103
  23. package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +26 -3
  24. package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +19 -3
  25. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +265 -92
  26. package/Runtime/Core/CodeGen.meta +8 -0
  27. package/Runtime/Core/DataStructure/ImmutableBitSet.cs +5 -20
  28. package/Runtime/Core/Helper/Helpers.cs +8 -0
  29. package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +11 -7
  30. package/Runtime/Core/Helper/Objects.cs +1 -1
  31. package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs +5142 -0
  32. package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs.meta +11 -0
  33. package/Runtime/Core/Helper/ReflectionHelpers.cs +1812 -1518
  34. package/Runtime/Core/Math/Line2D.cs +2 -4
  35. package/Runtime/Core/Math/Line3D.cs +2 -4
  36. package/Runtime/Core/Random/FlurryBurstRandom.cs +0 -6
  37. package/Runtime/Tags/AttributeMetadataCache.cs +4 -6
  38. package/Runtime/Tags/CosmeticEffectData.cs +1 -1
  39. package/Runtime/Visuals/UIToolkit/MultiFileSelectorElement.cs +3 -3
  40. package/Tests/Editor/Helper/HelpersTests.cs +2 -2
  41. package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs +87 -0
  42. package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs.meta +11 -0
  43. package/Tests/Editor/Helper/SpriteHelpersTests.cs +1 -1
  44. package/Tests/Editor/PrefabCheckerReportTests.cs +3 -3
  45. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +18 -12
  46. package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +8 -7
  47. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +2 -1
  48. package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +6 -5
  49. package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +2 -1
  50. package/Tests/Editor/Sprites/SpriteCropperTests.cs +7 -6
  51. package/Tests/Editor/Sprites/SpritePivotAdjusterAdditionalTests.cs +2 -1
  52. package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +4 -3
  53. package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +10 -9
  54. package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +2 -1
  55. package/Tests/Runtime/Helper/ObjectsTests.cs +1 -1
  56. package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs +2923 -0
  57. package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs.meta +11 -0
  58. package/Tests/Runtime/Helper/ReflectionHelperTests.cs +660 -0
  59. package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs +1238 -0
  60. package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs.meta +11 -0
  61. package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs +832 -0
  62. package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs.meta +11 -0
  63. package/package.json +1 -1
  64. package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs +0 -60
  65. package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs.meta +0 -3
@@ -0,0 +1,832 @@
1
+ namespace WallstopStudios.UnityHelpers.Tests.Performance
2
+ {
3
+ using System;
4
+ using System.Collections.Generic;
5
+ using System.Diagnostics;
6
+ using System.Globalization;
7
+ using NUnit.Framework;
8
+ using UnityEngine;
9
+ using WallstopStudios.UnityHelpers.Core.Attributes;
10
+
11
+ public sealed class RelationalComponentBenchmarkTests
12
+ {
13
+ private const int NumIterations = 10_000;
14
+
15
+ private const string DocumentPath = "Docs/RELATIONAL_COMPONENT_PERFORMANCE.md";
16
+ private const string SectionPrefix = "RELATIONAL_COMPONENTS_";
17
+
18
+ private static readonly TimeSpan BenchmarkDuration = TimeSpan.FromSeconds(1);
19
+
20
+ private static readonly Func<ScenarioResult>[] ScenarioFactories =
21
+ {
22
+ RunParentSingleScenario,
23
+ RunParentArrayScenario,
24
+ RunParentListScenario,
25
+ RunParentHashSetScenario,
26
+ RunChildSingleScenario,
27
+ RunChildArrayScenario,
28
+ RunChildListScenario,
29
+ RunChildHashSetScenario,
30
+ RunSiblingSingleScenario,
31
+ RunSiblingArrayScenario,
32
+ RunSiblingListScenario,
33
+ RunSiblingHashSetScenario,
34
+ };
35
+
36
+ [Test]
37
+ [Timeout(0)]
38
+ public void Benchmark()
39
+ {
40
+ List<ScenarioResult> results = new();
41
+ foreach (Func<ScenarioResult> factory in ScenarioFactories)
42
+ {
43
+ ScenarioResult result = factory();
44
+ results.Add(result);
45
+ }
46
+
47
+ string opsHeader =
48
+ "| Scenario | Relational Ops/s | Manual Ops/s | Rel/Manual | Iterations |";
49
+ string opsDivider = "| --- | ---: | ---: | ---: | ---: |";
50
+
51
+ UnityEngine.Debug.Log("### Relational Component Assignment Benchmarks");
52
+ UnityEngine.Debug.Log(opsHeader);
53
+ UnityEngine.Debug.Log(opsDivider);
54
+
55
+ List<string> sectionLines = new()
56
+ {
57
+ string.Format(
58
+ CultureInfo.InvariantCulture,
59
+ "_Last updated {0:yyyy-MM-dd HH:mm} UTC on {1}_",
60
+ DateTime.UtcNow,
61
+ SystemInfo.operatingSystem
62
+ ),
63
+ string.Empty,
64
+ "Numbers capture repeated `Assign*Components` calls for one second per scenario.",
65
+ "Higher operations per second are better.",
66
+ string.Empty,
67
+ "### Operations per second (higher is better)",
68
+ opsHeader,
69
+ opsDivider,
70
+ };
71
+
72
+ foreach (ScenarioResult result in results)
73
+ {
74
+ string opsRow = FormatOpsRow(result);
75
+ UnityEngine.Debug.Log(opsRow);
76
+ sectionLines.Add(opsRow);
77
+ }
78
+
79
+ sectionLines.Add(string.Empty);
80
+
81
+ string sectionName = SectionPrefix + GetOperatingSystemToken();
82
+ BenchmarkReadmeUpdater.UpdateSection(sectionName, sectionLines, DocumentPath);
83
+ }
84
+
85
+ private static ScenarioResult RunParentSingleScenario()
86
+ {
87
+ GameObject root = CreateGameObject("ParentSingleRoot");
88
+ root.AddComponent<BoxCollider>();
89
+
90
+ GameObject child = CreateGameObject("ParentSingleChild");
91
+ child.transform.SetParent(root.transform, false);
92
+
93
+ ParentSingleRelational relational = child.AddComponent<ParentSingleRelational>();
94
+ ParentSingleManual manual = child.AddComponent<ParentSingleManual>();
95
+
96
+ ScenarioResult result = ExecuteScenario(
97
+ "Parent - Single",
98
+ () => relational.Assign(),
99
+ () => manual.Assign()
100
+ );
101
+
102
+ DestroyImmediate(child);
103
+ DestroyImmediate(root);
104
+
105
+ return result;
106
+ }
107
+
108
+ private static ScenarioResult RunParentArrayScenario()
109
+ {
110
+ GameObject grandParent = CreateGameObject("ParentArrayGrand");
111
+ grandParent.AddComponent<BoxCollider>();
112
+
113
+ GameObject parent = CreateGameObject("ParentArrayParent");
114
+ parent.transform.SetParent(grandParent.transform, false);
115
+ parent.AddComponent<BoxCollider>();
116
+
117
+ GameObject child = CreateGameObject("ParentArrayChild");
118
+ child.transform.SetParent(parent.transform, false);
119
+
120
+ ParentArrayRelational relational = child.AddComponent<ParentArrayRelational>();
121
+ ParentArrayManual manual = child.AddComponent<ParentArrayManual>();
122
+
123
+ ScenarioResult result = ExecuteScenario(
124
+ "Parent - Array",
125
+ () => relational.Assign(),
126
+ () => manual.Assign()
127
+ );
128
+
129
+ DestroyImmediate(child);
130
+ DestroyImmediate(parent);
131
+ DestroyImmediate(grandParent);
132
+
133
+ return result;
134
+ }
135
+
136
+ private static ScenarioResult RunParentListScenario()
137
+ {
138
+ GameObject grandParent = CreateGameObject("ParentListGrand");
139
+ grandParent.AddComponent<BoxCollider>();
140
+
141
+ GameObject parent = CreateGameObject("ParentListParent");
142
+ parent.transform.SetParent(grandParent.transform, false);
143
+ parent.AddComponent<BoxCollider>();
144
+
145
+ GameObject child = CreateGameObject("ParentListChild");
146
+ child.transform.SetParent(parent.transform, false);
147
+
148
+ ParentListRelational relational = child.AddComponent<ParentListRelational>();
149
+ ParentListManual manual = child.AddComponent<ParentListManual>();
150
+
151
+ ScenarioResult result = ExecuteScenario(
152
+ "Parent - List",
153
+ () => relational.Assign(),
154
+ () => manual.Assign()
155
+ );
156
+
157
+ DestroyImmediate(child);
158
+ DestroyImmediate(parent);
159
+ DestroyImmediate(grandParent);
160
+
161
+ return result;
162
+ }
163
+
164
+ private static ScenarioResult RunParentHashSetScenario()
165
+ {
166
+ GameObject grandParent = CreateGameObject("ParentHashGrand");
167
+ grandParent.AddComponent<BoxCollider>();
168
+
169
+ GameObject parent = CreateGameObject("ParentHashParent");
170
+ parent.transform.SetParent(grandParent.transform, false);
171
+ parent.AddComponent<BoxCollider>();
172
+
173
+ GameObject child = CreateGameObject("ParentHashChild");
174
+ child.transform.SetParent(parent.transform, false);
175
+
176
+ ParentHashSetRelational relational = child.AddComponent<ParentHashSetRelational>();
177
+ ParentHashSetManual manual = child.AddComponent<ParentHashSetManual>();
178
+
179
+ ScenarioResult result = ExecuteScenario(
180
+ "Parent - HashSet",
181
+ () => relational.Assign(),
182
+ () => manual.Assign()
183
+ );
184
+
185
+ DestroyImmediate(child);
186
+ DestroyImmediate(parent);
187
+ DestroyImmediate(grandParent);
188
+
189
+ return result;
190
+ }
191
+
192
+ private static ScenarioResult RunChildSingleScenario()
193
+ {
194
+ GameObject parent = CreateGameObject("ChildSingleParent");
195
+
196
+ ChildSingleRelational relational = parent.AddComponent<ChildSingleRelational>();
197
+ ChildSingleManual manual = parent.AddComponent<ChildSingleManual>();
198
+
199
+ GameObject child = CreateGameObject("ChildSingleChild");
200
+ child.AddComponent<BoxCollider>();
201
+ child.transform.SetParent(parent.transform, false);
202
+
203
+ ScenarioResult result = ExecuteScenario(
204
+ "Child - Single",
205
+ () => relational.Assign(),
206
+ () => manual.Assign()
207
+ );
208
+
209
+ DestroyImmediate(child);
210
+ DestroyImmediate(parent);
211
+
212
+ return result;
213
+ }
214
+
215
+ private static ScenarioResult RunChildArrayScenario()
216
+ {
217
+ GameObject parent = CreateGameObject("ChildArrayParent");
218
+
219
+ ChildArrayRelational relational = parent.AddComponent<ChildArrayRelational>();
220
+ ChildArrayManual manual = parent.AddComponent<ChildArrayManual>();
221
+
222
+ List<GameObject> children = CreateChildColliders(parent, 6);
223
+
224
+ ScenarioResult result = ExecuteScenario(
225
+ "Child - Array",
226
+ () => relational.Assign(),
227
+ () => manual.Assign()
228
+ );
229
+
230
+ DestroyChildren(children);
231
+ DestroyImmediate(parent);
232
+
233
+ return result;
234
+ }
235
+
236
+ private static ScenarioResult RunChildListScenario()
237
+ {
238
+ GameObject parent = CreateGameObject("ChildListParent");
239
+
240
+ ChildListRelational relational = parent.AddComponent<ChildListRelational>();
241
+ ChildListManual manual = parent.AddComponent<ChildListManual>();
242
+
243
+ List<GameObject> children = CreateChildColliders(parent, 8);
244
+
245
+ ScenarioResult result = ExecuteScenario(
246
+ "Child - List",
247
+ () => relational.Assign(),
248
+ () => manual.Assign()
249
+ );
250
+
251
+ DestroyChildren(children);
252
+ DestroyImmediate(parent);
253
+
254
+ return result;
255
+ }
256
+
257
+ private static ScenarioResult RunChildHashSetScenario()
258
+ {
259
+ GameObject parent = CreateGameObject("ChildHashParent");
260
+
261
+ ChildHashSetRelational relational = parent.AddComponent<ChildHashSetRelational>();
262
+ ChildHashSetManual manual = parent.AddComponent<ChildHashSetManual>();
263
+
264
+ List<GameObject> children = CreateChildColliders(parent, 8);
265
+
266
+ ScenarioResult result = ExecuteScenario(
267
+ "Child - HashSet",
268
+ () => relational.Assign(),
269
+ () => manual.Assign()
270
+ );
271
+
272
+ DestroyChildren(children);
273
+ DestroyImmediate(parent);
274
+
275
+ return result;
276
+ }
277
+
278
+ private static ScenarioResult RunSiblingSingleScenario()
279
+ {
280
+ GameObject host = CreateGameObject("SiblingSingleHost");
281
+
282
+ SiblingSingleRelational relational = host.AddComponent<SiblingSingleRelational>();
283
+ SiblingSingleManual manual = host.AddComponent<SiblingSingleManual>();
284
+
285
+ host.AddComponent<BoxCollider>();
286
+
287
+ ScenarioResult result = ExecuteScenario(
288
+ "Sibling - Single",
289
+ () => relational.Assign(),
290
+ () => manual.Assign()
291
+ );
292
+
293
+ DestroyImmediate(host);
294
+
295
+ return result;
296
+ }
297
+
298
+ private static ScenarioResult RunSiblingArrayScenario()
299
+ {
300
+ GameObject host = CreateGameObject("SiblingArrayHost");
301
+
302
+ SiblingArrayRelational relational = host.AddComponent<SiblingArrayRelational>();
303
+ SiblingArrayManual manual = host.AddComponent<SiblingArrayManual>();
304
+
305
+ AddSiblingColliders(host, 6);
306
+
307
+ ScenarioResult result = ExecuteScenario(
308
+ "Sibling - Array",
309
+ () => relational.Assign(),
310
+ () => manual.Assign()
311
+ );
312
+
313
+ DestroyImmediate(host);
314
+
315
+ return result;
316
+ }
317
+
318
+ private static ScenarioResult RunSiblingListScenario()
319
+ {
320
+ GameObject host = CreateGameObject("SiblingListHost");
321
+
322
+ SiblingListRelational relational = host.AddComponent<SiblingListRelational>();
323
+ SiblingListManual manual = host.AddComponent<SiblingListManual>();
324
+
325
+ AddSiblingColliders(host, 8);
326
+
327
+ ScenarioResult result = ExecuteScenario(
328
+ "Sibling - List",
329
+ () => relational.Assign(),
330
+ () => manual.Assign()
331
+ );
332
+
333
+ DestroyImmediate(host);
334
+
335
+ return result;
336
+ }
337
+
338
+ private static ScenarioResult RunSiblingHashSetScenario()
339
+ {
340
+ GameObject host = CreateGameObject("SiblingHashHost");
341
+
342
+ SiblingHashSetRelational relational = host.AddComponent<SiblingHashSetRelational>();
343
+ SiblingHashSetManual manual = host.AddComponent<SiblingHashSetManual>();
344
+
345
+ AddSiblingColliders(host, 8);
346
+
347
+ ScenarioResult result = ExecuteScenario(
348
+ "Sibling - HashSet",
349
+ () => relational.Assign(),
350
+ () => manual.Assign()
351
+ );
352
+
353
+ DestroyImmediate(host);
354
+ return result;
355
+ }
356
+
357
+ private static ScenarioResult ExecuteScenario(
358
+ string label,
359
+ Action relationalAction,
360
+ Action manualAction
361
+ )
362
+ {
363
+ if (relationalAction == null)
364
+ {
365
+ throw new ArgumentNullException(nameof(relationalAction));
366
+ }
367
+
368
+ if (manualAction == null)
369
+ {
370
+ throw new ArgumentNullException(nameof(manualAction));
371
+ }
372
+
373
+ Prewarm(relationalAction);
374
+ Prewarm(manualAction);
375
+
376
+ BenchmarkMetrics relationalMetrics = Measure(relationalAction);
377
+ BenchmarkMetrics manualMetrics = Measure(manualAction);
378
+
379
+ return new ScenarioResult(label, relationalMetrics, manualMetrics);
380
+ }
381
+
382
+ private static void Prewarm(Action action)
383
+ {
384
+ for (int i = 0; i < 10; ++i)
385
+ {
386
+ action();
387
+ }
388
+ }
389
+
390
+ private static BenchmarkMetrics Measure(Action action)
391
+ {
392
+ GC.Collect();
393
+ GC.WaitForPendingFinalizers();
394
+ GC.Collect();
395
+
396
+ Stopwatch stopwatch = Stopwatch.StartNew();
397
+
398
+ int iterations = 0;
399
+ do
400
+ {
401
+ for (int i = 0; i < NumIterations; ++i)
402
+ {
403
+ action();
404
+ ++iterations;
405
+ }
406
+ } while (stopwatch.Elapsed < BenchmarkDuration);
407
+
408
+ stopwatch.Stop();
409
+ double opsPerSecond = iterations / stopwatch.Elapsed.TotalSeconds;
410
+ return new BenchmarkMetrics(opsPerSecond, iterations, stopwatch.Elapsed);
411
+ }
412
+
413
+ private static string FormatOpsRow(ScenarioResult result)
414
+ {
415
+ string ratio =
416
+ result.Manual.OpsPerSecond > 0d
417
+ ? (result.Relational.OpsPerSecond / result.Manual.OpsPerSecond).ToString(
418
+ "0.00",
419
+ CultureInfo.InvariantCulture
420
+ ) + "x"
421
+ : "n/a";
422
+
423
+ return "| "
424
+ + result.Label
425
+ + " | "
426
+ + FormatOps(result.Relational.OpsPerSecond)
427
+ + " | "
428
+ + FormatOps(result.Manual.OpsPerSecond)
429
+ + " | "
430
+ + ratio
431
+ + " | "
432
+ + result.Relational.Iterations.ToString("N0", CultureInfo.InvariantCulture)
433
+ + " |";
434
+ }
435
+
436
+ private static string FormatOps(double value)
437
+ {
438
+ if (value >= 1000d)
439
+ {
440
+ return value.ToString("N0", CultureInfo.InvariantCulture);
441
+ }
442
+
443
+ if (value >= 100d)
444
+ {
445
+ return value.ToString("N1", CultureInfo.InvariantCulture);
446
+ }
447
+
448
+ return value.ToString("0.00", CultureInfo.InvariantCulture);
449
+ }
450
+
451
+ private static GameObject CreateGameObject(string name)
452
+ {
453
+ return new GameObject(name);
454
+ }
455
+
456
+ private static List<GameObject> CreateChildColliders(GameObject parent, int count)
457
+ {
458
+ List<GameObject> children = new(count);
459
+ for (int i = 0; i < count; ++i)
460
+ {
461
+ GameObject child = CreateGameObject($"Child_{i}");
462
+ child.AddComponent<BoxCollider>();
463
+ child.transform.SetParent(parent.transform, false);
464
+ children.Add(child);
465
+ }
466
+
467
+ return children;
468
+ }
469
+
470
+ private static void AddSiblingColliders(GameObject host, int count)
471
+ {
472
+ for (int i = 0; i < count; ++i)
473
+ {
474
+ host.AddComponent<BoxCollider>();
475
+ }
476
+ }
477
+
478
+ private static void DestroyChildren(IEnumerable<GameObject> children)
479
+ {
480
+ if (children == null)
481
+ {
482
+ return;
483
+ }
484
+
485
+ foreach (GameObject child in children)
486
+ {
487
+ DestroyImmediate(child);
488
+ }
489
+ }
490
+
491
+ private static void DestroyImmediate(UnityEngine.Object obj)
492
+ {
493
+ if (obj != null)
494
+ {
495
+ UnityEngine.Object.DestroyImmediate(obj);
496
+ }
497
+ }
498
+
499
+ private static string GetOperatingSystemToken()
500
+ {
501
+ RuntimePlatform platform = Application.platform;
502
+ switch (platform)
503
+ {
504
+ case RuntimePlatform.WindowsEditor:
505
+ case RuntimePlatform.WindowsPlayer:
506
+ case RuntimePlatform.WindowsServer:
507
+ return "WINDOWS";
508
+ case RuntimePlatform.OSXEditor:
509
+ case RuntimePlatform.OSXPlayer:
510
+ return "MACOS";
511
+ case RuntimePlatform.LinuxEditor:
512
+ case RuntimePlatform.LinuxPlayer:
513
+ case RuntimePlatform.LinuxServer:
514
+ return "LINUX";
515
+ default:
516
+ return "OTHER";
517
+ }
518
+ }
519
+
520
+ private readonly struct ScenarioResult
521
+ {
522
+ public ScenarioResult(
523
+ string label,
524
+ BenchmarkMetrics relational,
525
+ BenchmarkMetrics manual
526
+ )
527
+ {
528
+ Label = label;
529
+ Relational = relational;
530
+ Manual = manual;
531
+ }
532
+
533
+ public string Label { get; }
534
+
535
+ public BenchmarkMetrics Relational { get; }
536
+
537
+ public BenchmarkMetrics Manual { get; }
538
+ }
539
+
540
+ private readonly struct BenchmarkMetrics
541
+ {
542
+ public BenchmarkMetrics(double opsPerSecond, int iterations, TimeSpan elapsed)
543
+ {
544
+ OpsPerSecond = opsPerSecond;
545
+ Iterations = iterations;
546
+ Elapsed = elapsed;
547
+ }
548
+
549
+ public double OpsPerSecond { get; }
550
+
551
+ public int Iterations { get; }
552
+
553
+ public TimeSpan Elapsed { get; }
554
+ }
555
+
556
+ private sealed class ParentSingleRelational : MonoBehaviour
557
+ {
558
+ [ParentComponent]
559
+ private BoxCollider parentCollider;
560
+
561
+ public void Assign()
562
+ {
563
+ this.AssignParentComponents();
564
+ }
565
+ }
566
+
567
+ private sealed class ParentSingleManual : MonoBehaviour
568
+ {
569
+ private BoxCollider parentCollider;
570
+
571
+ public void Assign()
572
+ {
573
+ parentCollider = GetComponentInParent<BoxCollider>();
574
+ }
575
+ }
576
+
577
+ private sealed class ParentArrayRelational : MonoBehaviour
578
+ {
579
+ [ParentComponent]
580
+ private BoxCollider[] parentColliders;
581
+
582
+ public void Assign()
583
+ {
584
+ this.AssignParentComponents();
585
+ }
586
+ }
587
+
588
+ private sealed class ParentArrayManual : MonoBehaviour
589
+ {
590
+ private BoxCollider[] parentColliders;
591
+
592
+ public void Assign()
593
+ {
594
+ parentColliders = GetComponentsInParent<BoxCollider>();
595
+ }
596
+ }
597
+
598
+ private sealed class ParentListRelational : MonoBehaviour
599
+ {
600
+ [ParentComponent]
601
+ private List<BoxCollider> parentColliders = new();
602
+
603
+ public void Assign()
604
+ {
605
+ this.AssignParentComponents();
606
+ }
607
+ }
608
+
609
+ private sealed class ParentListManual : MonoBehaviour
610
+ {
611
+ private readonly List<BoxCollider> parentColliders = new();
612
+
613
+ public void Assign()
614
+ {
615
+ GetComponentsInParent(false, parentColliders);
616
+ }
617
+ }
618
+
619
+ private sealed class ParentHashSetRelational : MonoBehaviour
620
+ {
621
+ [ParentComponent]
622
+ private HashSet<BoxCollider> parentColliders = new();
623
+
624
+ public void Assign()
625
+ {
626
+ this.AssignParentComponents();
627
+ }
628
+ }
629
+
630
+ private sealed class ParentHashSetManual : MonoBehaviour
631
+ {
632
+ private readonly HashSet<BoxCollider> parentColliders = new();
633
+
634
+ public void Assign()
635
+ {
636
+ BoxCollider[] buffer = GetComponentsInParent<BoxCollider>();
637
+ parentColliders.Clear();
638
+ for (int i = 0; i < buffer.Length; ++i)
639
+ {
640
+ parentColliders.Add(buffer[i]);
641
+ }
642
+ }
643
+ }
644
+
645
+ private sealed class ChildSingleRelational : MonoBehaviour
646
+ {
647
+ [ChildComponent(OnlyDescendants = true)]
648
+ private BoxCollider childCollider;
649
+
650
+ public void Assign()
651
+ {
652
+ this.AssignChildComponents();
653
+ }
654
+ }
655
+
656
+ private sealed class ChildSingleManual : MonoBehaviour
657
+ {
658
+ private BoxCollider childCollider;
659
+
660
+ public void Assign()
661
+ {
662
+ BoxCollider[] buffer = GetComponentsInChildren<BoxCollider>();
663
+ childCollider = buffer.Length > 0 ? buffer[0] : null;
664
+ }
665
+ }
666
+
667
+ private sealed class ChildArrayRelational : MonoBehaviour
668
+ {
669
+ [ChildComponent(OnlyDescendants = true)]
670
+ private BoxCollider[] childColliders;
671
+
672
+ public void Assign()
673
+ {
674
+ this.AssignChildComponents();
675
+ }
676
+ }
677
+
678
+ private sealed class ChildArrayManual : MonoBehaviour
679
+ {
680
+ private BoxCollider[] childColliders;
681
+
682
+ public void Assign()
683
+ {
684
+ BoxCollider[] buffer = GetComponentsInChildren<BoxCollider>();
685
+ if (buffer.Length == 0)
686
+ {
687
+ childColliders = Array.Empty<BoxCollider>();
688
+ }
689
+ else
690
+ {
691
+ childColliders = buffer;
692
+ }
693
+ }
694
+ }
695
+
696
+ private sealed class ChildListRelational : MonoBehaviour
697
+ {
698
+ [ChildComponent(OnlyDescendants = true)]
699
+ private List<BoxCollider> childColliders = new();
700
+
701
+ public void Assign()
702
+ {
703
+ this.AssignChildComponents();
704
+ }
705
+ }
706
+
707
+ private sealed class ChildListManual : MonoBehaviour
708
+ {
709
+ private readonly List<BoxCollider> childColliders = new();
710
+
711
+ public void Assign()
712
+ {
713
+ GetComponentsInChildren(childColliders);
714
+ }
715
+ }
716
+
717
+ private sealed class ChildHashSetRelational : MonoBehaviour
718
+ {
719
+ [ChildComponent(OnlyDescendants = true)]
720
+ private HashSet<BoxCollider> childColliders = new();
721
+
722
+ public void Assign()
723
+ {
724
+ this.AssignChildComponents();
725
+ }
726
+ }
727
+
728
+ private sealed class ChildHashSetManual : MonoBehaviour
729
+ {
730
+ private readonly HashSet<BoxCollider> childColliders = new();
731
+
732
+ public void Assign()
733
+ {
734
+ BoxCollider[] buffer = GetComponentsInChildren<BoxCollider>();
735
+ childColliders.Clear();
736
+ for (int i = 0; i < buffer.Length; ++i)
737
+ {
738
+ childColliders.Add(buffer[i]);
739
+ }
740
+ }
741
+ }
742
+
743
+ private sealed class SiblingSingleRelational : MonoBehaviour
744
+ {
745
+ [SiblingComponent]
746
+ private BoxCollider siblingCollider;
747
+
748
+ public void Assign()
749
+ {
750
+ this.AssignSiblingComponents();
751
+ }
752
+ }
753
+
754
+ private sealed class SiblingSingleManual : MonoBehaviour
755
+ {
756
+ private BoxCollider siblingCollider;
757
+
758
+ public void Assign()
759
+ {
760
+ siblingCollider = GetComponent<BoxCollider>();
761
+ }
762
+ }
763
+
764
+ private sealed class SiblingArrayRelational : MonoBehaviour
765
+ {
766
+ [SiblingComponent]
767
+ private BoxCollider[] siblingColliders;
768
+
769
+ public void Assign()
770
+ {
771
+ this.AssignSiblingComponents();
772
+ }
773
+ }
774
+
775
+ private sealed class SiblingArrayManual : MonoBehaviour
776
+ {
777
+ private BoxCollider[] siblingColliders;
778
+
779
+ public void Assign()
780
+ {
781
+ siblingColliders = GetComponents<BoxCollider>();
782
+ }
783
+ }
784
+
785
+ private sealed class SiblingListRelational : MonoBehaviour
786
+ {
787
+ [SiblingComponent]
788
+ private List<BoxCollider> siblingColliders = new();
789
+
790
+ public void Assign()
791
+ {
792
+ this.AssignSiblingComponents();
793
+ }
794
+ }
795
+
796
+ private sealed class SiblingListManual : MonoBehaviour
797
+ {
798
+ private readonly List<BoxCollider> siblingColliders = new();
799
+
800
+ public void Assign()
801
+ {
802
+ GetComponents(siblingColliders);
803
+ }
804
+ }
805
+
806
+ private sealed class SiblingHashSetRelational : MonoBehaviour
807
+ {
808
+ [SiblingComponent]
809
+ private HashSet<BoxCollider> siblingColliders = new();
810
+
811
+ public void Assign()
812
+ {
813
+ this.AssignSiblingComponents();
814
+ }
815
+ }
816
+
817
+ private sealed class SiblingHashSetManual : MonoBehaviour
818
+ {
819
+ private readonly HashSet<BoxCollider> siblingColliders = new();
820
+
821
+ public void Assign()
822
+ {
823
+ BoxCollider[] buffer = GetComponents<BoxCollider>();
824
+ siblingColliders.Clear();
825
+ for (int i = 0; i < buffer.Length; ++i)
826
+ {
827
+ siblingColliders.Add(buffer[i]);
828
+ }
829
+ }
830
+ }
831
+ }
832
+ }