com.wallstop-studios.unity-helpers 2.0.0-rc81.9 → 2.0.1

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 (264) hide show
  1. package/.editorconfig +1 -1
  2. package/.gitattributes +1 -1
  3. package/.githooks/pre-commit +31 -5
  4. package/.githooks/pre-push +50 -0
  5. package/.github/dependabot.yml +24 -2
  6. package/.github/scripts/check-markdown-links.ps1 +77 -0
  7. package/.github/scripts/check_markdown_links.py +89 -0
  8. package/.github/scripts/check_markdown_url_encoding.py +74 -0
  9. package/.github/scripts/validate_markdown_links.py +194 -0
  10. package/.github/workflows/csharpier-autofix.yml +152 -0
  11. package/.github/workflows/format-on-demand.yml +305 -0
  12. package/.github/workflows/lint-doc-links.yml +8 -5
  13. package/.github/workflows/markdown-json.yml +6 -2
  14. package/.github/workflows/npm-publish.yml +1 -1
  15. package/.github/workflows/prettier-autofix.yml +195 -0
  16. package/.github/workflows/update-dotnet-tools.yml +80 -0
  17. package/.github/workflows/yaml-format-lint.yml +41 -0
  18. package/.lychee.toml +4 -4
  19. package/.markdownlint.jsonc +21 -0
  20. package/.pre-commit-config.yaml +11 -3
  21. package/.yamllint.yaml +31 -0
  22. package/AGENTS.md +5 -1
  23. package/Docs/CHANGELOG.md +11 -0
  24. package/Docs/CONTRIBUTING.md +49 -0
  25. package/Docs/CONTRIBUTING.md.meta +7 -0
  26. package/{EDITOR_TOOLS_GUIDE.md → Docs/EDITOR_TOOLS_GUIDE.md} +4 -0
  27. package/Docs/EFFECTS_SYSTEM.md +1316 -0
  28. package/{EFFECTS_SYSTEM_TUTORIAL.md → Docs/EFFECTS_SYSTEM_TUTORIAL.md} +1 -1
  29. package/{GETTING_STARTED.md → Docs/GETTING_STARTED.md} +50 -64
  30. package/{GLOSSARY.md → Docs/GLOSSARY.md} +4 -4
  31. package/Docs/HELPER_UTILITIES.md +885 -0
  32. package/Docs/HELPER_UTILITIES.md.meta +7 -0
  33. package/{INDEX.md → Docs/INDEX.md} +107 -62
  34. package/Docs/MATH_AND_EXTENSIONS.md +1039 -0
  35. package/{RANDOM_PERFORMANCE.md → Docs/RANDOM_PERFORMANCE.md} +15 -15
  36. package/{RELATIONAL_COMPONENTS.md → Docs/RELATIONAL_COMPONENTS.md} +111 -84
  37. package/{SERIALIZATION.md → Docs/SERIALIZATION.md} +15 -0
  38. package/{SPATIAL_TREES_2D_GUIDE.md → Docs/SPATIAL_TREES_2D_GUIDE.md} +2 -2
  39. package/{SPATIAL_TREES_3D_GUIDE.md → Docs/SPATIAL_TREES_3D_GUIDE.md} +1 -1
  40. package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +241 -0
  41. package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +243 -0
  42. package/{THIRD_PARTY_NOTICES.md → Docs/THIRD_PARTY_NOTICES.md} +1 -1
  43. package/Docs/UTILITY_COMPONENTS.md +906 -0
  44. package/Docs/UTILITY_COMPONENTS.md.meta +7 -0
  45. package/Docs/VISUAL_COMPONENTS.md +337 -0
  46. package/Docs/VISUAL_COMPONENTS.md.meta +7 -0
  47. package/Editor/AnimationEventEditor.cs +337 -160
  48. package/Editor/Core/Helper/AnimationEventHelpers.cs +178 -152
  49. package/Editor/CustomEditors/PersistentDirectoryGUI.cs +20 -11
  50. package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +11 -2
  51. package/Editor/FitTextureSizeWindow.cs +43 -19
  52. package/Editor/PersistentDirectorySettings.cs +64 -12
  53. package/Editor/PrefabChecker.cs +72 -5
  54. package/Editor/Sprites/AnimationCopier.cs +131 -55
  55. package/Editor/Sprites/AnimationCreator.cs +63 -22
  56. package/Editor/Sprites/AnimationViewerWindow.cs +42 -6
  57. package/Editor/Sprites/TexturePlatformNameHelper.cs +50 -39
  58. package/Editor/Sprites/TextureResizerWizard.cs +23 -1
  59. package/Editor/Sprites/TextureSettingsApplierWindow.cs +148 -85
  60. package/Editor/Tools/ImageBlurTool.cs +81 -10
  61. package/Editor/Utils/EditorUi.cs +1 -1
  62. package/Editor/Utils/ScriptableObjectSingletonCreator.cs +1 -1
  63. package/README.md +428 -2433
  64. package/Runtime/AssemblyInfo.cs +4 -0
  65. package/Runtime/Core/Attributes/NotNullAttribute.cs +1 -3
  66. package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +50 -5
  67. package/Runtime/Core/DataStructure/CyclicBuffer.cs +0 -1
  68. package/Runtime/Core/DataStructure/KDTree3D.cs +1 -1
  69. package/Runtime/Core/DataStructure/OctTree3D.cs +1 -1
  70. package/Runtime/Core/Extension/AsyncOperationExtensions.cs +122 -0
  71. package/Runtime/Core/Extension/RandomExtensions.cs +68 -0
  72. package/Runtime/Core/Extension/WallstopStudiosLogger.cs +16 -0
  73. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -1
  74. package/Runtime/Core/Helper/ReflectionHelpers.cs +21 -10
  75. package/Runtime/Core/Helper/SpriteHelpers.cs +3 -1
  76. package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +45 -1
  77. package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +13 -5
  78. package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +1 -1
  79. package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +1 -1
  80. package/Runtime/Core/Serialization/ProtobufUnitySurrogates.cs +24 -29
  81. package/Runtime/Core/Serialization/Serializer.cs +101 -0
  82. package/Runtime/Integrations/Reflex/AssemblyInfo.cs +7 -0
  83. package/Runtime/Integrations/Reflex/AssemblyInfo.cs.meta +11 -0
  84. package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs +198 -0
  85. package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs.meta +11 -0
  86. package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs +86 -0
  87. package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs.meta +11 -0
  88. package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs +316 -0
  89. package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs.meta +11 -0
  90. package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs +86 -0
  91. package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs.meta +11 -0
  92. package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef +20 -0
  93. package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef.meta +7 -0
  94. package/Runtime/Integrations/Reflex.meta +8 -0
  95. package/Runtime/Integrations/VContainer/AssemblyInfo.cs +9 -0
  96. package/Runtime/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
  97. package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +96 -0
  98. package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +90 -10
  99. package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +13 -1
  100. package/Runtime/Integrations/VContainer/RelationalObjectPools.cs +114 -0
  101. package/Runtime/Integrations/VContainer/RelationalObjectPools.cs.meta +11 -0
  102. package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +16 -4
  103. package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs +241 -0
  104. package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs.meta +11 -0
  105. package/Runtime/Integrations/Zenject/AssemblyInfo.cs +9 -0
  106. package/Runtime/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
  107. package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +69 -2
  108. package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +89 -12
  109. package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +23 -1
  110. package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs +44 -0
  111. package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs.meta +11 -0
  112. package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +16 -10
  113. package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs +243 -0
  114. package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs.meta +11 -0
  115. package/Runtime/Tags/AttributeMetadataCache.cs +1 -4
  116. package/Runtime/Utils/Buffers.cs +4 -4
  117. package/Runtime/Utils/ScriptableObjectSingleton.cs +1 -2
  118. package/Runtime/Utils/SetTextureImportData.cs +3 -1
  119. package/Runtime/Utils/TextureScale.cs +10 -2
  120. package/Runtime/Visuals/UGUI/EnhancedImage.cs +6 -0
  121. package/Runtime/Visuals/UIToolkit/LayeredImage.cs +4 -1
  122. package/Samples~/DI - Reflex/README.md +527 -0
  123. package/Samples~/DI - Reflex/README.md.meta +7 -0
  124. package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs +36 -0
  125. package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs.meta +11 -0
  126. package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs +79 -0
  127. package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs.meta +11 -0
  128. package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs +30 -0
  129. package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs.meta +11 -0
  130. package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs +79 -0
  131. package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs.meta +11 -0
  132. package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef +26 -0
  133. package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef.meta +9 -0
  134. package/Samples~/DI - Reflex/Scripts.meta +8 -0
  135. package/Samples~/DI - Reflex.meta +8 -0
  136. package/Samples~/DI - VContainer/README.md +238 -56
  137. package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +22 -4
  138. package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +5 -2
  139. package/Samples~/DI - VContainer/Scripts/Spawner.cs +113 -4
  140. package/Samples~/DI - Zenject/README.md +223 -58
  141. package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +3 -0
  142. package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs +37 -0
  143. package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs.meta +12 -0
  144. package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +74 -3
  145. package/Samples~/Random - PRNG/README.md +2 -1
  146. package/Samples~/Relational Components - Basic/README.md +3 -1
  147. package/Samples~/Serialization - JSON/README.md +2 -1
  148. package/Samples~/Spatial Structures - 2D and 3D/README.md +2 -1
  149. package/Samples~/UGUI - EnhancedImage/README.md +2 -1
  150. package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +2 -1
  151. package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +16 -0
  152. package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +32 -34
  153. package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs +41 -0
  154. package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs.meta +11 -0
  155. package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef +27 -0
  156. package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef.meta +7 -0
  157. package/Tests/Editor/Integrations/Reflex.meta +8 -0
  158. package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +21 -18
  159. package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs +164 -0
  160. package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs.meta +11 -0
  161. package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +2 -1
  162. package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +3 -2
  163. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs +127 -0
  164. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs.meta +11 -0
  165. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +25 -23
  166. package/Tests/Editor/PersistentDirectorySettingsTests.cs +58 -0
  167. package/Tests/Editor/PersistentDirectorySettingsTests.cs.meta +11 -0
  168. package/Tests/Editor/PrefabCheckerReportTests.cs +32 -0
  169. package/Tests/Editor/PrefabCheckerReportTests.cs.meta +11 -0
  170. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +63 -0
  171. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs.meta +11 -0
  172. package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +1 -1
  173. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +38 -0
  174. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs.meta +11 -0
  175. package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +1 -1
  176. package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +12 -12
  177. package/Tests/Editor/Sprites/SpriteCropperTests.cs +9 -9
  178. package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +3 -3
  179. package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +18 -0
  180. package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +5 -5
  181. package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +3 -3
  182. package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +4 -4
  183. package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +4 -4
  184. package/Tests/Editor/Tools/ImageBlurToolTests.cs +22 -110
  185. package/Tests/Editor/Utils/CommonTestBase.cs +60 -1
  186. package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +6 -6
  187. package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +66 -74
  188. package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +4 -15
  189. package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +29 -29
  190. package/Tests/Runtime/Extensions/AsyncOperationExtensionsTests.cs +179 -0
  191. package/Tests/Runtime/Extensions/RandomExtensionTests.cs +55 -0
  192. package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs +445 -0
  193. package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs.meta +11 -0
  194. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef +28 -0
  195. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef.meta +7 -0
  196. package/Tests/Runtime/Integrations/Reflex.meta +8 -0
  197. package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +257 -221
  198. package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs +91 -0
  199. package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs.meta +11 -0
  200. package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +251 -233
  201. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +1 -1
  202. package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +6 -1
  203. package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +4 -1
  204. package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs +30 -0
  205. package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs.meta +11 -0
  206. package/Tests/Runtime/Serialization/JsonConverterTests.cs +8 -12
  207. package/Tests/Runtime/Serialization/JsonRoundtripComprehensiveTests.cs +4 -9
  208. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +16 -5
  209. package/Tests/Runtime/Serialization/ProtoRoundtripComprehensiveTests.cs +13 -13
  210. package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +12 -0
  211. package/Tests/Runtime/Serialization/SerializerFileIoTests.cs +105 -0
  212. package/Tests/Runtime/Serialization/SerializerFileIoTests.cs.meta +11 -0
  213. package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs +247 -0
  214. package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs.meta +11 -0
  215. package/Tests/Runtime/TestUtils/CommonTestBase.cs +99 -0
  216. package/Tests/Runtime/TestUtils/ReflexTestSupport.cs +111 -0
  217. package/Tests/Runtime/TestUtils/ReflexTestSupport.cs.meta +12 -0
  218. package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +1 -1
  219. package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +1 -1
  220. package/Tests/Runtime/Utils/LZMATests.cs +1 -1
  221. package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +5 -5
  222. package/Tests/Runtime/Visuals/EnhancedImageTests.cs +25 -56
  223. package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +1 -8
  224. package/Tests/TestUtils.meta +8 -0
  225. package/package-lock.json.meta +7 -0
  226. package/package.json +13 -4
  227. package/scripts/check-eol.ps1 +4 -5
  228. package/scripts/lint-tests.ps1 +156 -0
  229. package/scripts/lint-tests.ps1.meta +7 -0
  230. package/scripts/normalize-eol.ps1 +6 -9
  231. package/.github/workflows/csharpier.yml +0 -135
  232. package/CHANGELOG.md +0 -0
  233. package/EFFECTS_SYSTEM.md +0 -242
  234. package/MATH_AND_EXTENSIONS.md +0 -316
  235. package/SPATIAL_TREE_2D_PERFORMANCE.md +0 -238
  236. package/SPATIAL_TREE_3D_PERFORMANCE.md +0 -240
  237. /package/{CHANGELOG.md.meta → Docs/CHANGELOG.md.meta} +0 -0
  238. /package/{DATA_STRUCTURES.md → Docs/DATA_STRUCTURES.md} +0 -0
  239. /package/{DATA_STRUCTURES.md.meta → Docs/DATA_STRUCTURES.md.meta} +0 -0
  240. /package/{EDITOR_TOOLS_GUIDE.md.meta → Docs/EDITOR_TOOLS_GUIDE.md.meta} +0 -0
  241. /package/{EFFECTS_SYSTEM.md.meta → Docs/EFFECTS_SYSTEM.md.meta} +0 -0
  242. /package/{EFFECTS_SYSTEM_TUTORIAL.md.meta → Docs/EFFECTS_SYSTEM_TUTORIAL.md.meta} +0 -0
  243. /package/{GETTING_STARTED.md.meta → Docs/GETTING_STARTED.md.meta} +0 -0
  244. /package/{GLOSSARY.md.meta → Docs/GLOSSARY.md.meta} +0 -0
  245. /package/{HULLS.md → Docs/HULLS.md} +0 -0
  246. /package/{HULLS.md.meta → Docs/HULLS.md.meta} +0 -0
  247. /package/{INDEX.md.meta → Docs/INDEX.md.meta} +0 -0
  248. /package/{LICENSE.md → Docs/LICENSE.md} +0 -0
  249. /package/{LICENSE.md.meta → Docs/LICENSE.md.meta} +0 -0
  250. /package/{MATH_AND_EXTENSIONS.md.meta → Docs/MATH_AND_EXTENSIONS.md.meta} +0 -0
  251. /package/{RANDOM_PERFORMANCE.md.meta → Docs/RANDOM_PERFORMANCE.md.meta} +0 -0
  252. /package/{REFLECTION_HELPERS.md → Docs/REFLECTION_HELPERS.md} +0 -0
  253. /package/{REFLECTION_HELPERS.md.meta → Docs/REFLECTION_HELPERS.md.meta} +0 -0
  254. /package/{RELATIONAL_COMPONENTS.md.meta → Docs/RELATIONAL_COMPONENTS.md.meta} +0 -0
  255. /package/{SERIALIZATION.md.meta → Docs/SERIALIZATION.md.meta} +0 -0
  256. /package/{SINGLETONS.md → Docs/SINGLETONS.md} +0 -0
  257. /package/{SINGLETONS.md.meta → Docs/SINGLETONS.md.meta} +0 -0
  258. /package/{SPATIAL_TREES_2D_GUIDE.md.meta → Docs/SPATIAL_TREES_2D_GUIDE.md.meta} +0 -0
  259. /package/{SPATIAL_TREES_3D_GUIDE.md.meta → Docs/SPATIAL_TREES_3D_GUIDE.md.meta} +0 -0
  260. /package/{SPATIAL_TREE_2D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_2D_PERFORMANCE.md.meta} +0 -0
  261. /package/{SPATIAL_TREE_3D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_3D_PERFORMANCE.md.meta} +0 -0
  262. /package/{SPATIAL_TREE_SEMANTICS.md → Docs/SPATIAL_TREE_SEMANTICS.md} +0 -0
  263. /package/{SPATIAL_TREE_SEMANTICS.md.meta → Docs/SPATIAL_TREE_SEMANTICS.md.meta} +0 -0
  264. /package/{THIRD_PARTY_NOTICES.md.meta → Docs/THIRD_PARTY_NOTICES.md.meta} +0 -0
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 5f80cea9bb684c5785835732e55f45cd
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "WallstopStudios.UnityHelpers.Tests.Runtime.Reflex",
3
+ "rootNamespace": "WallstopStudios.UnityHelpers.Tests.Integrations.Reflex",
4
+ "references": [
5
+ "UnityEditor.TestRunner",
6
+ "UnityEngine.TestRunner",
7
+ "WallstopStudios.UnityHelpers",
8
+ "WallstopStudios.UnityHelpers.Integration.Reflex",
9
+ "WallstopStudios.UnityHelpers.Tests.Runtime",
10
+ "WallstopStudios.UnityHelpers.Tests.Editor",
11
+ "Reflex"
12
+ ],
13
+ "includePlatforms": [],
14
+ "excludePlatforms": [],
15
+ "allowUnsafeCode": false,
16
+ "overrideReferences": true,
17
+ "precompiledReferences": ["nunit.framework.dll"],
18
+ "autoReferenced": false,
19
+ "defineConstraints": ["UNITY_INCLUDE_TESTS", "REFLEX_PRESENT"],
20
+ "versionDefines": [
21
+ {
22
+ "name": "com.gustavopsantos.reflex",
23
+ "expression": "0.0.1",
24
+ "define": "REFLEX_PRESENT"
25
+ }
26
+ ],
27
+ "noEngineReferences": false
28
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 21e3440d83c64c6fa3aab578d5464e90
3
+ AssemblyDefinitionImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 7a4391f438bd4bf4b7146f7f933e18c5
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -11,22 +11,14 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
11
11
  using WallstopStudios.UnityHelpers.Core.Attributes;
12
12
  using WallstopStudios.UnityHelpers.Integrations.VContainer;
13
13
  using WallstopStudios.UnityHelpers.Tags;
14
+ using WallstopStudios.UnityHelpers.Tests.TestUtils;
14
15
 
15
- public sealed class RelationalComponentsVContainerTests
16
+ public sealed class RelationalComponentsVContainerTests : CommonTestBase
16
17
  {
17
- private readonly List<GameObject> _spawned = new();
18
-
19
- [TearDown]
20
- public void Cleanup()
18
+ [SetUp]
19
+ public void CommonSetup()
21
20
  {
22
- for (int i = 0; i < _spawned.Count; i++)
23
- {
24
- if (_spawned[i] != null)
25
- {
26
- UnityEngine.Object.DestroyImmediate(_spawned[i]);
27
- }
28
- }
29
- _spawned.Clear();
21
+ ReflexTestSupport.EnsureReflexSettings();
30
22
  }
31
23
 
32
24
  [Test]
@@ -51,14 +43,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
51
43
  Is.SameAs(tester),
52
44
  "Assigner should receive the same component instance"
53
45
  );
54
- Assert.That(
55
- tester.parentBody,
56
- Is.Not.Null,
46
+ Assert.IsTrue(
47
+ tester.parentBody != null,
57
48
  "ParentComponent assignment should set parentBody"
58
49
  );
59
- Assert.That(
60
- tester.childCollider,
61
- Is.Not.Null,
50
+ Assert.IsTrue(
51
+ tester.childCollider != null,
62
52
  "ChildComponent assignment should set childCollider"
63
53
  );
64
54
  }
@@ -73,14 +63,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
73
63
 
74
64
  resolver.AssignRelationalComponents(tester);
75
65
 
76
- Assert.That(
77
- tester.parentBody,
78
- Is.Not.Null,
66
+ Assert.IsTrue(
67
+ tester.parentBody != null,
79
68
  "Fallback should assign parentBody without a bound assigner"
80
69
  );
81
- Assert.That(
82
- tester.childCollider,
83
- Is.Not.Null,
70
+ Assert.IsTrue(
71
+ tester.childCollider != null,
84
72
  "Fallback should assign childCollider without a bound assigner"
85
73
  );
86
74
  }
@@ -89,47 +77,105 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
89
77
  public System.Collections.IEnumerator EntryPointAssignsActiveSceneComponents()
90
78
  {
91
79
  AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
92
- try
93
- {
94
- Scene scene = SceneManager.CreateScene("VContainerTestScene_Active");
95
- SceneManager.SetActiveScene(scene);
96
- ContainerBuilder builder = new();
97
- builder.RegisterInstance(cache).AsSelf();
98
- RecordingAssigner assigner = new RecordingAssigner();
99
- builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
100
- IObjectResolver resolver = builder.Build();
101
-
102
- VContainerRelationalTester tester = CreateHierarchy();
103
- GameObject rootObj = tester.transform.root.gameObject;
104
- SceneManager.MoveGameObjectToScene(rootObj, scene);
105
- yield return null;
106
-
107
- RelationalComponentEntryPoint entryPoint = new RelationalComponentEntryPoint(
108
- resolver.Resolve<IRelationalComponentAssigner>(),
109
- cache,
110
- RelationalSceneAssignmentOptions.Default
111
- );
112
- entryPoint.Initialize();
113
- yield return null;
80
+ Scene scene = CreateTempScene("VContainerTestScene_Active");
81
+ ContainerBuilder builder = new();
82
+ builder.RegisterInstance(cache).AsSelf();
83
+ RecordingAssigner assigner = new();
84
+ builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
85
+ IObjectResolver resolver = builder.Build();
114
86
 
115
- Assert.That(
116
- tester.parentBody,
117
- Is.Not.Null,
118
- "Entry point should assign parentBody in the active scene"
119
- );
120
- Assert.That(
121
- tester.childCollider,
122
- Is.Not.Null,
123
- "Entry point should assign childCollider in the active scene"
124
- );
125
- }
126
- finally
127
- {
128
- if (cache != null)
129
- {
130
- UnityEngine.Object.DestroyImmediate(cache);
131
- }
132
- }
87
+ VContainerRelationalTester tester = CreateHierarchy();
88
+ GameObject rootObj = tester.transform.root.gameObject;
89
+ SceneManager.MoveGameObjectToScene(rootObj, scene);
90
+ yield return null;
91
+
92
+ RelationalComponentEntryPoint entryPoint = new(
93
+ resolver.Resolve<IRelationalComponentAssigner>(),
94
+ cache,
95
+ RelationalSceneAssignmentOptions.Default
96
+ );
97
+ entryPoint.Initialize();
98
+ yield return null;
99
+
100
+ Assert.IsTrue(
101
+ tester.parentBody != null,
102
+ "Entry point should assign parentBody in the active scene"
103
+ );
104
+ Assert.IsTrue(
105
+ tester.childCollider != null,
106
+ "Entry point should assign childCollider in the active scene"
107
+ );
108
+ }
109
+
110
+ [UnityTest]
111
+ public System.Collections.IEnumerator SceneLoadListenerAssignsAdditiveSceneSinglePass()
112
+ {
113
+ AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
114
+ RelationalComponentAssigner assigner = new(cache);
115
+ RelationalSceneAssignmentOptions options = new(
116
+ includeInactive: true,
117
+ useSinglePassScan: true
118
+ );
119
+ RelationalSceneLoadListener listener = new(assigner, cache, options);
120
+ listener.Initialize();
121
+ TrackDisposable(listener);
122
+
123
+ Scene additive = CreateTempScene(
124
+ "VContainer_Additive_Runtime_Single",
125
+ setActive: false
126
+ );
127
+
128
+ VContainerRelationalTester tester = CreateHierarchy();
129
+ GameObject root = tester.transform.root.gameObject;
130
+ SceneManager.MoveGameObjectToScene(root, additive);
131
+
132
+ yield return null;
133
+
134
+ listener.OnSceneLoaded(additive, LoadSceneMode.Additive);
135
+ yield return null;
136
+
137
+ Assert.IsTrue(
138
+ tester.parentBody != null,
139
+ "Scene load listener should assign parentBody in single-pass mode"
140
+ );
141
+ Assert.IsTrue(
142
+ tester.childCollider != null,
143
+ "Scene load listener should assign childCollider in single-pass mode"
144
+ );
145
+ }
146
+
147
+ [UnityTest]
148
+ public System.Collections.IEnumerator SceneLoadListenerAssignsAdditiveSceneMultiPass()
149
+ {
150
+ AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
151
+ RelationalComponentAssigner assigner = new(cache);
152
+ RelationalSceneAssignmentOptions options = new(
153
+ includeInactive: true,
154
+ useSinglePassScan: false
155
+ );
156
+ RelationalSceneLoadListener listener = new(assigner, cache, options);
157
+ listener.Initialize();
158
+ TrackDisposable(listener);
159
+
160
+ Scene additive = CreateTempScene("VContainer_Additive_Runtime_Multi", setActive: false);
161
+
162
+ VContainerRelationalTester tester = CreateHierarchy();
163
+ GameObject root = tester.transform.root.gameObject;
164
+ SceneManager.MoveGameObjectToScene(root, additive);
165
+
166
+ yield return null;
167
+
168
+ listener.OnSceneLoaded(additive, LoadSceneMode.Additive);
169
+ yield return null;
170
+
171
+ Assert.IsTrue(
172
+ tester.parentBody != null,
173
+ "Scene load listener should assign parentBody in multi-pass mode"
174
+ );
175
+ Assert.IsTrue(
176
+ tester.childCollider != null,
177
+ "Scene load listener should assign childCollider in multi-pass mode"
178
+ );
133
179
  }
134
180
 
135
181
  [Test]
@@ -147,14 +193,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
147
193
  Is.SameAs(tester),
148
194
  "BuildUpWithRelations should return the same component instance"
149
195
  );
150
- Assert.That(
151
- tester.parentBody,
152
- Is.Not.Null,
196
+ Assert.IsTrue(
197
+ tester.parentBody != null,
153
198
  "BuildUpWithRelations should assign parentBody"
154
199
  );
155
- Assert.That(
156
- tester.childCollider,
157
- Is.Not.Null,
200
+ Assert.IsTrue(
201
+ tester.childCollider != null,
158
202
  "BuildUpWithRelations should assign childCollider"
159
203
  );
160
204
  }
@@ -182,14 +226,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
182
226
  IObjectResolver resolver = builder.Build();
183
227
  VContainerRelationalTester tester = CreateHierarchy();
184
228
  resolver.AssignRelationalHierarchy(tester.gameObject, includeInactiveChildren: false);
185
- Assert.That(
186
- tester.parentBody,
187
- Is.Not.Null,
229
+ Assert.IsTrue(
230
+ tester.parentBody != null,
188
231
  "AssignRelationalHierarchy should assign parentBody"
189
232
  );
190
- Assert.That(
191
- tester.childCollider,
192
- Is.Not.Null,
233
+ Assert.IsTrue(
234
+ tester.childCollider != null,
193
235
  "AssignRelationalHierarchy should assign childCollider"
194
236
  );
195
237
  }
@@ -232,24 +274,20 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
232
274
  rootTester.gameObject,
233
275
  includeInactiveChildren: false
234
276
  );
235
- Assert.That(
236
- rootTester.parentBody,
237
- Is.Not.Null,
277
+ Assert.IsTrue(
278
+ rootTester.parentBody != null,
238
279
  "Root tester should be assigned even when includeInactiveChildren is false"
239
280
  );
240
- Assert.That(
241
- rootTester.childCollider,
242
- Is.Not.Null,
281
+ Assert.IsTrue(
282
+ rootTester.childCollider != null,
243
283
  "Root tester should be assigned even when includeInactiveChildren is false"
244
284
  );
245
- Assert.That(
246
- subTester.parentBody,
247
- Is.Null,
285
+ Assert.IsTrue(
286
+ subTester.parentBody == null,
248
287
  "Inactive sub tester should be skipped when includeInactiveChildren is false"
249
288
  );
250
- Assert.That(
251
- subTester.childCollider,
252
- Is.Null,
289
+ Assert.IsTrue(
290
+ subTester.childCollider == null,
253
291
  "Inactive sub tester should be skipped when includeInactiveChildren is false"
254
292
  );
255
293
 
@@ -258,14 +296,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
258
296
  rootTester.gameObject,
259
297
  includeInactiveChildren: true
260
298
  );
261
- Assert.That(
262
- subTester.parentBody,
263
- Is.Not.Null,
299
+ Assert.IsTrue(
300
+ subTester.parentBody != null,
264
301
  "Inactive sub tester should be assigned when includeInactiveChildren is true"
265
302
  );
266
- Assert.That(
267
- subTester.childCollider,
268
- Is.Not.Null,
303
+ Assert.IsTrue(
304
+ subTester.childCollider != null,
269
305
  "Inactive sub tester should be assigned when includeInactiveChildren is true"
270
306
  );
271
307
  }
@@ -274,51 +310,39 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
274
310
  public System.Collections.IEnumerator EntryPointIgnoresNonActiveScenes()
275
311
  {
276
312
  AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
277
- try
278
- {
279
- Scene active = SceneManager.CreateScene("VContainerActiveScene_Sep");
280
- SceneManager.SetActiveScene(active);
281
-
282
- ContainerBuilder builder = new();
283
- builder.RegisterInstance(cache).AsSelf();
284
- RecordingAssigner assigner = new RecordingAssigner();
285
- builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
286
- IObjectResolver resolver = builder.Build();
287
-
288
- VContainerRelationalTester testerA = CreateHierarchy();
289
- SceneManager.MoveGameObjectToScene(testerA.transform.root.gameObject, active);
290
-
291
- Scene secondary = SceneManager.CreateScene("VContainerSecondaryScene_Sep");
292
- VContainerRelationalTester testerB = CreateHierarchy();
293
- SceneManager.MoveGameObjectToScene(testerB.transform.root.gameObject, secondary);
294
- yield return null;
295
-
296
- RelationalComponentEntryPoint entryPoint = new RelationalComponentEntryPoint(
297
- resolver.Resolve<IRelationalComponentAssigner>(),
298
- cache,
299
- new RelationalSceneAssignmentOptions(includeInactive: true)
300
- );
301
- entryPoint.Initialize();
302
- yield return null;
313
+ Scene active = CreateTempScene("VContainerActiveScene_Sep");
314
+ ContainerBuilder builder = new();
315
+ builder.RegisterInstance(cache).AsSelf();
316
+ RecordingAssigner assigner = new();
317
+ builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
318
+ IObjectResolver resolver = builder.Build();
303
319
 
304
- Assert.That(
305
- assigner.CallCount,
306
- Is.EqualTo(1),
307
- "Entry point should only process components from the active scene"
308
- );
309
- Assert.That(
310
- assigner.LastComponent,
311
- Is.SameAs(testerA),
312
- "Active scene tester should be assigned"
313
- );
314
- }
315
- finally
316
- {
317
- if (cache != null)
318
- {
319
- UnityEngine.Object.DestroyImmediate(cache);
320
- }
321
- }
320
+ VContainerRelationalTester testerA = CreateHierarchy();
321
+ SceneManager.MoveGameObjectToScene(testerA.transform.root.gameObject, active);
322
+
323
+ Scene secondary = CreateTempScene("VContainerSecondaryScene_Sep", setActive: false);
324
+ VContainerRelationalTester testerB = CreateHierarchy();
325
+ SceneManager.MoveGameObjectToScene(testerB.transform.root.gameObject, secondary);
326
+ yield return null;
327
+
328
+ RelationalComponentEntryPoint entryPoint = new(
329
+ resolver.Resolve<IRelationalComponentAssigner>(),
330
+ cache,
331
+ new RelationalSceneAssignmentOptions(includeInactive: true)
332
+ );
333
+ entryPoint.Initialize();
334
+ yield return null;
335
+
336
+ Assert.That(
337
+ assigner.CallCount,
338
+ Is.EqualTo(1),
339
+ "Entry point should only process components from the active scene"
340
+ );
341
+ Assert.That(
342
+ assigner.LastComponent,
343
+ Is.SameAs(testerA),
344
+ "Active scene tester should be assigned"
345
+ );
322
346
  }
323
347
 
324
348
  [Test]
@@ -339,25 +363,23 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
339
363
  child.transform.SetParent(middle.transform);
340
364
 
341
365
  // Expect an error about missing child component due to IncludeInactive=false on attribute
342
- UnityEngine.TestTools.LogAssert.Expect(
343
- UnityEngine.LogType.Error,
366
+ LogAssert.Expect(
367
+ LogType.Error,
344
368
  new System.Text.RegularExpressions.Regex(
345
369
  ".*Unable to find child component of type UnityEngine\\.CapsuleCollider for field 'childCollider'.*"
346
370
  )
347
371
  );
348
372
  resolver.AssignRelationalComponents(tester);
349
- Assert.That(tester.parentBody, Is.Not.Null, "Parent assignment should succeed");
350
- Assert.That(
351
- tester.childCollider,
352
- Is.Null,
373
+ Assert.IsTrue(tester.parentBody != null, "Parent assignment should succeed");
374
+ Assert.IsTrue(
375
+ tester.childCollider == null,
353
376
  "Child assignment should ignore inactive child when IncludeInactive is false"
354
377
  );
355
378
 
356
379
  child.SetActive(true);
357
380
  resolver.AssignRelationalComponents(tester);
358
- Assert.That(
359
- tester.childCollider,
360
- Is.Not.Null,
381
+ Assert.IsTrue(
382
+ tester.childCollider != null,
361
383
  "Child assignment should include active child when IncludeInactive is false"
362
384
  );
363
385
  }
@@ -366,65 +388,87 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
366
388
  public System.Collections.IEnumerator EntryPointRespectsIncludeInactiveOption()
367
389
  {
368
390
  AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
369
- try
370
- {
371
- Scene scene = SceneManager.CreateScene("VContainerTestScene_Inactive");
372
- SceneManager.SetActiveScene(scene);
373
- ContainerBuilder builder = new();
374
- builder.RegisterInstance(cache).AsSelf();
375
- RecordingAssigner assigner = new RecordingAssigner();
376
- builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
377
- IObjectResolver resolver = builder.Build();
378
-
379
- VContainerRelationalTester tester = CreateHierarchy();
380
- tester.gameObject.SetActive(false);
381
- GameObject rootObj = tester.transform.root.gameObject;
382
- SceneManager.MoveGameObjectToScene(rootObj, scene);
383
- yield return null;
384
-
385
- RelationalComponentEntryPoint disabledEntryPoint =
386
- new RelationalComponentEntryPoint(
387
- resolver.Resolve<IRelationalComponentAssigner>(),
388
- cache,
389
- new RelationalSceneAssignmentOptions(includeInactive: false)
390
- );
391
- disabledEntryPoint.Initialize();
392
- Assert.That(
393
- tester.parentBody,
394
- Is.Null,
395
- "Disabled option should skip inactive components"
396
- );
397
- Assert.That(
398
- tester.childCollider,
399
- Is.Null,
400
- "Disabled option should skip inactive components"
401
- );
391
+ Scene scene = CreateTempScene("VContainerTestScene_Inactive");
392
+ ContainerBuilder builder = new();
393
+ builder.RegisterInstance(cache).AsSelf();
394
+ RecordingAssigner assigner = new();
395
+ builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
396
+ IObjectResolver resolver = builder.Build();
402
397
 
403
- RelationalComponentEntryPoint enabledEntryPoint = new RelationalComponentEntryPoint(
404
- resolver.Resolve<IRelationalComponentAssigner>(),
405
- cache,
406
- new RelationalSceneAssignmentOptions(includeInactive: true)
407
- );
408
- enabledEntryPoint.Initialize();
409
- yield return null;
410
- Assert.That(
411
- tester.parentBody,
412
- Is.Not.Null,
413
- "Enabled option should include inactive components"
414
- );
415
- Assert.That(
416
- tester.childCollider,
417
- Is.Not.Null,
418
- "Enabled option should include inactive components"
419
- );
420
- }
421
- finally
422
- {
423
- if (cache != null)
424
- {
425
- UnityEngine.Object.DestroyImmediate(cache);
426
- }
427
- }
398
+ VContainerRelationalTester tester = CreateHierarchy();
399
+ tester.gameObject.SetActive(false);
400
+ GameObject rootObj = tester.transform.root.gameObject;
401
+ SceneManager.MoveGameObjectToScene(rootObj, scene);
402
+ yield return null;
403
+
404
+ RelationalComponentEntryPoint disabledEntryPoint = new(
405
+ resolver.Resolve<IRelationalComponentAssigner>(),
406
+ cache,
407
+ new RelationalSceneAssignmentOptions(includeInactive: false)
408
+ );
409
+ disabledEntryPoint.Initialize();
410
+ Assert.IsTrue(
411
+ tester.parentBody == null,
412
+ "Disabled option should skip inactive components"
413
+ );
414
+ Assert.IsTrue(
415
+ tester.childCollider == null,
416
+ "Disabled option should skip inactive components"
417
+ );
418
+
419
+ RelationalComponentEntryPoint enabledEntryPoint = new(
420
+ resolver.Resolve<IRelationalComponentAssigner>(),
421
+ cache,
422
+ new RelationalSceneAssignmentOptions(includeInactive: true)
423
+ );
424
+ enabledEntryPoint.Initialize();
425
+ yield return null;
426
+ Assert.IsTrue(
427
+ tester.parentBody != null,
428
+ "Enabled option should include inactive components"
429
+ );
430
+ Assert.IsTrue(
431
+ tester.childCollider != null,
432
+ "Enabled option should include inactive components"
433
+ );
434
+ }
435
+
436
+ [UnityTest]
437
+ public System.Collections.IEnumerator EntryPointUsesMultiPassWhenConfigured()
438
+ {
439
+ AttributeMetadataCache cache = CreateCacheFor(typeof(VContainerRelationalTester));
440
+ Scene scene = CreateTempScene("VContainerMultiPassScene");
441
+ ContainerBuilder builder = new();
442
+ builder.RegisterInstance(cache).AsSelf();
443
+ RecordingAssigner assigner = new();
444
+ builder.RegisterInstance(assigner).As<IRelationalComponentAssigner>();
445
+ IObjectResolver resolver = builder.Build();
446
+
447
+ VContainerRelationalTester tester = CreateHierarchy();
448
+ SceneManager.MoveGameObjectToScene(tester.transform.root.gameObject, scene);
449
+ yield return null;
450
+
451
+ RelationalComponentEntryPoint entryPoint = new(
452
+ resolver.Resolve<IRelationalComponentAssigner>(),
453
+ cache,
454
+ new RelationalSceneAssignmentOptions(
455
+ includeInactive: true,
456
+ useSinglePassScan: false
457
+ )
458
+ );
459
+ entryPoint.Initialize();
460
+ yield return null;
461
+
462
+ Assert.That(
463
+ assigner.CallCount,
464
+ Is.EqualTo(1),
465
+ "Multi-pass configuration should still assign each relational component once"
466
+ );
467
+ Assert.That(
468
+ assigner.LastComponent,
469
+ Is.SameAs(tester),
470
+ "Multi-pass configuration should target the tracked tester"
471
+ );
428
472
  }
429
473
 
430
474
  private VContainerRelationalTester CreateHierarchy()
@@ -443,27 +487,22 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
443
487
  return tester;
444
488
  }
445
489
 
446
- private GameObject Track(GameObject gameObject)
447
- {
448
- _spawned.Add(gameObject);
449
- return gameObject;
450
- }
451
-
452
- private static AttributeMetadataCache CreateCacheFor(Type componentType)
490
+ private AttributeMetadataCache CreateCacheFor(Type componentType)
453
491
  {
454
- AttributeMetadataCache cache =
455
- ScriptableObject.CreateInstance<AttributeMetadataCache>();
492
+ AttributeMetadataCache cache = Track(
493
+ ScriptableObject.CreateInstance<AttributeMetadataCache>()
494
+ );
456
495
 
457
496
  AttributeMetadataCache.RelationalFieldMetadata[] fields =
458
497
  {
459
- new AttributeMetadataCache.RelationalFieldMetadata(
498
+ new(
460
499
  nameof(VContainerRelationalTester.parentBody),
461
500
  AttributeMetadataCache.RelationalAttributeKind.Parent,
462
501
  AttributeMetadataCache.FieldKind.Single,
463
502
  typeof(Rigidbody).AssemblyQualifiedName,
464
503
  isInterface: false
465
504
  ),
466
- new AttributeMetadataCache.RelationalFieldMetadata(
505
+ new(
467
506
  nameof(VContainerRelationalTester.childCollider),
468
507
  AttributeMetadataCache.RelationalAttributeKind.Child,
469
508
  AttributeMetadataCache.FieldKind.Single,
@@ -474,10 +513,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Integrations.VContainer
474
513
 
475
514
  AttributeMetadataCache.RelationalTypeMetadata[] relationalTypes =
476
515
  {
477
- new AttributeMetadataCache.RelationalTypeMetadata(
478
- componentType.AssemblyQualifiedName,
479
- fields
480
- ),
516
+ new(componentType.AssemblyQualifiedName, fields),
481
517
  };
482
518
 
483
519
  cache._relationalTypeMetadata = relationalTypes;