From 55ca11e682ff9b685350bf62f5ef59caad82b7ac Mon Sep 17 00:00:00 2001 From: Unity Technologies <@unity> Date: Fri, 6 Sep 2024 00:00:00 +0000 Subject: [PATCH] com.unity.entities@1.3.2 ## [1.3.2] - 2024-09-06 ### Added * Overloads for `ComponentLookup.HasComponent`, `ComponentLookup.TryGetComponent`, `BufferLookup.HasBuffer`, and `BufferLookup.TryGetBuffer` adding parameter `out bool entityExists`, as well as dedicated `ComponentLookup.EntityExists` and `BufferLookup.EntityExists` APIs, to allow user-code to distinguish entity non-existence from component non-existence without additional boilerplate, inside jobs. * adding missing dependencies `com.unity.modules.physics`, `com.unity.modules.uielements`. ### Changed * Updated Burst dependency to version 1.8.17 * Add API docs discouraging the use of the `ExclusiveEntityTransaction.EntityManager` property. Many EntityManager operations are not safe to use within the context of an ExclusiveEntityTransaction; only the methods directly exposed by `ExclusiveEntityTransaction` are guaranteed to work correctly. * Add API docs discouraging the creation of `EntityQuery` objects with multiple query descriptions. This feature works in narrow contexts, but is known to cause errors and incompatibilities with other DOTS features. * Add API docs to note that enabling and disabling components inside `IJobEntityChunkBeginEnd.OnChunkBegin()` does not affect the entities iterated in the current chunk, as its `chunkEnabledMask` has already been computed. * Zero-size `IBufferElementData` and `ISharedComponentData` structs no longer cause the TypeManager to throw during initialization. Zero-size buffer and shared components are usually a sign of pointless waste (especially buffer components, which have a significant chunk-memory cost even if the actual elements are empty), but they shouldn't cause a fatal error. ### Fixed * Various SGICE002 errors that happen if you type invalid C# code * Various SGICE003 errors that happen if you type invalid C# code * NullReferenceException on UnityObjectRef after Asset Garbage Collection (This fix requires editor versions 2022.3.43f1 and 6000.0.16f1 and beyond) --- CHANGELOG.md | 35 ++ Documentation~/concepts-safety.md | 8 +- Documentation~/index.md | 1 - Documentation~/systems-entityquery-create.md | 14 +- Unity.Deformations/DeformationComponents.cs | 2 +- .../BufferLookupPerformanceTests.cs | 445 +++++++++--------- .../BufferElementDataTests.cs | 38 +- .../CleanupBufferElementDataTests.cs | 25 +- Unity.Entities.Tests/ComponentSystemTests.cs | 81 ++++ .../EntityRemapUtilityTests.cs | 41 +- .../EntityTransactionTests.cs | 2 + .../ForEachBufferAccessTests.cs | 8 +- .../SharedComponentDataTests.cs | 14 + Unity.Entities.Tests/SizeTests.cs | 5 +- Unity.Entities.Tests/TypeManagerTests.cs | 92 ++-- .../Unity.Entities.Tests.asmdef | 15 +- Unity.Entities.Tests/UnityObjectRefTests.cs | 179 +++++++ .../UnityObjectRefTests.cs.meta | 11 + .../Diff/EntityDifferComponentChanges.cs | 4 +- Unity.Entities/Diff/EntityPatcher.cs | 25 +- Unity.Entities/EntityCommandBuffer.cs | 4 +- Unity.Entities/EntityComponentStore.cs | 15 +- ...tityComponentStoreCreateDestroyEntities.cs | 2 +- Unity.Entities/EntityComponentStoreDebug.cs | 16 +- Unity.Entities/EntityDataAccess.cs | 4 +- Unity.Entities/EntityManager.cs | 10 +- Unity.Entities/EntityRemapUtility.cs | 35 +- Unity.Entities/ExclusiveEntityTransaction.cs | 26 +- Unity.Entities/IJobEntity.cs | 7 + .../Internal/InternalCompilerInterface.cs | 2 +- Unity.Entities/Iterators/BufferLookup.cs | 48 +- Unity.Entities/Iterators/ComponentLookup.cs | 54 ++- .../Iterators/EntityQueryBuilder.cs | 4 + Unity.Entities/ManagedComponentStore.cs | 2 +- .../Serialization/UnityObjectRef.cs | 277 ++++++++++- .../SourceGenerators/AspectGenerator.dll | Bin 85504 -> 85504 bytes .../SourceGenerators/AspectGenerator.pdb | Bin 25508 -> 26092 bytes Unity.Entities/SourceGenerators/Common.dll | Bin 43008 -> 43008 bytes Unity.Entities/SourceGenerators/Common.pdb | Bin 18884 -> 19476 bytes .../SourceGenerators/JobEntityGenerator.dll | Bin 80896 -> 80384 bytes .../SourceGenerators/JobEntityGenerator.pdb | Bin 24388 -> 24900 bytes .../IjeSchedulingSyntaxWalker.cs | 6 +- .../JobEntityDescription.cs | 8 + .../JobEntityGenerator/JobEntityModule.cs | 4 +- .../SystemGenerator.Common.dll | Bin 54784 -> 54784 bytes .../SystemGenerator.Common.pdb | Bin 23336 -> 23944 bytes ...temGenerator.EntityQueryBulkOperations.dll | Bin 15360 -> 15360 bytes ...temGenerator.EntityQueryBulkOperations.pdb | Bin 10876 -> 11452 bytes .../SystemGenerator.LambdaJobs.dll | Bin 148480 -> 148992 bytes .../SystemGenerator.LambdaJobs.pdb | Bin 40732 -> 41328 bytes .../SystemGenerator.SystemAPI.Query.dll | Bin 68096 -> 67584 bytes .../SystemGenerator.SystemAPI.Query.pdb | Bin 21892 -> 22480 bytes ...SystemGenerator.SystemAPI.QueryBuilder.dll | Bin 25088 -> 25088 bytes ...SystemGenerator.SystemAPI.QueryBuilder.pdb | Bin 13352 -> 13932 bytes .../SystemGenerator.SystemAPI.dll | Bin 31232 -> 32256 bytes .../SystemGenerator.SystemAPI.pdb | Bin 14300 -> 14988 bytes .../SourceGenerators/SystemGenerator.dll | Bin 19968 -> 19968 bytes .../SourceGenerators/SystemGenerator.pdb | Bin 12912 -> 13476 bytes .../Unity.Entities.Analyzer.CodeFixes.dll | Bin 18944 -> 18944 bytes .../Unity.Entities.Analyzer.CodeFixes.pdb | Bin 11492 -> 12064 bytes .../Unity.Entities.Analyzer.dll | Bin 30208 -> 30208 bytes .../Unity.Entities.Analyzer.pdb | Bin 13784 -> 14368 bytes Unity.Entities/Types/TypeManager.cs | 88 ++-- Unity.Entities/Unity.Entities.asmdef | 12 +- ValidationExceptions.json | 17 +- package.json | 16 +- 66 files changed, 1311 insertions(+), 391 deletions(-) create mode 100644 Unity.Entities.Tests/UnityObjectRefTests.cs create mode 100644 Unity.Entities.Tests/UnityObjectRefTests.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index 2837da32..3d9e16d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ uid: changelog # Changelog +## [1.3.2] - 2024-09-06 + +### Added + +* Overloads for `ComponentLookup.HasComponent`, `ComponentLookup.TryGetComponent`, `BufferLookup.HasBuffer`, and `BufferLookup.TryGetBuffer` adding parameter `out bool entityExists`, as well as dedicated `ComponentLookup.EntityExists` and `BufferLookup.EntityExists` APIs, to allow user-code to distinguish entity non-existence from component non-existence without additional boilerplate, inside jobs. +* adding missing dependencies `com.unity.modules.physics`, `com.unity.modules.uielements`. + +### Changed + +* Updated Burst dependency to version 1.8.17 +* Add API docs discouraging the use of the `ExclusiveEntityTransaction.EntityManager` property. Many EntityManager operations are not safe to use within the context of an ExclusiveEntityTransaction; only the methods directly exposed by `ExclusiveEntityTransaction` are guaranteed to work correctly. +* Add API docs discouraging the creation of `EntityQuery` objects with multiple query descriptions. This feature works in narrow contexts, but is known to cause errors and incompatibilities with other DOTS features. +* Add API docs to note that enabling and disabling components inside `IJobEntityChunkBeginEnd.OnChunkBegin()` does not affect the entities iterated in the current chunk, as its `chunkEnabledMask` has already been computed. +* Zero-size `IBufferElementData` and `ISharedComponentData` structs no longer cause the TypeManager to throw during initialization. Zero-size buffer and shared components are usually a sign of pointless waste (especially buffer components, which have a significant chunk-memory cost even if the actual elements are empty), but they shouldn't cause a fatal error. + +### Fixed + +* Various SGICE002 errors that happen if you type invalid C# code +* Various SGICE003 errors that happen if you type invalid C# code +* NullReferenceException on UnityObjectRef after Asset Garbage Collection (This fix requires editor versions 2022.3.43f1 and 6000.0.16f1 and beyond) + + ## [1.3.0-pre.4] - 2024-07-17 ### Changed @@ -22,6 +44,7 @@ uid: changelog * EntityComponentStore leaked memory during domain reload. + ## [1.3.0-exp.1] - 2024-06-11 ### Added @@ -68,6 +91,18 @@ uid: changelog ### Known Issues +## [1.2.4] - 2024-08-14 + +### Fixed + +* Debug proxies (used by external debuggers) were sometimes using invalid field offsets when inspecting structs in blob assets. This led to incorrect values being reported in debugger watch windows. In particular, this would be triggered by the use of bool fields in blob asset structs. +* Entity version numbers could go back to 1 after reallocation in some edge cases. +* When building a content update, a temporary path was getting created in the drive root instead of the Library folder. This would also cause content update builds to grow in size every time they were built. The folder is now created in the Library correctly. +* Error in build when sprites are contained in subscenes has been removed. +* Regression in compilation time with assemblies with lots of system methods. +* EntityComponentStore leaked memory during domain reload. + + ## [1.2.3] - 2024-05-30 ### Fixed diff --git a/Documentation~/concepts-safety.md b/Documentation~/concepts-safety.md index ecadaab9..660a1071 100644 --- a/Documentation~/concepts-safety.md +++ b/Documentation~/concepts-safety.md @@ -17,6 +17,12 @@ One of the most common issues with safety in Entities is when [structural change The Entities API stores data in chunks that are typically accessed through the [job system](xref:JobSystem) or the main thread. The job system typically handles all safety of data that's passed in with NativeContainers, and uses notations to mark if the data is read from, written to, or both. However, any API that causes a structural change might make this data move in memory and invalidate any reference held to that data. +#### ExclusiveEntityTransaction + +In general, all structural changes must be made on the main thread using the world's `EntityManager`. The `ExclusiveEntityTransaction` feature allows you to temporarily place an `EntityManager` into a mode where a single worker thread (running an `IJob`) can safely perform structural-change operations on that World's entities, leaving the main thread free to perform other work. + +The main motivation for this feature is to allow a secondary / streaming World to safely modify its entities and perform structural changes, without blocking the main thread from processing entities in the default World. It is not intended as a fully general-purpose interface to `EntityManager` functionality from worker threads. Certain `EntityManager` operations rely on main-thread-only features in their implementation, and will therefore not function correctly if called from job code. Only the subset of operations directly exposed by `ExclusiveEntityTransaction` are officially supported. + ### RefRW/RefRO The Entities package contains explicit reference types that you can use to mark the contained type to be accessed as ReadWrite (`RefRW`) or ReadOnly (`RefRO`). These reference types have checks to ensure that the contained type is still valid when running with safety checks enabled. [Structural changes](concepts-structural-changes.md) might cause the contained type to no longer be valid. @@ -34,4 +40,4 @@ There are a few cases that aren't guarded against. This section outlines any cas The `InternalCompilerInterface` static class includes a number of methods that expose some of the DOTS internals to source-generated code. This is necessary because generated code can only typically call public APIs. >[!WARNING] ->Do not use the APIs contained in InternalCompilerInterface. They are only in the context of being called from generated code and are likely to change in the future. \ No newline at end of file +>Do not use the APIs contained in InternalCompilerInterface. They are only in the context of being called from generated code and are likely to change in the future. diff --git a/Documentation~/index.md b/Documentation~/index.md index e4bf7a17..f14bf59b 100644 --- a/Documentation~/index.md +++ b/Documentation~/index.md @@ -10,7 +10,6 @@ See the [DOTS Guide and Samples](https://github.com/Unity-Technologies/EntityCom * 2022.3 (LTS) * 2023.3 (Latest Beta and beyond) -* Unity 6 ## Package installation diff --git a/Documentation~/systems-entityquery-create.md b/Documentation~/systems-entityquery-create.md index f1230681..b3ab771c 100644 --- a/Documentation~/systems-entityquery-create.md +++ b/Documentation~/systems-entityquery-create.md @@ -8,12 +8,14 @@ The query uses [`EntityQueryBuilder.WithAllRW`](xref:Unity.Entities.EntityQue ## Specify which archetypes the system selects -Queries only match archetypes that contain the components you specify. You can specify components with three different [`EntityQueryBuilder`](xref:Unity.Entities.EntityQueryBuilder) methods: - -* `WithAll()`: To match the query, an archetype must contain all the query's required components. -* `WithAny()`: To match the query, an archetype must contain at least one of the query's optional components. -* `WithNone()`: To match the query, an archetype must not contain any of the query's excluded components. -* `WithAspect()`: To match the query, an archetype must meet the [aspect’s](aspects-intro.md) component requirements. Use last when building a query to avoid component aliasing. +Queries only match archetypes that contain the components you specify. You can specify components with the following [`EntityQueryBuilder`](xref:Unity.Entities.EntityQueryBuilder) methods: + +* `WithAll()`: To match the query, an entity's archetype must contain all the query's required components, and these components must be enabled on that entity. +* `WithAny()`: To match the query, an entity's archetype must contain at least one of the query's optional components, and these components must be enabled on that entity. +* `WithNone()`: To match the query, either an entity's archetype must not contain any of the query's excluded components, or the components must be present but disabled on that entity. +* `WithDisabled()`: To match the query, an entity's archetype must contain this component, and the component must be disabled on that entity. +* `WithAbsent()`: To match the query, an entity's archetype must not contain the specified components. +* `WithPresent()`: To match the query, an entity's archetype must contain the specified components (whether or not they are enabled). For example, the following query includes archetypes that contain the `ObjectRotation` and `ObjectRotationSpeed`components, but excludes any archetypes that contain the `Static` component: diff --git a/Unity.Deformations/DeformationComponents.cs b/Unity.Deformations/DeformationComponents.cs index af84e67e..99b553e3 100644 --- a/Unity.Deformations/DeformationComponents.cs +++ b/Unity.Deformations/DeformationComponents.cs @@ -13,7 +13,7 @@ namespace Unity.Deformations public struct BlendShapeWeight : IBufferElementData { /// - /// The weight value of the blend shape. + /// The weight value of the blend shape. The range is from `0.0f` to `100.0f`, where `0.0f` is 0% and `100.0f` is 100%. /// public float Value; } diff --git a/Unity.Entities.PerformanceTests/BufferLookupPerformanceTests.cs b/Unity.Entities.PerformanceTests/BufferLookupPerformanceTests.cs index de445f09..6de6c62f 100644 --- a/Unity.Entities.PerformanceTests/BufferLookupPerformanceTests.cs +++ b/Unity.Entities.PerformanceTests/BufferLookupPerformanceTests.cs @@ -1,223 +1,222 @@ -// using NUnit.Framework; -// using Unity.Collections; -// using Unity.Entities.Tests; -// using Unity.PerformanceTesting; -// -// namespace Unity.Entities.PerformanceTests -// { -// [Category("Performance")] -// partial class BufferLookupPerformanceTests : EntityQueryBuilderTestFixture -// { -// -// enum ScheduleMode -// { -// Parallel, Single, Run -// } -// -// -// partial class TryGetPerformanceSystem : SystemBase -// { -// public bool ReadOnly; -// public ScheduleMode Schedule; -// public bool UseHasComponent; //either use the if(hasComponent...) bufferLookup[entity] path of the tryGetComponent path. -// protected override void OnUpdate() -// { -// if (UseHasComponent) -// RunHasComponent(); -// else -// RunTryGetBuffer(); -// } -// -// private void RunHasComponent() -// { -// if (ReadOnly) -// { -// var lookup = GetBufferLookup(); -// if (Schedule == ScheduleMode.Run) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 += lookup[data.value1][0].Value3; -// }).Run(); -// } -// else if (Schedule == ScheduleMode.Parallel) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 += lookup[data.value1][0].Value3; -// }).ScheduleParallel(); -// CompleteDependency(); -// } -// else if (Schedule == ScheduleMode.Single) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 += lookup[data.value1][0].Value3; -// }).Schedule(); -// CompleteDependency(); -// } -// -// } -// else -// { -// var lookup = GetBufferLookup(false); -// -// if (Schedule == ScheduleMode.Run) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 = lookup[data.value1][0].Value3; -// }).Run(); -// } -// else if (Schedule == ScheduleMode.Parallel) -// { -// Entities.WithNativeDisableParallelForRestriction(lookup).ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 = lookup[data.value1][0].Value3; -// }).ScheduleParallel(); -// CompleteDependency(); -// } -// else if (Schedule == ScheduleMode.Single) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.HasComponent(data.value1)) -// data.value0 = lookup[data.value1][0].Value3; -// }).Schedule(); -// CompleteDependency(); -// } -// } -// } -// -// private void RunTryGetBuffer() -// { -// if (ReadOnly) -// { -// var lookup = GetBufferLookup(true); -// if (Schedule == ScheduleMode.Run) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 += buffer[0].Value3; -// }).Run(); -// } -// else if (Schedule == ScheduleMode.Parallel) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 += buffer[0].Value3; -// }).ScheduleParallel(); -// CompleteDependency(); -// } -// else if (Schedule == ScheduleMode.Single) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 += buffer[0].Value3; -// }).Schedule(); -// CompleteDependency(); -// } -// -// } -// else -// { -// var lookup = GetBufferLookup(false); -// if (Schedule == ScheduleMode.Run) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 = buffer[0].Value3; -// }).Run(); -// } -// else if (Schedule == ScheduleMode.Parallel) -// { -// Entities.WithNativeDisableParallelForRestriction(lookup).ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 = buffer[0].Value3; -// }).ScheduleParallel(); -// CompleteDependency(); -// } -// else if (Schedule == ScheduleMode.Single) -// { -// Entities.ForEach((ref EcsTestDataEntity data) => -// { -// if(lookup.TryGetBuffer(data.value1, out var buffer)) -// data.value0 = buffer[0].Value3; -// }).Schedule(); -// CompleteDependency(); -// } -// } -// } -// } -// -// void RunHasComponentSystem(bool readOnly, bool useHasComponent, ScheduleMode schedule) -// { -// var system = World.GetOrCreateSystem(); -// var name = (readOnly ? "ReadOnly" : "Write") + "_" + schedule.ToString(); -// Measure.Method(() => -// { -// system.ReadOnly = false; -// system.Schedule = schedule; -// system.UseHasComponent = useHasComponent; -// system.Update(); -// }) -// .SampleGroup(name) -// .MeasurementCount(10) -// .IterationsPerMeasurement(1) -// .WarmupCount(1) -// .Run(); -// } -// -// [Test, Performance] -// [Category("Performance")] // bug: this redundant category here required because our current test runner ignores Category on a fixture for generated test methods -// public void TestHasBufferLookup([Values(10000, 1000000)] int entityCount, [Values] bool useHasComponent) -// { -// -// -// var targetArchetype = m_Manager.CreateArchetype(); -// -// var targetEntities = m_Manager.CreateEntity(targetArchetype, entityCount, World.UpdateAllocator.ToAllocator); -// -// var archetype = m_Manager.CreateArchetype(typeof(EcsTestDataEntity)); -// var entities = m_Manager.CreateEntity(archetype, entityCount, World.UpdateAllocator.ToAllocator); -// -// -// for (int i = 0; i != entityCount;i++) -// m_Manager.SetComponentData(entities[i], new EcsTestDataEntity { value1 = targetEntities[i] }); -// -// //set every other entity with component data "latest" in typeindex. Which happens to be based on insertion order according to a quick debug log -// for (int i = 0; i < entityCount; i += 2) -// { -// var buffer = m_Manager.AddBuffer(targetEntities[i]); -// buffer.Add(new EcsIntElement4 -// { -// Value0 = i, -// Value1 = i + 1, -// Value2 = i + 2, -// Value3 = i + 3, -// }); -// } -// -// targetEntities.Dispose(); -// entities.Dispose(); -// -// RunHasComponentSystem(true,useHasComponent, ScheduleMode.Run); -// RunHasComponentSystem(true,useHasComponent, ScheduleMode.Single); -// RunHasComponentSystem(true,useHasComponent, ScheduleMode.Parallel); -// -// RunHasComponentSystem(false,useHasComponent, ScheduleMode.Run); -// RunHasComponentSystem(false,useHasComponent, ScheduleMode.Single); -// RunHasComponentSystem(false,useHasComponent, ScheduleMode.Parallel); -// } -// } -// } +using System; +using NUnit.Framework; +using Unity.Collections; +using Unity.Entities.Tests; +using Unity.PerformanceTesting; + +namespace Unity.Entities.PerformanceTests +{ + [Category("Performance")] + partial class BufferLookupPerformanceTests : ECSTestsFixture + { + + enum ScheduleMode + { + Parallel, Single, Run + } + + + partial class TryGetPerformanceSystem : SystemBase + { + public bool ReadOnly; + public ScheduleMode Schedule; + public bool UseHasBuffer; //either use the if(hasBuffer...) bufferLookup[entity] path of the tryGetComponent path. + protected override void OnUpdate() + { + if (UseHasBuffer) + RunHasBuffer(); + else + RunTryGetBuffer(); + } + + private void RunHasBuffer() + { + if (ReadOnly) + { + var lookup = GetBufferLookup(); + if (Schedule == ScheduleMode.Run) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 += lookup[data.value1][0].Value3; + }).Run(); + } + else if (Schedule == ScheduleMode.Parallel) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 += lookup[data.value1][0].Value3; + }).ScheduleParallel(); + CompleteDependency(); + } + else if (Schedule == ScheduleMode.Single) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 += lookup[data.value1][0].Value3; + }).Schedule(); + CompleteDependency(); + } + + } + else + { + var lookup = GetBufferLookup(false); + + if (Schedule == ScheduleMode.Run) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 = lookup[data.value1][0].Value3; + }).Run(); + } + else if (Schedule == ScheduleMode.Parallel) + { + Entities.WithNativeDisableParallelForRestriction(lookup).ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 = lookup[data.value1][0].Value3; + }).ScheduleParallel(); + CompleteDependency(); + } + else if (Schedule == ScheduleMode.Single) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.HasBuffer(data.value1)) + data.value0 = lookup[data.value1][0].Value3; + }).Schedule(); + CompleteDependency(); + } + } + } + + private void RunTryGetBuffer() + { + if (ReadOnly) + { + var lookup = GetBufferLookup(true); + if (Schedule == ScheduleMode.Run) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 += buffer[0].Value3; + }).Run(); + } + else if (Schedule == ScheduleMode.Parallel) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 += buffer[0].Value3; + }).ScheduleParallel(); + CompleteDependency(); + } + else if (Schedule == ScheduleMode.Single) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 += buffer[0].Value3; + }).Schedule(); + CompleteDependency(); + } + + } + else + { + var lookup = GetBufferLookup(false); + if (Schedule == ScheduleMode.Run) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 = buffer[0].Value3; + }).Run(); + } + else if (Schedule == ScheduleMode.Parallel) + { + Entities.WithNativeDisableParallelForRestriction(lookup).ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 = buffer[0].Value3; + }).ScheduleParallel(); + CompleteDependency(); + } + else if (Schedule == ScheduleMode.Single) + { + Entities.ForEach((ref EcsTestDataEntity data) => + { + if(lookup.TryGetBuffer(data.value1, out var buffer)) + data.value0 = buffer[0].Value3; + }).Schedule(); + CompleteDependency(); + } + } + } + } + + void RunHasBufferSystem(bool readOnly, bool useHasBuffer, ScheduleMode schedule) + { + var system = World.GetOrCreateSystemManaged(); + var name = (readOnly ? "ReadOnly" : "Write") + "_" + schedule.ToString(); + Measure.Method(() => + { + system.ReadOnly = false; + system.Schedule = schedule; + system.UseHasBuffer = useHasBuffer; + system.Update(); + }) + .SampleGroup(name) + .MeasurementCount(10) + .IterationsPerMeasurement(1) + .WarmupCount(1) + .Run(); + } + + [Test, Performance] + [Category("Performance")] // bug: this redundant category here required because our current test runner ignores Category on a fixture for generated test methods + public void TestHasBufferLookup([Values(10000, 1000000)] int entityCount, [Values] bool useHasBuffer) + { + var targetArchetype = m_Manager.CreateArchetype(); + + var targetEntities = m_Manager.CreateEntity(targetArchetype, entityCount, World.UpdateAllocator.ToAllocator); + + var archetype = m_Manager.CreateArchetype(typeof(EcsTestDataEntity)); + var entities = m_Manager.CreateEntity(archetype, entityCount, World.UpdateAllocator.ToAllocator); + + + for (int i = 0; i != entityCount;i++) + m_Manager.SetComponentData(entities[i], new EcsTestDataEntity { value1 = targetEntities[i] }); + + //set every other entity with component data "latest" in typeindex. Which happens to be based on insertion order according to a quick debug log + for (int i = 0; i < entityCount; i += 2) + { + var buffer = m_Manager.AddBuffer(targetEntities[i]); + buffer.Add(new EcsIntElement4 + { + Value0 = i, + Value1 = i + 1, + Value2 = i + 2, + Value3 = i + 3, + }); + } + + targetEntities.Dispose(); + entities.Dispose(); + + RunHasBufferSystem(true,useHasBuffer, ScheduleMode.Run); + RunHasBufferSystem(true,useHasBuffer, ScheduleMode.Single); + RunHasBufferSystem(true,useHasBuffer, ScheduleMode.Parallel); + + RunHasBufferSystem(false,useHasBuffer, ScheduleMode.Run); + RunHasBufferSystem(false,useHasBuffer, ScheduleMode.Single); + RunHasBufferSystem(false,useHasBuffer, ScheduleMode.Parallel); + } + } +} diff --git a/Unity.Entities.Tests/BufferElementDataTests.cs b/Unity.Entities.Tests/BufferElementDataTests.cs index 91781845..aba9b249 100644 --- a/Unity.Entities.Tests/BufferElementDataTests.cs +++ b/Unity.Entities.Tests/BufferElementDataTests.cs @@ -25,6 +25,27 @@ namespace Unity.Entities.Tests { class BufferElementDataTests : ECSTestsFixture { + public struct EmptyBufferElement : IBufferElementData + { + } + + [Test] + public void EmptyBufferElement_Works() + { + var e = m_Manager.CreateEntity(typeof(EmptyBufferElement)); + var b = m_Manager.GetBuffer(e, isReadOnly: false); + // C# treats empty component types as having size=1 + Assert.AreEqual(128, b.Capacity); + b.Add(new EmptyBufferElement()); + b.Add(new EmptyBufferElement()); + Assert.AreEqual(2, b.Length); + Assert.AreEqual(b[0], b[1]); + // Make sure buffers still work if they exceed the internal capacity + b.Capacity = 256; + Assert.AreEqual(2, b.Length); + Assert.AreEqual(b[0], b[1]); + } + [InternalBufferCapacity(1024 * 1024)] public struct OverSizedCapacity : IBufferElementData { @@ -510,9 +531,24 @@ public void BufferLookup_Works() var intLookup = EmptySystem.GetBufferLookup(); Assert.IsTrue(intLookup.HasBuffer(entityInt)); - Assert.IsFalse(intLookup.HasBuffer(new Entity())); + Assert.IsTrue(intLookup.HasBuffer(entityInt, out var entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(intLookup.EntityExists(entityInt)); Assert.AreEqual(2, intLookup[entityInt][1].Value); + + Assert.IsFalse(intLookup.HasBuffer(new Entity())); + Assert.IsFalse(intLookup.HasBuffer(new Entity(), out entityExists)); + Assert.IsFalse(entityExists); + Assert.IsFalse(intLookup.EntityExists(new Entity())); + + m_Manager.DestroyEntity(entityInt); + intLookup = EmptySystem.GetBufferLookup(); + + Assert.IsFalse(intLookup.HasBuffer(entityInt)); + Assert.IsFalse(intLookup.HasBuffer(entityInt, out entityExists)); + Assert.IsFalse(entityExists); + Assert.IsFalse(intLookup.EntityExists(entityInt)); } [Test] diff --git a/Unity.Entities.Tests/CleanupBufferElementDataTests.cs b/Unity.Entities.Tests/CleanupBufferElementDataTests.cs index 5e8fe965..04feda6b 100644 --- a/Unity.Entities.Tests/CleanupBufferElementDataTests.cs +++ b/Unity.Entities.Tests/CleanupBufferElementDataTests.cs @@ -320,9 +320,32 @@ public void BufferLookup_Works() var intLookup = EmptySystem.GetBufferLookup(); Assert.IsTrue(intLookup.HasBuffer(entityInt)); - Assert.IsFalse(intLookup.HasBuffer(new Entity())); + Assert.IsTrue(intLookup.HasBuffer(entityInt, out var entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(intLookup.EntityExists(entityInt)); Assert.AreEqual(2, intLookup[entityInt][1].Value); + + Assert.IsFalse(intLookup.HasBuffer(new Entity())); + Assert.IsFalse(intLookup.HasBuffer(new Entity(), out entityExists)); + Assert.IsFalse(entityExists); + Assert.IsFalse(intLookup.EntityExists(new Entity())); + + m_Manager.DestroyEntity(entityInt); + intLookup = EmptySystem.GetBufferLookup(); + + Assert.IsTrue(intLookup.HasBuffer(entityInt)); + Assert.IsTrue(intLookup.HasBuffer(entityInt, out entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(intLookup.EntityExists(entityInt)); + + m_Manager.RemoveComponent(entityInt); + intLookup = EmptySystem.GetBufferLookup(); + + Assert.IsFalse(intLookup.HasBuffer(entityInt)); + Assert.IsFalse(intLookup.HasBuffer(entityInt, out entityExists)); + Assert.IsFalse(entityExists); + Assert.IsFalse(intLookup.EntityExists(entityInt)); } [Test] diff --git a/Unity.Entities.Tests/ComponentSystemTests.cs b/Unity.Entities.Tests/ComponentSystemTests.cs index a855f3d5..1d2c23d9 100644 --- a/Unity.Entities.Tests/ComponentSystemTests.cs +++ b/Unity.Entities.Tests/ComponentSystemTests.cs @@ -416,6 +416,7 @@ protected override void OnUpdate() #if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG //accessing a potentially stale ComponentLookup before Update() will throw an exception Assert.Throws(() => _lookup1.HasComponent(_entity)); + Assert.Throws(() => _lookup1.HasComponent(_entity, out _)); #endif var lookup2 = GetComponentLookup(); @@ -431,6 +432,9 @@ protected override void OnUpdate() Assert.AreEqual(lookup2.m_Safety, _lookup1.m_Safety); #endif Assert.IsTrue(_lookup1.HasComponent(_entity)); + Assert.IsTrue(_lookup1.HasComponent(_entity, out var entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(_lookup1.EntityExists(_entity)); } } @@ -648,6 +652,17 @@ public void ComponentLookup_TryGetComponent_Works() Assert.AreEqual(1, componentDataB.value); Assert.AreEqual(2, componentDataC.value); + Assert.IsTrue(array.TryGetComponent(entityA, out componentDataA, out var entityAExists)); + Assert.IsTrue(array.TryGetComponent(entityB, out componentDataB, out var entityBExists)); + Assert.IsTrue(array.TryGetComponent(entityC, out componentDataC, out var entityCExists)); + + Assert.AreEqual(0, componentDataA.value); + Assert.AreEqual(1, componentDataB.value); + Assert.AreEqual(2, componentDataC.value); + + Assert.IsTrue(entityAExists); + Assert.IsTrue(entityBExists); + Assert.IsTrue(entityCExists); } struct ComponentLookupContainerJob : IJob @@ -702,6 +717,10 @@ public void ComponentLookup_TryGetComponent_HasTagComponent() var array = m_Manager.GetComponentLookup(); Assert.IsTrue(array.TryGetComponent(entity,out var tagComponent)); Assert.AreEqual(default(EcsTestTag),tagComponent); + Assert.IsTrue(array.TryGetComponent(entity,out tagComponent, out var entityExists)); + Assert.AreEqual(default(EcsTestTag),tagComponent); + Assert.IsTrue(entityExists); + Assert.IsTrue(array.EntityExists(entity)); } [Test] @@ -767,6 +786,28 @@ public void ComponentLookup_TryGetComponent_NoComponent() Assert.AreEqual(componentData, default(EcsTestData)); } + [Test] + public void ComponentLookup_TryGetComponent_InvalidEntity([Values]bool destroy) + { + var entity = m_Manager.CreateEntity(typeof(EcsTestData)); + m_Manager.SetComponentData(entity, new EcsTestData + { + value = 5 + }); + + if (destroy) + m_Manager.DestroyEntity(entity); + else entity = Entity.Null; + + var array = m_Manager.GetComponentLookup(); + Assert.IsFalse(array.TryGetComponent(entity, out var componentData)); + Assert.AreEqual(componentData, default(EcsTestData)); + Assert.IsFalse(array.TryGetComponent(entity, out componentData, out var entityExists)); + Assert.AreEqual(componentData, default(EcsTestData)); + Assert.IsFalse(entityExists); + Assert.IsFalse(array.EntityExists(entity)); + } + [Test] public void ComponentLookup_TryGetComponent_FullyUpdatesLookupCache() { @@ -863,6 +904,9 @@ public void BufferLookup_HasBuffer_Works() var array = m_Manager.GetBufferLookup(); Assert.IsTrue(array.HasBuffer(entity)); + Assert.IsTrue(array.HasBuffer(entity, out var entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(array.EntityExists(entity)); } [Test] @@ -876,6 +920,10 @@ public void BufferLookup_TryGetBuffer_Works() Assert.IsTrue(array.TryGetBuffer(entity, out var bufferData)); CollectionAssert.AreEqual(new EcsIntElement[] { 0, 1, 2 }, bufferData.ToNativeArray(Allocator.Temp).ToArray()); + Assert.IsTrue(array.TryGetBuffer(entity, out bufferData, out bool entityExists)); + CollectionAssert.AreEqual(new EcsIntElement[] { 0, 1, 2 }, bufferData.ToNativeArray(Allocator.Temp).ToArray()); + Assert.IsTrue(entityExists); + Assert.IsTrue(array.EntityExists(entity)); } [Test] @@ -886,6 +934,39 @@ public void BufferLookup_TryGetBuffer_NoComponent() Assert.IsFalse(array.TryGetBuffer(entity, out var bufferData)); //I can't do an equivalence check to default since equals appears to not be implemented Assert.IsFalse(bufferData.IsCreated); + Assert.IsFalse(array.TryGetBuffer(entity, out bufferData, out bool entityExists)); + Assert.IsFalse(bufferData.IsCreated); + Assert.IsTrue(entityExists); + Assert.IsTrue(array.EntityExists(entity)); + + m_Manager.DestroyEntity(entity); + array = m_Manager.GetBufferLookup(); + + Assert.IsFalse(array.TryGetBuffer(entity, out bufferData, out entityExists)); + Assert.IsFalse(bufferData.IsCreated); + Assert.IsFalse(entityExists); + Assert.IsFalse(array.EntityExists(entity)); + } + + [Test] + public void BufferLookup_TryGetBuffer_InvalidEntity([Values]bool destroy) + { + var entity = m_Manager.CreateEntity(); + m_Manager.AddBuffer(entity); + m_Manager.GetBuffer(entity).AddRange(new NativeArray(new EcsIntElement[] { 0, 1, 2 }, Allocator.Temp)); + var array = m_Manager.GetBufferLookup(); + + if(destroy) m_Manager.DestroyEntity(entity); + else entity = Entity.Null; + array = m_Manager.GetBufferLookup(); + + Assert.IsFalse(array.TryGetBuffer(entity, out var bufferData)); + //I can't do an equivalence check to default since equals appears to not be implemented + Assert.IsFalse(bufferData.IsCreated); + Assert.IsFalse(array.TryGetBuffer(entity, out bufferData, out bool entityExists)); + Assert.IsFalse(bufferData.IsCreated); + Assert.IsFalse(entityExists); + Assert.IsFalse(array.EntityExists(entity)); } [Test] diff --git a/Unity.Entities.Tests/EntityRemapUtilityTests.cs b/Unity.Entities.Tests/EntityRemapUtilityTests.cs index fecb126a..fb4cff0a 100644 --- a/Unity.Entities.Tests/EntityRemapUtilityTests.cs +++ b/Unity.Entities.Tests/EntityRemapUtilityTests.cs @@ -129,45 +129,52 @@ public void HasEntityReferencesManaged_Basic() //shallow types with no recursion //primitive - EntityRemapUtility.HasEntityReferencesManaged(typeof(string),out var entRef, out var blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(string),out var entRef, out var blobRef, out var unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); - EntityRemapUtility.HasEntityReferencesManaged(typeof(System.Int32),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(System.Int32),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); //blob only - EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesBlob),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesBlob),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); //entity only - EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesEntity),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesEntity),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); - //blob and entity - EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesBlobEntity),out entRef, out blobRef); + //blob and entity and unityobjref + EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TypeOverridesBlobEntityUnityObject),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, unityObjectRef); // entity ref in class with managed strings - EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TestEntityInClassWithManagedFields),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TestEntityInClassWithManagedFields),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); // blob asset ref in class with managed strings - EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TestBlobRefInClassWithManagedFields),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(TypeManagerTests.TestBlobRefInClassWithManagedFields),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); } public sealed class RecursionA3: IComponentData @@ -180,18 +187,21 @@ public sealed class RecursionA2: IComponentData { public Recursion1LayerBlob blob1; public Recursion1LayerEntity entity1; + public Recursion1LayerUnityObject objectRef; } public sealed class RecursionB2: IComponentData { public Recursion1LayerBlob blob1; public Recursion1LayerEntity entity1; + public Recursion1LayerUnityObject objectRef; } public sealed class RecursionC2: IComponentData { public Recursion1LayerBlob blob1; public Recursion1LayerEntity entity1; + public Recursion1LayerUnityObject objectRef; } public sealed class Recursion1LayerEntity: IComponentData @@ -204,24 +214,31 @@ public sealed class Recursion1LayerBlob: IComponentData TypeManagerTests.TypeOverridesBlob blob; } + public sealed class Recursion1LayerUnityObject : IComponentData + { + TypeManagerTests.TypeOverridesUnityObjectRef unityObjectRef; + } + [Test] public void HasEntityReferencesManaged_Recursion() { - EntityRemapUtility.HasEntityReferencesManaged(typeof(RecursionA2),out var entRef, out var blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(RecursionA2),out var entRef, out var blobRef, out var unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, unityObjectRef); - EntityRemapUtility.HasEntityReferencesManaged(typeof(RecursionA3),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(RecursionA3),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, unityObjectRef); - EntityRemapUtility.HasEntityReferencesManaged(typeof(EcsTestManagedDataEntity),out entRef, out blobRef); + EntityRemapUtility.HasEntityReferencesManaged(typeof(EcsTestManagedDataEntity),out entRef, out blobRef, out unityObjectRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.HasRef, entRef); Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); - Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, blobRef); + Assert.AreEqual(EntityRemapUtility.HasRefResult.NoRef, unityObjectRef); } diff --git a/Unity.Entities.Tests/EntityTransactionTests.cs b/Unity.Entities.Tests/EntityTransactionTests.cs index 2795048d..3e41f496 100644 --- a/Unity.Entities.Tests/EntityTransactionTests.cs +++ b/Unity.Entities.Tests/EntityTransactionTests.cs @@ -322,6 +322,7 @@ public void BufferLookup_AcquiredBeforeTransaction_Throws() var linkedEntityGroup = m_Manager.GetBufferLookup(); m_Manager.BeginExclusiveEntityTransaction(); Assert.Throws(() => linkedEntityGroup.HasBuffer(c)); + Assert.Throws(() => linkedEntityGroup.HasBuffer(c, out _)); m_Manager.EndExclusiveEntityTransaction(); } @@ -342,6 +343,7 @@ public void BufferLookup_AcquiredFromTransaction_Throws() var transaction = m_Manager.BeginExclusiveEntityTransaction(); var linkedEntityGroup = transaction.EntityManager.GetBufferLookup(); Assert.DoesNotThrow(() => linkedEntityGroup.HasBuffer(c)); + Assert.DoesNotThrow(() => linkedEntityGroup.HasBuffer(c, out _)); m_Manager.EndExclusiveEntityTransaction(); } diff --git a/Unity.Entities.Tests/ForEachCodegen/ForEachBufferAccessTests.cs b/Unity.Entities.Tests/ForEachCodegen/ForEachBufferAccessTests.cs index 5e2844a3..3daa454f 100644 --- a/Unity.Entities.Tests/ForEachCodegen/ForEachBufferAccessTests.cs +++ b/Unity.Entities.Tests/ForEachCodegen/ForEachBufferAccessTests.cs @@ -209,17 +209,19 @@ public void BufferAccessMethodsExpandILPastShortBranchDistance_CausesNoException var a = 0; if (data.value < 100) { + if (GetBufferLookup().HasBuffer(e)) a++; if (GetBufferLookup().HasBuffer(e)) a++; if (GetBufferLookup().HasBuffer(e)) a++; - if (GetBufferLookup().HasBuffer(e)) + bool entityExists; + if (GetBufferLookup().HasBuffer(e, out entityExists)) a++; - if (GetBufferLookup().HasBuffer(e)) + if (GetBufferLookup().HasBuffer(e, out entityExists)) a++; - if (GetBufferLookup().HasBuffer(e)) + if (GetBufferLookup().HasBuffer(e, out entityExists)) a++; } data.value = a; diff --git a/Unity.Entities.Tests/SharedComponentDataTests.cs b/Unity.Entities.Tests/SharedComponentDataTests.cs index 305be672..c7f19a31 100644 --- a/Unity.Entities.Tests/SharedComponentDataTests.cs +++ b/Unity.Entities.Tests/SharedComponentDataTests.cs @@ -1293,5 +1293,19 @@ public unsafe void IRefCounted_IsDisposed_AfterAddedToTwoEntities_AndDeletedBoth Assert.AreEqual(0, RefCount1); world.Dispose(); } + + public struct EmptySharedComponent : ISharedComponentData + { + } + + [Test] + public void EmptySharedComponent_Works() + { + var e = m_Manager.CreateEntity(); + m_Manager.AddSharedComponent(e, new EmptySharedComponent()); + + } + + } } diff --git a/Unity.Entities.Tests/SizeTests.cs b/Unity.Entities.Tests/SizeTests.cs index 47a18601..fa56238e 100644 --- a/Unity.Entities.Tests/SizeTests.cs +++ b/Unity.Entities.Tests/SizeTests.cs @@ -88,11 +88,14 @@ public void SIZ_TagCanAddComponentData() } [Test] - public void SIZ_TagThrowsOnComponentLookup() + public void SIZ_TagAllowedOnComponentLookup() { var entity = m_Manager.CreateEntity(typeof(EcsTestTag)); var fromEntity = m_Manager.GetComponentLookup(); Assert.IsTrue(fromEntity.HasComponent(entity)); + Assert.IsTrue(fromEntity.HasComponent(entity, out var entityExists)); + Assert.IsTrue(entityExists); + Assert.IsTrue(fromEntity.EntityExists(entity)); var res = fromEntity[entity]; Assert.AreEqual(res , default(EcsTestTag)); } diff --git a/Unity.Entities.Tests/TypeManagerTests.cs b/Unity.Entities.Tests/TypeManagerTests.cs index d2c0f16d..3017157e 100644 --- a/Unity.Entities.Tests/TypeManagerTests.cs +++ b/Unity.Entities.Tests/TypeManagerTests.cs @@ -18,14 +18,14 @@ [assembly: RegisterGenericComponentType(typeof(TypeManagerTests.GenericComponent>))] [assembly: RegisterGenericComponentType(typeof(TypeManagerTests.GenericComponent>))] - - -namespace Unity.Entities.Tests + + +namespace Unity.Entities.Tests { partial class TypeManagerTests : ECSTestsFixture { internal struct TestType1 : IComponentData - { + { int empty; } struct TestTypeWithEntity : IComponentData @@ -559,7 +559,7 @@ public void TestGetSystems() var sys = allSystemTypes[i]; var systemTypeIndex = TypeManager.GetSystemTypeIndex();// A group we know will always exist - if(sys == systemTypeIndex) + if(sys == systemTypeIndex) { foundTestSystem = true; break; @@ -708,20 +708,26 @@ public void GetSystemsRespectsCreateBeforeCreateAfter() Assert.Less(indexOfB, indexOfC); } - [TypeManager.TypeOverrides(hasNoEntityReferences: false, hasNoBlobReferences: true)] - public struct TypeOverridesNoBlobUnmanaged : IComponentData + [TypeManager.TypeOverrides(hasNoEntityReferences: false, hasNoBlobReferences: true, hasNoUnityObjectReferences: true)] + public struct TypeOverridesNoBlobNoUnityObjectUnmanaged : IComponentData { public Entity entity; } - [TypeManager.TypeOverrides(hasNoEntityReferences: true, hasNoBlobReferences: false)] - public struct TypeOverridesNoEntityUnmanaged : IComponentData + [TypeManager.TypeOverrides(hasNoEntityReferences: true, hasNoBlobReferences: false, hasNoUnityObjectReferences: true)] + public struct TypeOverridesNoEntityNoUnityObjectUnmanaged : IComponentData { public BlobAssetReference blob; } - [TypeManager.TypeOverrides(hasNoEntityReferences: false, hasNoBlobReferences: false)] - public struct TypeOverridesNoBlobNoEntityUnmanaged : IComponentData + [TypeManager.TypeOverrides(hasNoEntityReferences: true, hasNoBlobReferences: true, hasNoUnityObjectReferences: false)] + public struct TypeOverridesNoEntityNoBlobUnmanaged : IComponentData + { + public UnityObjectRef obj; + } + + [TypeManager.TypeOverrides(hasNoEntityReferences: false, hasNoBlobReferences: false, hasNoUnityObjectReferences: false)] + public struct TypeOverridesNoBlobNoEntityNoUnityObjectUnmanaged : IComponentData { public float data; } @@ -729,16 +735,25 @@ public struct TypeOverridesNoBlobNoEntityUnmanaged : IComponentData [Test] public void TypeOverrideWorks_Unmanaged_ValidTypesDoNotThrow() { - var typeOverridesNoBlobInfo = TypeManager.GetTypeInfo(); - Assert.IsTrue(TypeManager.HasEntityReferences(typeOverridesNoBlobInfo.TypeIndex)); - Assert.IsFalse(typeOverridesNoBlobInfo.HasBlobAssetRefs); + var typeOverridesNoBlobNoUnityObjectInfo = TypeManager.GetTypeInfo(); + Assert.IsTrue(TypeManager.HasEntityReferences(typeOverridesNoBlobNoUnityObjectInfo.TypeIndex)); + Assert.IsFalse(typeOverridesNoBlobNoUnityObjectInfo.HasUnityObjectRefs); + Assert.IsFalse(typeOverridesNoBlobNoUnityObjectInfo.HasBlobAssetRefs); - var typeOverridesNoEntityInfo = TypeManager.GetTypeInfo(); - Assert.IsTrue(typeOverridesNoEntityInfo.HasBlobAssetRefs); + var typeOverridesNoEntityNoUnityObjectInfo = TypeManager.GetTypeInfo(); + Assert.IsTrue(typeOverridesNoEntityNoUnityObjectInfo.HasBlobAssetRefs); + Assert.IsFalse(typeOverridesNoEntityNoUnityObjectInfo.HasUnityObjectRefs); + Assert.IsFalse(TypeManager.HasEntityReferences(typeOverridesNoEntityNoUnityObjectInfo.TypeIndex)); - var typeOverridesNoBlobNoEntityInfo = TypeManager.GetTypeInfo(); - Assert.IsFalse(TypeManager.HasEntityReferences(typeOverridesNoBlobNoEntityInfo.TypeIndex)); - Assert.IsFalse(typeOverridesNoBlobNoEntityInfo.HasBlobAssetRefs); + var typeOverridesNoEntityNoBlobInfo = TypeManager.GetTypeInfo(); + Assert.IsTrue(typeOverridesNoEntityNoBlobInfo.HasUnityObjectRefs); + Assert.IsFalse(typeOverridesNoEntityNoBlobInfo.HasBlobAssetRefs); + Assert.IsFalse(TypeManager.HasEntityReferences(typeOverridesNoEntityNoBlobInfo.TypeIndex)); + + var typeOverridesNoBlobNoEntityNoUnityObjectInfo = TypeManager.GetTypeInfo(); + Assert.IsFalse(TypeManager.HasEntityReferences(typeOverridesNoBlobNoEntityNoUnityObjectInfo.TypeIndex)); + Assert.IsFalse(typeOverridesNoBlobNoEntityNoUnityObjectInfo.HasBlobAssetRefs); + Assert.IsFalse(typeOverridesNoBlobNoEntityNoUnityObjectInfo.HasUnityObjectRefs); } [DisableAutoTypeRegistration] @@ -818,9 +833,6 @@ struct EmptySharedComponent : ISharedComponentData [TestCase(typeof(Shared), @"\bdisabled\b", TestName = "Implements both ISharedComponentData and IEnableableComponent")] [TestCase(typeof(float), @"\b(not .*|in)valid\b", TestName = "Not valid component type")] - - [TestCase(typeof(EmptyBufferComponent), @"\b(is .*|in)valid\b", TestName = "IBufferElementData types cannot be empty")] - [TestCase(typeof(EmptySharedComponent), @"\b(is .*|in)valid\b", TestName = "ISharedComponentData types cannot be empty")] [TestRequiresDotsDebugOrCollectionChecks("Test requires component type safety checks")] public void BuildComponentType_ThrowsArgumentException_WithExpectedFailures(Type type, string keywordPattern) { @@ -830,6 +842,16 @@ public void BuildComponentType_ThrowsArgumentException_WithExpectedFailures(Type ); } + [TestCase(typeof(EmptyBufferComponent), TestName = "IBufferElementData types can be empty")] + [TestCase(typeof(EmptySharedComponent), TestName = "ISharedComponentData types can be empty")] + [TestRequiresDotsDebugOrCollectionChecks("Test requires component type safety checks")] + public void BuildComponentType_DoesNotThrow(Type type) + { + // This was briefly a fatal error in TypeManager initialization, but we decided to relax it; + // empty components are pointless and wasteful, but not actively harmful. + Assert.DoesNotThrow(() => TypeManager.BuildComponentType(type, new TypeManager.BuildComponentCache())); + } + struct UnmanagedSharedComponent : ISharedComponentData { int a; @@ -1081,7 +1103,7 @@ public void TestNestedNativeContainersDoesNotThrow() { Assert.DoesNotThrow(() => { - Assert.IsTrue(TypeManager.BuildComponentType(typeof(NestedNativeContainerComponent), new TypeManager.BuildComponentCache()).TypeIndex.HasNativeContainer); + Assert.IsTrue(TypeManager.BuildComponentType(typeof(NestedNativeContainerComponent), new TypeManager.BuildComponentCache()).TypeIndex.HasNativeContainer); }); } @@ -1163,40 +1185,48 @@ public class TestBlobRefInClassWithManagedFields : IComponentData } [DisableAutoTypeRegistration] - [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:true)] - public sealed class TypeOverridesBlobEntity: IComponentData + [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:true, hasNoUnityObjectReferences:true)] + public sealed class TypeOverridesBlobEntityUnityObject: IComponentData { public Entity entity; public BlobAssetReference blob; + public UnityObjectRef objectRef; } [DisableAutoTypeRegistration] - [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:false)] + [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:false, hasNoUnityObjectReferences:false)] public sealed class TypeOverridesEntity : IComponentData { public Entity entity; } [DisableAutoTypeRegistration] - [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:true)] + [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:true, hasNoUnityObjectReferences:false)] public sealed class TypeOverridesBlob: IComponentData { public BlobAssetReference blob; } - [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:true)] + [DisableAutoTypeRegistration] + [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:false, hasNoUnityObjectReferences:true)] + public sealed class TypeOverridesUnityObjectRef: IComponentData + { + public UnityObjectRef UnityObjectRef; + } + + [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:true, hasNoUnityObjectReferences:false)] public sealed class TypeOverridesNoBlob: IComponentData { public Entity entity; } - [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:false)] + [TypeManager.TypeOverrides(hasNoEntityReferences:true, hasNoBlobReferences:false, hasNoUnityObjectReferences:false)] public sealed class TypeOverridesNoEntity : IComponentData { public BlobAssetReference blob; } - [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:false)] + [TypeManager.TypeOverrides(hasNoEntityReferences:false, hasNoBlobReferences:false, hasNoUnityObjectReferences:false)] public sealed class TypeOverridesNoBlobNoEntity: IComponentData { public string data; @@ -1306,7 +1336,7 @@ public void TypeOverrideWorks_Managed_InvalidTypesThrow() TypeManager.BuildComponentCache cache = new TypeManager.BuildComponentCache(); Assert.Throws(() => { TypeManager.BuildComponentType(typeof(TypeOverridesBlob), cache); }); Assert.Throws(() => { TypeManager.BuildComponentType(typeof(TypeOverridesEntity), cache); }); - Assert.Throws(() => { TypeManager.BuildComponentType(typeof(TypeOverridesBlobEntity), cache); }); + Assert.Throws(() => { TypeManager.BuildComponentType(typeof(TypeOverridesBlobEntityUnityObject), cache); }); } [Test] diff --git a/Unity.Entities.Tests/Unity.Entities.Tests.asmdef b/Unity.Entities.Tests/Unity.Entities.Tests.asmdef index 56c177eb..5cca3c48 100644 --- a/Unity.Entities.Tests/Unity.Entities.Tests.asmdef +++ b/Unity.Entities.Tests/Unity.Entities.Tests.asmdef @@ -25,8 +25,7 @@ "defineConstraints": [ "UNITY_INCLUDE_TESTS" ], - "versionDefines": - [ + "versionDefines": [ { "name": "Unity", "expression": "2022.2.14f1", @@ -36,7 +35,17 @@ "name": "Unity", "expression": "2022.3.11f1", "define": "UNITY_2022_3_11F1_OR_NEWER" + }, + { + "name": "Unity", + "expression": "2022.3.43f1", + "define": "UNITY_2022_3_43F1_OR_NEWER" + }, + { + "name": "Unity", + "expression": "6000.0.16f1", + "define": "UNITY_6000_0_16F1_OR_NEWER" } ], "noEngineReferences": false -} +} \ No newline at end of file diff --git a/Unity.Entities.Tests/UnityObjectRefTests.cs b/Unity.Entities.Tests/UnityObjectRefTests.cs new file mode 100644 index 00000000..60bde10b --- /dev/null +++ b/Unity.Entities.Tests/UnityObjectRefTests.cs @@ -0,0 +1,179 @@ +#if UNITY_EDITOR +using System; +using System.Collections; +using NUnit.Framework; +using Unity.Collections; +using UnityEditor; +using UnityEngine; +using UnityEngine.TestTools; + +namespace Unity.Entities.Tests +{ + [Serializable] + public class UnityObjectRefTests : ECSTestsCommonBase + { + private string TempAssetDir; + private string TempAssetPath; + + [OneTimeSetUp] + public void OneTimeSetup() + { + var guid = AssetDatabase.CreateFolder("Assets", nameof(UnityObjectRefTests)); + TempAssetDir = AssetDatabase.GUIDToAssetPath(guid); + TempAssetPath = $"{TempAssetDir}/TempTextAsset.asset"; + var textAsset = new TextAsset("Foo"); + AssetDatabase.CreateAsset(textAsset, TempAssetPath); + AssetDatabase.Refresh(); + } + + [OneTimeTearDown] + public void OneTimeTearDown() + { + AssetDatabase.DeleteAsset(TempAssetDir); + } + + struct StructWithUnityObjectRef : IComponentData + { + public UnityObjectRef UnityObjectRef; + } + +#if !UNITY_DISABLE_MANAGED_COMPONENTS + class ClassWithUnityObjectRef : IComponentData + { + public UnityObjectRef UnityObjectRef; + } + + struct SharedComponentManagedWithUnityObjectRef : ISharedComponentData, IEquatable + { + public UnityObjectRef UnityObjectRef; + public UnityEngine.Object DummyManagedField; + + public bool Equals(SharedComponentManagedWithUnityObjectRef other) + { + return UnityObjectRef.Equals(other.UnityObjectRef) && Equals(DummyManagedField, other.DummyManagedField); + } + + public override bool Equals(object obj) + { + return obj is SharedComponentManagedWithUnityObjectRef other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(UnityObjectRef, DummyManagedField); + } + } +#endif // !UNITY_DISABLE_MANAGED_COMPONENTS + + struct SharedComponentWithUnityObjectRef : ISharedComponentData + { + public UnityObjectRef UnityObjectRef; + } + + [TypeManager.TypeOverrides(hasNoBlobReferences:true, hasNoEntityReferences:true, hasNoUnityObjectReferences:true, allowForcedNoReferences:true)] + struct StructWithUnityObjectRefOverride : IComponentData + { + public UnityObjectRef UnityObjectRef; + } + +#if (UNITY_2022_3 && UNITY_2022_3_43F1_OR_NEWER) || (UNITY_6000 && UNITY_6000_0_16F1_OR_NEWER) + [UnityTest] + public IEnumerator AssetGC_StructWithUnityObjectRefOverride_AssetReleased() + { + var textAsset = AssetDatabase.LoadAssetAtPath(TempAssetPath); + var instanceID = textAsset.GetInstanceID(); + + using var world = new World("TestWorld"); + var entity = world.EntityManager.CreateEntity(new ComponentType(typeof(StructWithUnityObjectRefOverride))); + world.EntityManager.SetComponentData(entity, new StructWithUnityObjectRefOverride{UnityObjectRef = textAsset}); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + + textAsset = null; + + yield return Resources.UnloadUnusedAssets(); + + Assert.IsFalse(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + } + + [UnityTest] + public IEnumerator AssetGC_StructComponent_AssetNotReleased() + { + var textAsset = AssetDatabase.LoadAssetAtPath(TempAssetPath); + var instanceID = textAsset.GetInstanceID(); + + using var world = new World("TestWorld"); + var entity = world.EntityManager.CreateEntity(new ComponentType(typeof(StructWithUnityObjectRef))); + world.EntityManager.SetComponentData(entity, new StructWithUnityObjectRef{UnityObjectRef = textAsset}); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + + textAsset = null; + + yield return Resources.UnloadUnusedAssets(); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + } + +#if !UNITY_DISABLE_MANAGED_COMPONENTS + [UnityTest] + public IEnumerator AssetGC_ClassComponent_AssetNotReleased() + { + var textAsset = AssetDatabase.LoadAssetAtPath(TempAssetPath); + var instanceID = textAsset.GetInstanceID(); + + using var world = new World("TestWorld"); + var entity = world.EntityManager.CreateEntity(new ComponentType(typeof(ClassWithUnityObjectRef))); + world.EntityManager.SetComponentData(entity, new ClassWithUnityObjectRef{UnityObjectRef = textAsset}); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + + textAsset = null; + + yield return Resources.UnloadUnusedAssets(); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + } + + [UnityTest] + public IEnumerator AssetGC_SharedComponentManaged_AssetNotReleased() + { + var textAsset = AssetDatabase.LoadAssetAtPath(TempAssetPath); + var instanceID = textAsset.GetInstanceID(); + + using var world = new World("TestWorld"); + var entity = world.EntityManager.CreateEntity(new ComponentType(typeof(SharedComponentManagedWithUnityObjectRef))); + world.EntityManager.SetSharedComponentManaged(entity, new SharedComponentManagedWithUnityObjectRef{UnityObjectRef = textAsset}); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + + textAsset = null; + + yield return Resources.UnloadUnusedAssets(); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + } +#endif + + [UnityTest] + public IEnumerator AssetGC_SharedComponent_AssetNotReleased() + { + var textAsset = AssetDatabase.LoadAssetAtPath(TempAssetPath); + var instanceID = textAsset.GetInstanceID(); + + using var world = new World("TestWorld"); + var entity = world.EntityManager.CreateEntity(new ComponentType(typeof(SharedComponentWithUnityObjectRef))); + world.EntityManager.SetSharedComponent(entity, new SharedComponentWithUnityObjectRef{UnityObjectRef = textAsset}); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + + textAsset = null; + + yield return Resources.UnloadUnusedAssets(); + + Assert.IsTrue(AssetDatabase.IsMainAssetAtPathLoaded(TempAssetPath)); + } +#endif // (UNITY_2022_3 && UNITY_2022_3_43F1_OR_NEWER) || (UNITY_6000 && UNITY_6000_0_16F1_OR_NEWER) + } +} +#endif diff --git a/Unity.Entities.Tests/UnityObjectRefTests.cs.meta b/Unity.Entities.Tests/UnityObjectRefTests.cs.meta new file mode 100644 index 00000000..ec636731 --- /dev/null +++ b/Unity.Entities.Tests/UnityObjectRefTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e49672a4a97df13f2a7ed184f457f325 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity.Entities/Diff/EntityDifferComponentChanges.cs b/Unity.Entities/Diff/EntityDifferComponentChanges.cs index 1a312c50..2855b188 100644 --- a/Unity.Entities/Diff/EntityDifferComponentChanges.cs +++ b/Unity.Entities/Diff/EntityDifferComponentChanges.cs @@ -22,7 +22,7 @@ static unsafe partial class EntityDiffer static bool TryGetEntityGuidComponent(EntityComponentStore* ecs, Entity entity, TypeIndex entityGuidTypeIndex, out EntityGuid entityGuid) { entityGuid = default; - if (!ecs->HasComponent(entity, entityGuidTypeIndex)) + if (!ecs->HasComponent(entity, entityGuidTypeIndex, out _)) { return false; } @@ -2278,7 +2278,7 @@ void IVisitPropertyAdapter.Visit(in VisitContextHasComponent(value, TypeManager.GetTypeIndex())) + if (m_EntityComponentStore->HasComponent(value, TypeManager.GetTypeIndex(), out _)) entityGuid = *(EntityGuid*)m_EntityComponentStore->GetComponentDataWithTypeRO(value, TypeManager.GetTypeIndex()); value = new Entity { Index = m_EntityReferencePatchId, Version = -1 }; diff --git a/Unity.Entities/Diff/EntityPatcher.cs b/Unity.Entities/Diff/EntityPatcher.cs index c973df96..0b369784 100644 --- a/Unity.Entities/Diff/EntityPatcher.cs +++ b/Unity.Entities/Diff/EntityPatcher.cs @@ -659,7 +659,7 @@ public void Execute(int index) do { - if (!store->HasComponent(entity, component.TypeIndex)) + if (!store->HasComponent(entity, component.TypeIndex, out _)) { ecb.AddComponent(index, entity, component); } @@ -804,19 +804,22 @@ public void Execute(int index) do { - if (!store->Exists(entity)) + if (!store->HasComponent(entity, component, out var entityExists)) { - EntityDoesNotExist.AddNoResize(new SetComponentError + if (entityExists) { - ComponentType = component, Guid = PackedEntityGuids[packedComponent.PackedEntityIndex] - }); - } - else if (!store->HasComponent(entity, component)) - { - ComponentDoesNotExist.AddNoResize(new SetComponentError + ComponentDoesNotExist.AddNoResize(new SetComponentError + { + ComponentType = component, Guid = PackedEntityGuids[packedComponent.PackedEntityIndex] + }); + } + else { - ComponentType = component, Guid = PackedEntityGuids[packedComponent.PackedEntityIndex] - }); + EntityDoesNotExist.AddNoResize(new SetComponentError + { + ComponentType = component, Guid = PackedEntityGuids[packedComponent.PackedEntityIndex] + }); + } } else { diff --git a/Unity.Entities/EntityCommandBuffer.cs b/Unity.Entities/EntityCommandBuffer.cs index f30c52c9..2de7d34a 100644 --- a/Unity.Entities/EntityCommandBuffer.cs +++ b/Unity.Entities/EntityCommandBuffer.cs @@ -5294,8 +5294,8 @@ static void FixupBufferContents( [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] private static void CheckBufferExistsOnEntity(EntityComponentStore* mgr, Entity entity, EntityComponentCommand* cmd) { - if (!mgr->HasComponent(entity, cmd->ComponentTypeIndex)) - throw new InvalidOperationException("Buffer does not exist on entity, cannot append element."); + if (!mgr->HasComponent(entity, cmd->ComponentTypeIndex, out bool entityExists)) + throw new InvalidOperationException($"Buffer does not exist on entity {entity} (entityExists:{entityExists}), cannot append element."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] diff --git a/Unity.Entities/EntityComponentStore.cs b/Unity.Entities/EntityComponentStore.cs index 44d61006..28d08794 100644 --- a/Unity.Entities/EntityComponentStore.cs +++ b/Unity.Entities/EntityComponentStore.cs @@ -1303,18 +1303,20 @@ public int GetComponentTypeOrderVersion(TypeIndex typeIndex) return m_ComponentTypeOrderVersion[typeIndex.Index]; } - public bool HasComponent(Entity entity, TypeIndex type) + public bool HasComponent(Entity entity, TypeIndex type, out bool entityExists) { - if (Hint.Unlikely(!Exists(entity))) + entityExists = Exists(entity); + if (Hint.Unlikely(!entityExists)) return false; var archetype = GetArchetype(entity); return ChunkDataUtility.GetIndexInTypeArray(archetype, type) != -1; } - internal bool HasComponent(Entity entity, TypeIndex type, ref LookupCache cache) + internal bool HasComponent(Entity entity, TypeIndex type, ref LookupCache cache, out bool entityExists) { - if (Hint.Unlikely(!Exists(entity))) + entityExists = Exists(entity); + if (Hint.Unlikely(!entityExists)) return false; var archetype = GetArchetype(entity); @@ -1323,9 +1325,10 @@ internal bool HasComponent(Entity entity, TypeIndex type, ref LookupCache cache) return cache.IndexInArchetype != -1; } - public bool HasComponent(Entity entity, ComponentType type) + public bool HasComponent(Entity entity, ComponentType type, out bool entityExists) { - if (Hint.Unlikely(!Exists(entity))) + entityExists = Exists(entity); + if (Hint.Unlikely(!entityExists)) return false; var archetype = GetArchetype(entity); diff --git a/Unity.Entities/EntityComponentStoreCreateDestroyEntities.cs b/Unity.Entities/EntityComponentStoreCreateDestroyEntities.cs index d5d16232..2e8f3a19 100644 --- a/Unity.Entities/EntityComponentStoreCreateDestroyEntities.cs +++ b/Unity.Entities/EntityComponentStoreCreateDestroyEntities.cs @@ -181,7 +181,7 @@ public ChunkIndex GetCleanChunk(Archetype* archetype, SharedComponentValues shar public void InstantiateEntities(Entity srcEntity, Entity* outputEntities, int instanceCount) { - if (HasComponent(srcEntity, m_LinkedGroupType)) + if (HasComponent(srcEntity, m_LinkedGroupType, out _)) { var header = (BufferHeader*)GetComponentDataWithTypeRO(srcEntity, m_LinkedGroupType); var entityPtr = (Entity*)BufferHeader.GetElementPointer(header); diff --git a/Unity.Entities/EntityComponentStoreDebug.cs b/Unity.Entities/EntityComponentStoreDebug.cs index 8b459260..b8a7f496 100644 --- a/Unity.Entities/EntityComponentStoreDebug.cs +++ b/Unity.Entities/EntityComponentStoreDebug.cs @@ -333,10 +333,10 @@ public void AssertValidEntities(Entity* entities, int count) [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] public void AssertEntityHasComponent(Entity entity, ComponentType componentType) { - if (HasComponent(entity, componentType)) + if (HasComponent(entity, componentType, out var entityExists)) return; - if (!Exists(entity)) + if (!entityExists) throw new ArgumentException("The entity does not exist." + AppendDestroyedEntityRecordError(entity)); throw new ArgumentException($"A component with type:{componentType} has not been added to the entity." + AppendRemovedComponentRecordError(entity, componentType)); @@ -348,10 +348,10 @@ public void AssertEntityHasComponent(NativeArray entities, ComponentType for (int i = 0; i < entities.Length; i++) { var entity = entities[i]; - if (HasComponent(entity, componentType)) + if (HasComponent(entity, componentType, out var entityExists)) continue; - if (!Exists(entity)) + if (!entityExists) throw new ArgumentException("The entity does not exist." + AppendDestroyedEntityRecordError(entity)); throw new ArgumentException($"A component with type:{componentType} has not been added to the entity." + AppendRemovedComponentRecordError(entity, componentType)); @@ -367,10 +367,10 @@ public void AssertEntityHasComponent(Entity entity, TypeIndex componentTypeIndex [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] public void AssertEntityHasComponent(Entity entity, TypeIndex componentTypeIndex, ref LookupCache typeLookupCache) { - if (Hint.Likely(HasComponent(entity, componentTypeIndex, ref typeLookupCache))) + if (Hint.Likely(HasComponent(entity, componentTypeIndex, ref typeLookupCache, out var entityExists))) return; - if (Hint.Unlikely(!Exists(entity))) + if (Hint.Unlikely(!entityExists)) throw new ArgumentException("The entity does not exist." + AppendDestroyedEntityRecordError(entity)); throw new ArgumentException($"A component with type:{componentTypeIndex} has not been added to the entity." + AppendRemovedComponentRecordError(entity, ComponentType.FromTypeIndex(componentTypeIndex))); @@ -723,7 +723,7 @@ public void CheckCanAddChunkComponent(NativeArray chunkArray, Co [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] public void AssertCanInstantiateEntities(Entity srcEntity, Entity* outputEntities, int instanceCount) { - if (HasComponent(srcEntity, m_LinkedGroupType)) + if (HasComponent(srcEntity, m_LinkedGroupType, out var entityExists)) { var header = (BufferHeader*)GetComponentDataWithTypeRO(srcEntity, m_LinkedGroupType); var entityPtr = (Entity*)BufferHeader.GetElementPointer(header); @@ -746,7 +746,7 @@ public void AssertCanInstantiateEntities(Entity srcEntity, Entity* outputEntitie } else { - if (!Exists(srcEntity)) + if (!entityExists) throw new ArgumentException("srcEntity is not a valid entity"); var srcArchetype = GetArchetype(srcEntity); diff --git a/Unity.Entities/EntityDataAccess.cs b/Unity.Entities/EntityDataAccess.cs index fe60d53d..b2a3b1c7 100644 --- a/Unity.Entities/EntityDataAccess.cs +++ b/Unity.Entities/EntityDataAccess.cs @@ -1225,7 +1225,7 @@ public void RemoveComponentDuringStructuralChange(NativeArray entities, public bool HasComponent(Entity entity, ComponentType type) { - return EntityComponentStore->HasComponent(entity, type); + return EntityComponentStore->HasComponent(entity, type, out _); } [GenerateTestsForBurstCompatibility(GenericTypeArguments = new[] {typeof(BurstCompatibleComponentData)})] @@ -1452,7 +1452,7 @@ public void ReplaceComponentForLinkedEntityGroup(Entity entity, TypeIndex typeIn // Filter the linked entities based on the mask foreach (var e in linkedEntities) { - if (EntityComponentStore->HasComponent(e, typeIndex)) + if (EntityComponentStore->HasComponent(e, typeIndex, out _)) { SetComponentDataRaw(e, typeIndex, data, componentSize); } diff --git a/Unity.Entities/EntityManager.cs b/Unity.Entities/EntityManager.cs index 261d462d..57da88b7 100644 --- a/Unity.Entities/EntityManager.cs +++ b/Unity.Entities/EntityManager.cs @@ -4483,7 +4483,13 @@ public EntityQuery CreateEntityQuery(params ComponentType[] requiredComponents) /// /// Creates a EntityQuery from an EntityQueryDesc. /// - /// A queryDesc identifying a set of component types. + /// + /// **Warning:** The ability to construct an from multiple query descriptions is not + /// a supported workflow. Queries with multiple query descriptions are not guaranteed to function correctly in + /// all contexts. In general, try to create queries with a single description. For more information, refer to + /// [Creating entity queries](xref:systems-entityquery-create). + /// + /// An array of query descsriptions identifying a sets of component types to match. /// The EntityQuery corresponding to the queryDesc. [ExcludeFromBurstCompatTesting("Takes managed array")] public EntityQuery CreateEntityQuery(params EntityQueryDesc[] queriesDesc) @@ -5915,7 +5921,7 @@ internal bool HasComponentRaw(Entity entity, TypeIndex typeIndex) { var access = GetCheckedEntityDataAccess(); var ecs = access->EntityComponentStore; - return ecs->HasComponent(entity, typeIndex); + return ecs->HasComponent(entity, typeIndex, out _); } #endregion diff --git a/Unity.Entities/EntityRemapUtility.cs b/Unity.Entities/EntityRemapUtility.cs index 60f1bbd0..99d57d98 100644 --- a/Unity.Entities/EntityRemapUtility.cs +++ b/Unity.Entities/EntityRemapUtility.cs @@ -152,6 +152,7 @@ public static void CalculateFieldOffsetsUnmanaged(Type type, out bool hasEntityRefs, out bool hasBlobRefs, out bool hasWeakAssetRefs, + out bool hasUnityObjectRefs, ref NativeList entityOffsets, ref NativeList blobOffsets, ref NativeList weakAssetRefOffsets, @@ -164,11 +165,13 @@ public static void CalculateFieldOffsetsUnmanaged(Type type, int entityOffsetsCount = entityOffsets.Length; int blobOffsetsCount = blobOffsets.Length; int weakAssetRefCount = weakAssetRefOffsets.Length; + int unityObjectRefCount = unityObjectRefOffsets.Length; CalculateOffsetsRecurse(ref entityOffsets, ref blobOffsets, ref weakAssetRefOffsets, ref unityObjectRefOffsets, type, 0, cache); hasEntityRefs = entityOffsets.Length != entityOffsetsCount; hasBlobRefs = blobOffsets.Length != blobOffsetsCount; hasWeakAssetRefs = weakAssetRefOffsets.Length != weakAssetRefCount; + hasUnityObjectRefs = unityObjectRefOffsets.Length != unityObjectRefCount; } static bool CalculateOffsetsRecurse(ref NativeList entityOffsets, ref NativeList blobOffsets, ref NativeList weakAssetRefOffsets, ref NativeList unityObjectRefOffsets, Type type, int baseOffset, HashSet noOffsetTypes) @@ -256,15 +259,21 @@ public struct EntityBlobRefResult /// public HasRefResult HasBlobRef; + /// + /// Specifies if there are any references. + /// + public HasRefResult HasUnityObjectRef; + /// /// Initializes and returns an instance of EntityBlobRefResult. /// /// Specifies if there are any references. /// Specifies if there are any references. - public EntityBlobRefResult(HasRefResult hasEntityRef, HasRefResult hasBlobRef) + public EntityBlobRefResult(HasRefResult hasEntityRef, HasRefResult hasBlobRef, HasRefResult hasUnityObjectRef) { this.HasEntityRef = hasEntityRef; this.HasBlobRef = hasBlobRef; + this.HasUnityObjectRef = hasUnityObjectRef; } } @@ -276,19 +285,20 @@ public EntityBlobRefResult(HasRefResult hasEntityRef, HasRefResult hasBlobRef) /// Specifies if the type has any references. /// Map of type to used to accelerate the type recursion. /// The maximum depth for the recursion. - public static void HasEntityReferencesManaged(Type type, out HasRefResult hasEntityReferences, out HasRefResult hasBlobReferences, Dictionary cache = null, int maxDepth = 128) + public static void HasEntityReferencesManaged(Type type, out HasRefResult hasEntityReferences, out HasRefResult hasBlobReferences, out HasRefResult hasUnityObjectReferences, Dictionary cache = null, int maxDepth = 128) { hasEntityReferences = HasRefResult.NoRef; hasBlobReferences = HasRefResult.NoRef; + hasUnityObjectReferences = HasRefResult.NoRef; if (cache == null) cache = new Dictionary(); - ProcessEntityOrBlobReferencesRecursiveManaged(type, ref hasEntityReferences, ref hasBlobReferences, 0, ref cache, maxDepth); + ProcessEntityOrBlobReferencesRecursiveManaged(type, ref hasEntityReferences, ref hasBlobReferences, ref hasUnityObjectReferences, 0, ref cache, maxDepth); } - static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefResult hasEntityReferences, ref HasRefResult hasBlobReferences, int depth, ref Dictionary cache, int maxDepth = 10) + static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefResult hasEntityReferences, ref HasRefResult hasBlobReferences, ref HasRefResult hasUnityObjectReferences, int depth, ref Dictionary cache, int maxDepth = 10) { // Avoid deep / infinite recursion @@ -296,6 +306,7 @@ static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefR { hasEntityReferences = HasRefResult.MayHaveRef; hasBlobReferences = HasRefResult.MayHaveRef; + hasUnityObjectReferences = HasRefResult.MayHaveRef; return; } @@ -305,6 +316,7 @@ static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefR var result = cache[type]; hasEntityReferences = result.HasEntityRef; hasBlobReferences = result.HasBlobRef; + hasUnityObjectReferences = result.HasUnityObjectRef; return; } @@ -312,11 +324,12 @@ static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefR HasRefResult localHasEntityRefs = HasRefResult.NoRef; HasRefResult localHasBlobRefs = HasRefResult.NoRef; + HasRefResult localHasUnityObjectRefs = HasRefResult.NoRef; var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (var field in fields) { - if (localHasEntityRefs > 0 && localHasBlobRefs > 0) + if (localHasEntityRefs > 0 && localHasBlobRefs > 0 && localHasUnityObjectRefs > 0) { break; } @@ -345,31 +358,39 @@ static void ProcessEntityOrBlobReferencesRecursiveManaged(Type type, ref HasRefR { localHasBlobRefs = HasRefResult.HasRef; } + else if (fieldType == typeof(UntypedUnityObjectRef)) + { + localHasUnityObjectRefs = HasRefResult.HasRef; + } else if (fieldType.IsValueType || fieldType.IsSealed) { HasRefResult recursiveHasEntityRefs = HasRefResult.NoRef; HasRefResult recursiveHasBlobRefs = HasRefResult.NoRef; + HasRefResult recursiveHasUnityObjectRefs = HasRefResult.NoRef; ProcessEntityOrBlobReferencesRecursiveManaged(fieldType, ref recursiveHasEntityRefs, - ref recursiveHasBlobRefs, depth + 1, ref cache, maxDepth); + ref recursiveHasBlobRefs, ref recursiveHasUnityObjectRefs, depth + 1, ref cache, maxDepth); localHasEntityRefs = localHasEntityRefs > recursiveHasEntityRefs ? localHasEntityRefs : recursiveHasEntityRefs; localHasBlobRefs = localHasBlobRefs > recursiveHasBlobRefs ? localHasBlobRefs : recursiveHasBlobRefs; + localHasUnityObjectRefs = localHasUnityObjectRefs > recursiveHasUnityObjectRefs ? localHasUnityObjectRefs : recursiveHasUnityObjectRefs; } // It is not possible to determine if there are entity references in a polymorphic non-sealed class type else { localHasEntityRefs = HasRefResult.MayHaveRef; localHasBlobRefs = HasRefResult.MayHaveRef; + localHasUnityObjectRefs = HasRefResult.MayHaveRef; } } if(!cache.ContainsKey(type)) - cache[type] = new EntityBlobRefResult(localHasEntityRefs, localHasBlobRefs); + cache[type] = new EntityBlobRefResult(localHasEntityRefs, localHasBlobRefs, localHasUnityObjectRefs); //Definitely seen a reference takes precedence over maybe, which is more cautious than being sure of no refs hasEntityReferences = hasEntityReferences > localHasEntityRefs ? hasEntityReferences : localHasEntityRefs; hasBlobReferences = hasBlobReferences > localHasBlobRefs ? hasBlobReferences : localHasBlobRefs; + hasUnityObjectReferences = hasUnityObjectReferences > localHasUnityObjectRefs ? hasUnityObjectReferences : localHasUnityObjectRefs; } diff --git a/Unity.Entities/ExclusiveEntityTransaction.cs b/Unity.Entities/ExclusiveEntityTransaction.cs index 07ee5af8..0644d84d 100644 --- a/Unity.Entities/ExclusiveEntityTransaction.cs +++ b/Unity.Entities/ExclusiveEntityTransaction.cs @@ -4,14 +4,19 @@ namespace Unity.Entities { /// - /// Provides an interface to safely perform operations from a single worker thread, by temporarily + /// Provides an interface to safely perform a subset of operations from a single worker thread, by temporarily /// giving that thread exclusive access to a 's . /// - /// The intended use case for this feature is to let a worker thread stream Entity data into a staging - /// and perform any necessary post-processing structural changes, prior to moving the final data into the main simulation world - /// using . This lets the main thread continue to safely process the primary world - /// while the new data is loading in, and not require a main-thread sync point until the new Entities are fully loaded - /// and ready to be injected. + /// + /// The intended use case for this interface is to let a worker thread stream Entity data into a staging + /// and perform any necessary post-processing structural changes, prior to moving the final data into the main simulation + /// world using . This lets the main thread continue to safely process + /// the primary world while the new data is loading in, and not require a main-thread sync point until the new + /// Entities are fully loaded and ready to be injected. + /// + /// **Warning:** Only the operations exposed by this struct are supported within the context + /// of an exclusive entity transaction. For more information, refer to [Safety in Entities](xref:concepts-safety). + /// /// /// public unsafe struct ExclusiveEntityTransaction @@ -19,8 +24,15 @@ public unsafe struct ExclusiveEntityTransaction private EntityManager m_Manager; /// - /// Return the entity manager this transaction operates upon + /// Return the entity manager this transaction operates upon. /// + /// + /// Do not use this property to invoke arbitrary methods from an ExclusiveEntityTransaction because it is undefined + /// behavior. Some EntityManager methods involve operations that are not + /// safe to perform from worker threads, or which might work in certain contexts but fail in others. + /// Only the operations exposed by the struct are guaranteed + /// to function correctly. + /// public EntityManager EntityManager => m_Manager; internal ExclusiveEntityTransaction(EntityManager manager) diff --git a/Unity.Entities/IJobEntity.cs b/Unity.Entities/IJobEntity.cs index 4e7465dc..73755075 100644 --- a/Unity.Entities/IJobEntity.cs +++ b/Unity.Entities/IJobEntity.cs @@ -29,6 +29,13 @@ public interface IJobEntityChunkBeginEnd /// Called at the beginning of every chunk iteration in the . /// It also tells whether or not to run `Execute` on the current . /// + /// + /// Note that the value passed to this function is also used to determine + /// which entities in the current chunk should be processed. Since the mask has already been computed, any components + /// which are enabled or disabled in this chunk during OnChunkBegin() will not affect which of the chunk's entities + /// are processed. To enable/disable components during a chunk pre-pass, it's necessary to use + /// to take full control of the chunk iteration logic. + /// /// An object providing access to the entities within a chunk. /// The index of the current chunk within the list of all chunks in all /// archetypes matched by the that the job was run against. diff --git a/Unity.Entities/Internal/InternalCompilerInterface.cs b/Unity.Entities/Internal/InternalCompilerInterface.cs index 60d44648..9d312aee 100644 --- a/Unity.Entities/Internal/InternalCompilerInterface.cs +++ b/Unity.Entities/Internal/InternalCompilerInterface.cs @@ -257,7 +257,7 @@ public static unsafe void WriteComponentData(EntityManager manager, Entity en var sizeOf = UnsafeUtility.SizeOf(); // MemCmp check is necessary to ensure we only write-back the value if we changed it in the lambda (or a called function) if (UnsafeUtility.MemCmp(UnsafeUtility.AddressOf(ref lambdaComponent), UnsafeUtility.AddressOf(ref originalComponent), sizeOf) != 0 && - ecs->HasComponent(entity, typeIndex)) + ecs->HasComponent(entity, typeIndex, out _)) { var ptr = ecs->GetComponentDataWithTypeRW(entity, typeIndex, ecs->GlobalSystemVersion); UnsafeUtility.CopyStructureToPtr(ref lambdaComponent, ptr); diff --git a/Unity.Entities/Iterators/BufferLookup.cs b/Unity.Entities/Iterators/BufferLookup.cs index 40ecfa8e..7ae8ad6e 100644 --- a/Unity.Entities/Iterators/BufferLookup.cs +++ b/Unity.Entities/Iterators/BufferLookup.cs @@ -103,13 +103,25 @@ internal BufferLookup(TypeIndex typeIndex, EntityDataAccess* access, bool isRead /// The entity. /// /// The buffer component of type T for the given entity, if it exists. /// True if the entity has a buffer component of type T, and false if it does not. - public bool TryGetBuffer(Entity entity, out DynamicBuffer bufferData) + public bool TryGetBuffer(Entity entity, out DynamicBuffer bufferData) => TryGetBuffer(entity, out bufferData, out _); + + /// + /// Retrieves the buffer components associated with the specified , if it exists. Then reports if the instance still refers to a valid entity and that it has a + /// buffer component of type T. + /// + /// The entity. + /// The buffer component of type T for the given entity, if it exists. + /// Denotes whether the given entity exists. Use to distinguish entity non-existence + /// from buffer non-existence. + /// True if the entity has a buffer component of type T, and false if it does not. + public bool TryGetBuffer(Entity entity, out DynamicBuffer bufferData, out bool entityExists) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(m_Safety0); #endif var ecs = m_Access->EntityComponentStore; - if (Hint.Unlikely(!ecs->Exists(entity))) + entityExists = ecs->Exists(entity); + if (Hint.Unlikely(!entityExists)) { bufferData = default; return false; @@ -135,21 +147,49 @@ public bool TryGetBuffer(Entity entity, out DynamicBuffer bufferData) } } + /// + /// Reports whether the specified entity exists. + /// Does not consider whether this buffer exists on the given entity. + /// + /// The referenced entity. + /// True if the entity exists, regardless of whether this entity has the given buffer. + /// + public bool EntityExists(Entity entity) + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + AtomicSafetyHandle.CheckReadAndThrow(m_Safety0); +#endif + var ecs = m_Access->EntityComponentStore; + return ecs->Exists(entity); + } + + /// + /// Reports whether the specified instance still refers to a valid entity and that it has a + /// buffer component of type T. + /// + /// The entity. + /// True if the entity has a buffer component of type T, and false if it does not. Also returns false if + /// the Entity instance refers to an entity that has been destroyed. + public bool HasBuffer(Entity entity) => HasBuffer(entity, out _); + /// /// Reports whether the specified instance still refers to a valid entity and that it has a /// buffer component of type T. /// /// The entity. + /// Denotes whether the given entity exists. Use to distinguish entity non-existence + /// from buffer non-existence. /// True if the entity has a buffer component of type T, and false if it does not. Also returns false if /// the Entity instance refers to an entity that has been destroyed. - public bool HasBuffer(Entity entity) + public bool HasBuffer(Entity entity, out bool entityExists) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(m_Safety0); #endif var ecs = m_Access->EntityComponentStore; - return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache); + return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache, out entityExists); } + /// Obsolete. Use instead. /// The entity. /// True if the entity has a buffer component of type T, and false if it does not. Also returns false if diff --git a/Unity.Entities/Iterators/ComponentLookup.cs b/Unity.Entities/Iterators/ComponentLookup.cs index e05686ac..f2ab6a3c 100644 --- a/Unity.Entities/Iterators/ComponentLookup.cs +++ b/Unity.Entities/Iterators/ComponentLookup.cs @@ -114,6 +114,22 @@ public void Update(ref SystemState systemState) #endif } + /// + /// Reports whether the specified entity exists. + /// Does not consider whether this component exists on the given entity. + /// + /// The referenced entity. + /// True if the entity exists, regardless of whether this entity has the given component. + /// + public bool EntityExists(Entity entity) + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + AtomicSafetyHandle.CheckReadAndThrow(m_Safety); +#endif + var ecs = m_Access->EntityComponentStore; + return ecs->Exists(entity); + } + /// /// Reports whether the specified instance still refers to a valid entity and that it has a /// component of type T. @@ -121,13 +137,24 @@ public void Update(ref SystemState systemState) /// The entity. /// True if the entity has a component of type T, and false if it does not. Also returns false if /// the Entity instance refers to an entity that has been destroyed. - public bool HasComponent(Entity entity) + public bool HasComponent(Entity entity) => HasComponent(entity, out _); + + /// + /// Reports whether the specified instance still refers to a valid entity and that it has a + /// component of type T. + /// + /// The entity. + /// Denotes whether the given entity exists. Use to differentiate an invalid entity + /// from the entity not having the given buffer. + /// True if the entity has a component of type T, and false if it does not. Also returns false if + /// the Entity instance refers to an entity that has been destroyed. + public bool HasComponent(Entity entity, out bool entityExists) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(m_Safety); #endif var ecs = m_Access->EntityComponentStore; - return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache); + return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache, out entityExists); } /// @@ -143,7 +170,7 @@ public bool HasComponent(SystemHandle system) AtomicSafetyHandle.CheckReadAndThrow(m_Safety); #endif var ecs = m_Access->EntityComponentStore; - return ecs->HasComponent(system.m_Entity, m_TypeIndex, ref m_Cache); + return ecs->HasComponent(system.m_Entity, m_TypeIndex, ref m_Cache, out _); } /// @@ -151,11 +178,12 @@ public bool HasComponent(SystemHandle system) /// component of type T. /// /// The entity. - /// /// The component of type T for the given entity, if it exists. + /// The component of type T for the given entity, if it exists. + /// Denotes whether the given entity exists. Use to differentiate an invalid entity + /// from the entity not having the given buffer. /// True if the entity has a component of type T, and false if it does not. - public bool TryGetComponent(Entity entity, out T componentData) + public bool TryGetComponent(Entity entity, out T componentData, out bool entityExists) { - #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(m_Safety); #endif @@ -164,10 +192,11 @@ public bool TryGetComponent(Entity entity, out T componentData) if (m_IsZeroSized != 0) { componentData = default; - return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache); + return ecs->HasComponent(entity, m_TypeIndex, ref m_Cache, out entityExists); } - if (Hint.Unlikely(!ecs->Exists(entity))) + entityExists = ecs->Exists(entity); + if (Hint.Unlikely(!entityExists)) { componentData = default; return false; @@ -182,6 +211,15 @@ public bool TryGetComponent(Entity entity, out T componentData) return true; } + /// + /// Retrieves the component associated with the specified , if it exists. Then reports if the instance still refers to a valid entity and that it has a + /// component of type T. + /// + /// The entity. + /// The component of type T for the given entity, if it exists. + /// True if the entity has a component of type T, and false if it does not. + public bool TryGetComponent(Entity entity, out T componentData) => TryGetComponent(entity, out componentData, out _); + /// /// Reports whether any of IComponentData components of the type T, in the chunk containing the /// specified , could have changed. diff --git a/Unity.Entities/Iterators/EntityQueryBuilder.cs b/Unity.Entities/Iterators/EntityQueryBuilder.cs index 8a8a2ab5..b174b68e 100644 --- a/Unity.Entities/Iterators/EntityQueryBuilder.cs +++ b/Unity.Entities/Iterators/EntityQueryBuilder.cs @@ -1717,6 +1717,10 @@ internal EntityQueryBuilder WithPresent(ComponentType* componentTypes, int count /// Add an additional query description to a single EntityQuery. /// /// + /// The ability to construct an from multiple query descriptions is preserved for backwards + /// compatibility, but the use of this feature is strongly discouraged in user projects. Queries with multiple + /// query descriptions are not guaranteed to function correctly in all contexts. + /// /// The resulting EntityQuery will match all entities matched by any individual query description. In terms of /// set theory, the query matches the union of its query descriptions, not the intersection. /// diff --git a/Unity.Entities/ManagedComponentStore.cs b/Unity.Entities/ManagedComponentStore.cs index 7eded4b1..16ed630b 100644 --- a/Unity.Entities/ManagedComponentStore.cs +++ b/Unity.Entities/ManagedComponentStore.cs @@ -39,7 +39,7 @@ internal unsafe class ManagedComponentStore UnsafeParallelMultiHashMap m_HashLookup = new UnsafeParallelMultiHashMap(128, Allocator.Persistent); - List m_SharedComponentData = new List(); + internal List m_SharedComponentData = new List(); struct SharedComponentInfo { diff --git a/Unity.Entities/Serialization/UnityObjectRef.cs b/Unity.Entities/Serialization/UnityObjectRef.cs index 6ff63cb2..dd8e8001 100644 --- a/Unity.Entities/Serialization/UnityObjectRef.cs +++ b/Unity.Entities/Serialization/UnityObjectRef.cs @@ -2,7 +2,12 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Profiling; +using Unity.Properties; +using UnityEditor; using UnityEngine; +using UnityEngine.Profiling; using Object = UnityEngine.Object; namespace Unity.Entities @@ -53,6 +58,272 @@ public int Add(int instanceId) } } +#if UNITY_EDITOR + [UnityEditor.InitializeOnLoad] +#endif + internal static class UnityObjectRefUtility + { +#if UNITY_EDITOR + static UnityObjectRefUtility() + { + EditorInitializeOnLoadMethod(); + } +#endif + + unsafe class ManagedUnityObjectRefCollector: + Properties.IPropertyBagVisitor, + Properties.IPropertyVisitor, + ITypedVisit, + IDisposable + { + UnsafeHashSet m_References; + UnsafeHashSet* m_InstanceIDRefs; + + public ManagedUnityObjectRefCollector(UnsafeHashSet* instanceIDRefs) + { + m_InstanceIDRefs = instanceIDRefs; + m_References = new UnsafeHashSet(256, Allocator.Temp); + } + + IPropertyBag GetPropertyBag(object obj) + { + var properties = PropertyBag.GetPropertyBag(obj.GetType()); + return properties; + } + + public void CollectReferences(ref object obj) + { + GetPropertyBag(obj).Accept(this, ref obj); + } + + void Properties.IPropertyBagVisitor.Visit(Properties.IPropertyBag properties, ref TContainer container) + { + foreach (var property in properties.GetProperties(ref container)) + ((Properties.IPropertyAccept)property).Accept(this, ref container); + } + + void Properties.IPropertyVisitor.Visit(Properties.Property property, + ref TContainer container) + { + if (Properties.TypeTraits.CanBeNull || !Properties.TypeTraits.IsValueType) + return; + + var value = property.GetValue(ref container); + + if (this is ITypedVisit typed) + { + typed.Visit(property, ref container, ref value); + return; + } + + Properties.PropertyContainer.Accept(this, ref value); + } + + void ITypedVisit.Visit(Properties.Property property, ref TContainer container, ref UntypedUnityObjectRef value) + { + m_InstanceIDRefs->Add(value.instanceId); + } + + public void Dispose() + { + m_References.Dispose(); + } + } + + private static unsafe void AddInstanceIDRefsFromComponent(byte* componentData, TypeManager.EntityOffsetInfo* unityObjectRefOffsets, int unityObjectRefCount, UnsafeHashSet* instanceIDRefs) + { + for (int i = 0; i < unityObjectRefCount; ++i) + { + var unityObjectRefOffset = unityObjectRefOffsets[i].Offset; + var unityObjectRefPtr = (UntypedUnityObjectRef*)(componentData + unityObjectRefOffset); + instanceIDRefs->Add(unityObjectRefPtr->instanceId); + } + } + + static unsafe void AddInstanceIDRefsFromChunk(Archetype* archetype, int entityCount, byte* chunkBuffer, UnsafeHashSet* instanceIDRefs) + { + var typeCount = archetype->TypesCount; + + for (var unordered_ti = 0; unordered_ti < typeCount; ++unordered_ti) + { + var ti = archetype->TypeMemoryOrderIndexToIndexInArchetype[unordered_ti]; + var type = archetype->Types[ti]; + if (type.IsZeroSized || type.IsManagedComponent || type.TypeIndex == ManagedComponentStore.CompanionLinkTypeIndex || type.TypeIndex == ManagedComponentStore.CompanionLinkTransformTypeIndex) + continue; + + ref readonly var ct = ref TypeManager.GetTypeInfo(type.TypeIndex); + var unityObjectRefCount = ct.UnityObjectRefOffsetCount; + + if (unityObjectRefCount == 0) + continue; + + var unityObjectRefOffsets = TypeManager.GetUnityObjectRefOffsets(ct); + int subArrayOffset = archetype->Offsets[ti]; + byte* componentArrayStart = chunkBuffer + subArrayOffset; + + if (type.IsBuffer) + { + BufferHeader* header = (BufferHeader*)componentArrayStart; + int strideSize = archetype->SizeOfs[ti]; + var elementSize = ct.ElementSize; + + for (int bi = 0; bi < entityCount; ++bi) + { + var bufferStart = BufferHeader.GetElementPointer(header); + var bufferEnd = bufferStart + header->Length * elementSize; + for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize) + { + AddInstanceIDRefsFromComponent(componentData, unityObjectRefOffsets,unityObjectRefCount, instanceIDRefs); + } + + header = (BufferHeader*)((byte*)header + strideSize); + } + } + else + { + int size = archetype->SizeOfs[ti]; + byte* end = componentArrayStart + size * entityCount; + for (var componentData = componentArrayStart; componentData < end; componentData += size) + { + AddInstanceIDRefsFromComponent(componentData, unityObjectRefOffsets, unityObjectRefCount, instanceIDRefs); + } + } + } + } + + static unsafe void AddInstanceIDRefsFromAllChunks(Archetype* archetype, UnsafeHashSet* instanceIDRefs) + { + for (var chunkIndex = 0; chunkIndex < archetype->Chunks.Count; chunkIndex++) + { + var chunk = archetype->Chunks[chunkIndex]; + var chunkPtr = chunk.GetPtr(); + var chunkBuffer = chunkPtr->Buffer; + + AddInstanceIDRefsFromChunk(archetype, chunk.Count, chunkBuffer, instanceIDRefs); + } + } + + static unsafe void AddInstanceIDRefsFromUnmanagedSharedComponents(EntityDataAccess* access, Archetype* archetype, UnsafeHashSet* instanceIDRefs) + { + int numSharedComponents = archetype->NumSharedComponents; + for (int iType = 0; iType < numSharedComponents; iType++) + { + var sharedComponents = archetype->Chunks.GetSharedComponentValueArrayForType(iType); + + for (int chunkIndex = 0; chunkIndex < archetype->Chunks.Count; chunkIndex++) + { + var sharedComponentIndex = sharedComponents[chunkIndex]; + + if (EntityComponentStore.IsUnmanagedSharedComponentIndex(sharedComponentIndex)) + { + var typeIndex = EntityComponentStore.GetComponentTypeFromSharedComponentIndex(sharedComponentIndex); + ref readonly var typeInfo = ref TypeManager.GetTypeInfo(typeIndex); + + var unityObjectRefCount = typeInfo.UnityObjectRefOffsetCount; + if (unityObjectRefCount == 0) + continue; + + var unityObjectRefOffsets = TypeManager.GetUnityObjectRefOffsets(typeInfo); + var dataPtr = (byte*)access->EntityComponentStore->GetSharedComponentDataAddr_Unmanaged(sharedComponentIndex, typeIndex); + AddInstanceIDRefsFromComponent(dataPtr, unityObjectRefOffsets, unityObjectRefCount, instanceIDRefs); + } + } + } + } + +#if !UNITY_DISABLE_MANAGED_COMPONENTS + static unsafe void AddInstanceIDRefsFromManagedComponents(EntityDataAccess* access, UnsafeHashSet* instanceIDRefs) + { + using var managedObjectRefWalker = new ManagedUnityObjectRefCollector(instanceIDRefs); + + // Managed components + s_AddFromManagedComponents.Begin(); + for (int i = 0; i < access->ManagedComponentStore.m_ManagedComponentData.Length; i++) + { + var managedComponent = access->ManagedComponentStore.m_ManagedComponentData[i]; + if (managedComponent == null) + continue; + + ref readonly var typeInfo = ref TypeManager.GetTypeInfo(TypeManager.GetTypeIndex(managedComponent.GetType())); + + if (!typeInfo.HasUnityObjectRefs || typeInfo.TypeIndex == ManagedComponentStore.CompanionReferenceTypeIndex ) + continue; + + managedObjectRefWalker.CollectReferences(ref managedComponent); + } + s_AddFromManagedComponents.End(); + + // Managed shared components + s_AddFromManagedSharedComponents.Begin(); + int sharedComponentCount = access->ManagedComponentStore.GetSharedComponentCount(); + for (int i = 0; i < sharedComponentCount; i++) + { + var managedSharedComponent = access->ManagedComponentStore.m_SharedComponentData[i]; + if (managedSharedComponent == null) + continue; + + ref readonly var typeInfo = ref TypeManager.GetTypeInfo(TypeManager.GetTypeIndex(managedSharedComponent.GetType())); + + if (!typeInfo.HasUnityObjectRefs) + continue; + + managedObjectRefWalker.CollectReferences(ref managedSharedComponent); + } + s_AddFromManagedSharedComponents.End(); + } +#endif + + private static ProfilerMarker s_AddFromChunks = new ProfilerMarker("AddFromChunks"); + private static ProfilerMarker s_AddFromUnmanagedSharedComponents = new ProfilerMarker("AddFromUnmanagaedSharedComponents"); + private static ProfilerMarker s_AddFromManagedComponents = new ProfilerMarker("AddFromManagedComponents"); + private static ProfilerMarker s_AddFromManagedSharedComponents = new ProfilerMarker("AddFromManagedSharedComponents"); + + static unsafe void AdditionalRootsHandlerDelegate(IntPtr state) + { + using var instanceIDRefs = new UnsafeHashSet(256, Allocator.Temp); + foreach (var world in World.s_AllWorlds) + { + var access = world.EntityManager.GetCheckedEntityDataAccessExclusive(); + access->CompleteAllTrackedJobs(); + for (var i = 0; i < access->EntityComponentStore->m_Archetypes.Length; ++i) + { + var archetype = access->EntityComponentStore->m_Archetypes.Ptr[i]; + + if (!archetype->HasUnityObjectRefs) + continue; + + s_AddFromChunks.Begin(); + AddInstanceIDRefsFromAllChunks(archetype, &instanceIDRefs); + s_AddFromChunks.End(); + s_AddFromUnmanagedSharedComponents.Begin(); + AddInstanceIDRefsFromUnmanagedSharedComponents(access, archetype, &instanceIDRefs); + s_AddFromUnmanagedSharedComponents.End(); + #if !UNITY_DISABLE_MANAGED_COMPONENTS + AddInstanceIDRefsFromManagedComponents(access, &instanceIDRefs); + #endif + } + } + + if (instanceIDRefs.Count == 0) + return; + + using var instanceIDs = instanceIDRefs.ToNativeArray(Allocator.Temp); +#if (UNITY_2022_3 && UNITY_2022_3_43F1_OR_NEWER) || (UNITY_6000 && UNITY_6000_0_16F1_OR_NEWER) + ResourcesAPIInternal.EntitiesAssetGC.MarkInstanceIDsAsRoot((IntPtr)instanceIDs.GetUnsafePtr(), instanceIDs.Length, state); +#endif + } + +#if !UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] +#endif + static void EditorInitializeOnLoadMethod() + { + #if (UNITY_2022_3 && UNITY_2022_3_43F1_OR_NEWER) || (UNITY_6000 && UNITY_6000_0_16F1_OR_NEWER) + ResourcesAPIInternal.EntitiesAssetGC.RegisterAdditionalRootsHandler(AdditionalRootsHandlerDelegate); + #endif + } + } + [Serializable] [StructLayout(LayoutKind.Sequential)] internal struct UntypedUnityObjectRef : IEquatable @@ -77,10 +348,12 @@ public override int GetHashCode() } /// - /// A utility structure that stores a reference of an for the BakingSystem to process in an unmanaged component. + /// A utility structure that stores a reference of an for Entities. Allows references to be stored on unmanaged component. /// /// Type of the Object that is going to be referenced by UnityObjectRef. - /// Stores the Object's instance ID. This means that the reference is only valid during the baking process. + /// Stores the Object's instance ID. Will also serialize asset references in SubScenes the same way managed components do with direct references to . This is the recommended way to store references to Unity assets in Entities as it remains unmanaged. + /// Serialization is supported on and + /// Unity assets referenced in this way will be prevented from being collect by Asset Garbage Collection (such as calling ). [Serializable] [StructLayout(LayoutKind.Sequential)] public struct UnityObjectRef : IEquatable> diff --git a/Unity.Entities/SourceGenerators/AspectGenerator.dll b/Unity.Entities/SourceGenerators/AspectGenerator.dll index 487aea0bc79032d20786f299f5a2d5987e245a4d..fedf8b0e5d0c5fbfde182d4375c77ca74f2c8439 100644 GIT binary patch delta 6011 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 diff --git a/Unity.Entities/SourceGenerators/AspectGenerator.pdb b/Unity.Entities/SourceGenerators/AspectGenerator.pdb index c2fa66e8926f17ff5aa127a08942565f3de8065a..4a92d9d92a5cabb772b0a5d7150119b8c87cd4d9 100644 GIT binary patch delta 2881 zcmZwH30PBC8V2D1W+RY*s353->?na4LWD#>g`gCuwJwwjZV&=Q*(7KOss_ZZs8zU# zOJUR}S`@d@py-TC5i4zJT?Q$NN~;#D7RP;QD^9<})_KIa5AXfX`Sa)Aa}#p5H8b5U z%v!~?6)r?xi-;Du5><0Co?MWx%gN9a4rdP{9?~meGPz(}Y#zrX#6}~lF@GNeuc)lt zRLuWgx?UI(buq@+;F0lkOnSeH(_c20udOtQ@!E1?sERn$jBH1W7={Kj9C{Bq1GyHt z1$hy93pt#_P$Y*#dgM~%5o8OJxD55hltuRcU6f<0r8Luh42|;0P`dXuxR{#KUArhD?|T3tENS7twyi2QcRoFV%iTaa37w7O|+Pt%-fOW5L1X{Y)cV; z=GbV{eSX#egOfKy8h>nWmi>&66aYiRBtoP$*nr4V`$l4mw1YliZ>fdJ`ytH_;sB18 zTD{x}=?nv5kfoLzjO~=Lm696_vDAn>*vl?`{j-(6nESy{7-o4bD?)+{fIyI1YRe+o z0j_T2_;gv|hh;t#av2_75;Wo5F8H3|QW5Vd&iQ;UhevG!4bH6sFD{SH3zR}DvXlMj zCM16~xeKX8ZOU;y$+aJxSZ3#|%NbX{r|ci&`aXHd$~-2zanvJ)2|2og!pZp>Zkl#J zGmn>+Tc8(Yr|1i``7G;^*~e}g!?W$%-+9Q;u()K6o)vlq+4p&)R@}hGcq)1qpR=EM z2KOqKgtOmx%6k_Ltc{nlcd?Ou-z%nH-#2cw*m|)uTk9o%yPV42_ENlE{+tc;9`Sa$ zo6Y|}<D4l9f2QbgcWZ-hwnIH)qb0kGKaCxqW*jBd~D>Txw}8Gzp%eF zP6M>x+htxpRE%bO+;r0EzngJ7;1--Bt){ygS1bkGrpCH+4@Lyuo+lj``!i z%M2^H+MQgvX6c5E;OD<4cikJb+~2eEzHZj4AMd_*R`-xIBvPNJ)fB{NbF}#>1-bds zNWEU0otjk`o0Fa^)#zV6xZ$t=iC0g)bg;YKM>oT(AH`nkdNj}VbN9x@mooFJs*7(8 zUdvo4??2c6x02~S`1$Q&&&D^&9GdSfec5MCjliJh_Jgc?Sy*l1#UIqS&;R=Stje^bJFZHddIZyq zV^Z^!nO!q(^AD;{M>lS(X$o3XF>Lz0T94~}I{7PG!{gF*ixv(v4NZ?dDX-YxS}@2o zaJ*;Hy6x<$iff0?CUuQCSi9p^RdPu!_00Tkuc6O{o|&`5dUX1k`tqh-hMNP{@4cJ2 z$-yyBG(|a~{mJoXd`8SzGeU;XFpC}MYxDKG+#HgVCO11zm!-`Q{Hvsp2Fawdz+kCd z5gdexLLwib(kkUzRk~c3mKKaZtwt3RlpZ`no|dLbSEXv?Dp{ypn?hMBIT`a(GPI;- z%YEktDy1@Ms6?KUlBNww)uzhO5*!kmo~8=bC}g3s6h)9qsg%jnwIM+onQ6G6FXP-% zpS0Dy@BS8DFhRG^U0p712z}ZwwL{Pcg<8#@NmnpPBxqjuhC{iOq#N zKc;RJYHV}tVIg`j$7FfjMkh>mZDC$_?b`jS(G(h=WO?%ee{-{?%x<1Ihf^nJ#gmS3 vjHgV^lV0#F*D~M1)ROp&*VlYy%l*ukG~d$HI?bB*zcpAcW4bfzpPWAc`aT2L delta 2233 zcmZY9drVVj7zXh7^t7eWma7Uf3X~#ODZO8WNsBUcic^71(dnREL{U&M#-UcNE>2w{ z9G5va=kOBj5ESdi(3yEzRL17*52F$tW66}M3Ct~CXZD<Ku zX7-$6wwPwGh$7OgBC1gleZiv6uUk^NsG^o|DAYt^q^2;Rf>GD-b#CFr@yOK}$7f@l zT~%Fzv34Np@S~5?-|8$nxA)l8eFx`k9)7Z6%T{*)uGJGm8%RW*$TP^tNPk8|nG8d3 zBUd0dB2OYOAj3rrC5l8e6IqGefow(gA^$=qvJ6>S5xJ0yk-L%YNR^l&y;wv`kRKv( za5<6?x0JT1rSt&K#z`q$BPET7p{t1u^Tks%_C7YI|InWA` z=`7WQC!K#8mNubogf=(|XW;@|f!=g6-GUe$Ki7}e==^B&^V-c}um@V;5Iok&$f}o7 zE=+;%A=MxwBea3lD5ES`2?H?KB%?042v^}Z=!Zdg2#ndE3SbtLKqb_`GFWBychhFb!O=6js7U_!QdUI9!5j&d$@f`$)4@^>a3WVUZW zQZ>STTa6tf3EP{npGlBXVCdf@8PXs4eM&C$zD!mk10e{4g%V)LHH2YU4~p zTerB5IOCAkniTF)oMC8d0hg(<4Q;h>>omE+K`$-8W^gTW*ENP$n-e&7yy?~EMy?{> z{A%+Y*Y;Y|6UO}$KYGZsJu^7{sG)D@Y2<20Rhh$HdL7Rt&t=aI&)wLu_VEuBu8qiD zKI@ab(IvKDwOyyLosfBF^`9E1T{y0FCD)M<>wNvrb<<;?boVIN?8vA-4DqAKU{09WtDjBux$}yIn-4tYCkt)vX8r2(yt4X%3`$H>9ikpPx>NNW|x>9Pbniq=Ot|IA3&dkolw(V~1&K8!~ z8WKSUEyrtXRV<+}7(+D3Xd#Foye|5==rW1!vOhXA>KVRw&il@D;G8pGc7w`pQ1@;Z zyyF(coa3M!_L1&$c%@WJC$arJy2c_Z~`g-ffTFW4%^PRwGPEEU7t55@0dt--X>l}zsYMg^oU1M<9TF{e%o)jPk%Qz5RwVkuH z74IX=h_2bqDSpojxt07;-GfTDYIvA{N_UGCHUFYousIcMJ zAukH4zeAgT^RITLH@Z|E$k8he-JjkLsXwQj7Pkih?V=f)amrqQ#Kn62ktUy4c6nu% zl?7h#yZvsj>=9X)*eLiJLFCo?na^ndyZ*5)Ks`Z<-0eeBljMFUvExDc9w+$)&OB~; zaOlSB+DNuUuy?D%%Bjt@v1UZTKr`2$h$^Gul*mP-D_n+)B$YH5=hKRm;)1*wjKTVbT1rSMUP-3X+;%X|1(NZ2GQlN<;R{?yx+w8! ziAzXITHzBBJ{57(%nm|diU<(yI_dVYu)9^y&Q{6!MyG## zFrsLKISznuHg#0-P-Yh@Q7$z6(<8v=xv2^O=l-%XfHo)x1SL>MST|u6kOIIuw~shz zi|XhBM%6&l{5`;_Oo_QW97vCqfpBe`Jp%zSnKNM0au|a4oTlV7B?n=c!d;$Ky4BWc zC?X!emJ^10xTjdp&i1COKTk-EkO_{=l1mdiX$?zbwSqfEZ!oYKak|a!3vlNpmvYd(S5cRvf*`dWCBO9~0PUzaYnCJ{shuU?aojEzDSO6nuRr8e3W+-(T%s zf9f|2{VR1J?Vof%nvPWVk`3Aek1wVUkOdh})#HWK6}+Bm#+G!uWm%m`9?KLym!3gp qypyh>ej>$@nLs)Y_Tgu94cIaN9gocq7CzryLb*e+E&M`BuHZkw#mkfc diff --git a/Unity.Entities/SourceGenerators/Common.pdb b/Unity.Entities/SourceGenerators/Common.pdb index 8bd45c34795d4f23fca08b69abab8967e59dd1d0..c3293739b4166f5d9ef5272874655efb755704ce 100644 GIT binary patch delta 2972 zcmZYB3se(V8VB%iLI@E81fj?q1c5+ENJ4lO6$HTwYE=wq@c|?OQ6Lmh$`%b0QH!)9 zLlw1JyMUsu*b4aE`dHM~)<<0*Jz8NcTB{zccGaqTtnPoJa@sV<-~HeF&AoRfnN08) z%QQ7J4eFUIoQVP!6IHno-LOJGy}Y!bIKPbW%622-BLg()q(i@&>yOinAB((!u_6NF z#6m+Z#`_OsSKH*ePUy_tn|Sv?)thHDRZmwpG#Q8D*dk)6o_KT&c>!t9FyzhfXd-eJ zl0~*4FC%Xwop}re@OYGkoR8drJczu5{2y|J6+>z(9%Um-kZs6r^a88D55Tjh%Uo5_!)kINAS$NKtxs{_GAZTV1#;D z2j9Z?Ar90BFCZ$^fu_MS_zkhx6;mLDK?JOUjYc%Bumg4j6DB4hIKoco zhEvcB0-2b~panYN7$nNYlnPVjPBa_d10$@24mbd}z%|^7yu*i5DolatFb5{(p{amI zSO=TKxsS=2wuU>?H!xJ;Opg>?je7}bl2Sk!Fbi}rU-|L~cdSf_o9=6*A=IrLLU)xS z8mPIP&2jGL_DF43AqWD|j&Tjy2&DSKl@AP+O~z?z>>Yoq`eIuIyC4gp)R0}(Lf z7UY0*1Ti?7YkPz6@Dm<B$bd|!#l>~eI{K2DDVVG& zO&E;NPit$%@M(-N0ByWbi*~%Q#oYFo+W;P)#tDlsg9FLJ zBr8583AN_dWN!BfZRn0-vsg&2%FbdJTfW#cv(6!?pg5&#XWi#1PLH0m@3~F!;U&E( z)D#z#SEiS0t#tZ@%mTj7P+le|$|)@ezC8U13pNGMaVrh_Wm$W;K5;9%I*egj&q3v1QMBSf0IREIZ6I!E$Cj ztM?4IEM8^*?rFKF$&{t>uv~tJZS}T1QLT)<<6UTc<4>P_?Sk6M+9kCOe!Pk4yX)5X<*g{KzIZjZ z&c{>SGfeg%GoCqNydrx)Kd$=I@3?Pc{TH_XQn(~PPJHp>x$$GBzWa|1@r5r;GI{^~ zd7ln%Zf*Rhb>ggb|lXSuYvhDnq9-#Rlc+GmAevSvRYPxgM*2T9*v{{3TVPtcL#o}XuA)%4A!g^9cGJrIf7mt^+icWP() zf6{ss;>F<)jWNHqetl)Zj*EB1H?#Xqej9F?o-}M(8`Tih*!t1)$6GYtEQ^;EuH9Ny z@pw_i+BCP1R?Ry!Y?&gsTXUTkI4@Uu`1X-Yn^KF7)!V&t(nJrLhRB2?p@B6~U5<0s zjCGy+iA~{#llv0d-?D1DAXt*Ny(?wj@Seu1lC~vZd+nJiTwXo-1TTNo2HCG^KPU?Z zj>nB}UVivO)xfzYvy1kHWuJFjdGXQn$ms#j9qt{i51#Z%m4Y1;)S2;CHOKcFwr#KQ z-%#7VKEL}oYh0Za8aQsN!Q?*Tdh*@%3vW4`^{^gl>iHn!mv=W!*|2E6q`50U=Jc1k z)XZ6tW1k(ZIMJ_O)i`7QoK0Va)y-)9yk2)(z41h03cF&q?)Hcl-M)dAjLM038B^Yi?bbB|3293c)sI7&&@qI{g)3rEtB^a?^1_^Ho3N!tS>fpFS_T<*fG|OEn~y* z8K%Z{p}w@Nz)*}|R;{6^q@Yk=Dtld0%asbbLKY!csUwsasHLjNSbdC2ADgFA=yVbI zr`N_tDf1#CRXUwEFE&@Jid96b^f^?RQ=GpbCtpuV0aRvKP^#6-@~}5M*;glvkt^iU zQdLflP9K%4&sAW4L{xO1E;d@LRzxdu)XLbH7=v}Lj$BV&Zz*gSY=WX9{k19soYwbtgD?6gq^Zq1ha+_bIs?3qzP+<5Ecm)o!} zMx8J(3uM}dv!_REB<6$M-^4iKR4b;K5MyA<;UqPi^%Ri^C$vu!jxBw?`w4&W-b{bXK|(D`w~GRA3eGIu=*%#QTV ou*7pbZYsAecfr`8(=IuV@pw5E%Q2PP_tin{-kF`E!~b6C|2d=itpET3 delta 2362 zcmZwJ3rtg27zgn0^l<@cYk8==Uxk8D`fh1uLlBYaWDEfxb5kB|Q6~=pUGPB#th!`Q z=g~}^#tlR?KC+EzOr|alqjS-1B-3QhJ=JAqW}2BS@s;d#L)Pbe%*k(L^`o=vTJ4E^caQBOFyRL<*#?x{~Ii-y-%)tEW#zeueQP zGsaVvHrHYNNx|hkC%^onq^IVXaYJBIXX>`XzAVryo?M{FdCe=BADBSoxVNmtU8G)t$Xc~GOn{Zlw~ z>B4C%^ywHKg1eBI&L|y9(`D2S@1)DA9}a_%A+CG&P>?!9L2f9A+3*IOADt)ApBVxv z6ZHbAAPVC2;szm9e=ff=8ucB_fiU!~)9D|cE1Yb)FR5Ywt(+^OTsirb` z4H{r4^k-`5FkAvfmWI-x3g*LGup17*&8)F>J4;LV-~q6STJpe~el)Gn0c+t~xB@@H zs%$Owz%Doh-$PN3mX<*mYz3`BOEHjQh#&(@gEE*0t6?J?ha2#hA(CQpBPkj5kPENa z(Ud?9G(c0X_%%h*^4uue0l&hKQLKrFKnW&+(jf<|;5Ln%5ziHw@X(X}6h=L!F#6o2 zqB}rl6@@?yOawFJK>>d7BZrDgp6OSN_SH0Zw6CRwW-a-k306pTEv=QRQpSGGR(vaE4`sgqyUUI>OzrWFb2W_9|!e6 zbQ0w41I^ye*4&u+4 z(Oi8dG7Ba`wp8=!4M_13iH}75>KU!lTaZ?;fnBQY(mRoP-~zW)%gW40z5p*mfmAz{ zS%~EOqtg5p6KA0NGR%ZBU}Q6tBVUCIm?hO#=T;%BVK&Tx0B-Ix+DWHq2W8?Lj2ALV zNtRGKlT(DCLpxTeM;j~jN$rr->SS`7AQVe&k4&D4!4L-HgkrgzqJ(;>?UC9Op#q&S zey9zhR@30h=rIbuEv6z;-rUk2THUm`y`!?VUg2qOZ{zaV1!|Rvm{Jp!U@9n|vw*k6 zx-{x%Dr@)h6S3~#(oN3d%t56t122km2A7ub4bPX3@=I~q!L$D1A@RXi?9S%p@r6ON zx?A|(cvEocH2*n1c(3kqG^@wPs}dZ+rAEFpA^3_tAM@W5tiiMX<+{Y+h3lMr z(etGaek9Qrv~b-?em60A`*n}GD`}}e>X~mfP#h=?lm`~16u76}*Iyl9+A)87nW4`0 zi}Av_t7k$F&c8JjZEP$)vSxg7b7Nz3ld-6+&D&VFv}1acui04N_CI?KrQEo1>$~Hc z-{;xaO!_n@xn}o^V~V%C@~2(jx@P91ixzFCjfFEM8^c1Fg0b#sZb?maI*sOBo6%~s zTC7HEjwjDmYjN7@99Dhhc}pWSCRyB!X<+2^kHcx`s4o3Bq@Jtfa*Hac=# zX1mqnwA5Mh9CowU?)Ext4yW5|%d@&XR$pzcrQYFoI$SndTHDmHytcucyTaSrwz#>8 zESABkX|W06y|-EKJ=UjTeHnaFfh!c_k->q2*-r;&xG?#Br8JZGPHq<0>^m(^+xH_+ zDAbGN{-lv@cv;~&aT)gPzr*8;s>`I4;@_wI&{=ZUds`b$YE7Kl5F@0JlalQupoq=H zDcTa7wz8wG-P>raTGZ;T_29n|m3X@Uj=1CgxB01}o(Z_{(<`w34^U-&XV`#>&zaJx z!3o^jz@WIIPcwLZ%6b+tIvF>KwFgrNS56(4iBqLX_!QV+a9(LXiyN6LE>Dv76+hz0 L?t@2P^2q-K4(i&^ diff --git a/Unity.Entities/SourceGenerators/JobEntityGenerator.dll b/Unity.Entities/SourceGenerators/JobEntityGenerator.dll index c43b254d26946f279a5d5ebf9bf3b900857d933f..b5358a17db0266339b8fb4cc379cf3fd4c8c5053 100644 GIT binary patch literal 80384 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 PNrjit-fxS1tT6EZu4?>1 literal 80896 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 btxfO`5^TU)9w=LmVe94J@|f4Y^tb;2!j)G- delta 4600 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 jobEntityInfos) + internal IjeSchedulingSyntaxWalker(ref SystemDescription systemDescription, Dictionary jobEntityInfos) : base(SyntaxWalkerDepth.Trivia) { _uniqueId = 0; _systemDescription = systemDescription; - _schedulingInvocationNodes = - jobEntityInfos.GroupBy(info => info.Candidate.Invocation) - .ToDictionary(group => group.Key, group => group.Single()); + _schedulingInvocationNodes = jobEntityInfos; _schedulingArgsInnerWriter = new StringWriter(); _schedulingArgsWriter = new IndentedTextWriter(_schedulingArgsInnerWriter); diff --git a/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityDescription.cs b/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityDescription.cs index c823e811..4bb77450 100644 --- a/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityDescription.cs +++ b/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityDescription.cs @@ -120,6 +120,14 @@ JobEntityParam CreateJobEntityParam(IParameterSymbol parameterSymbol, bool perfo var typeArgSymbol = namedTypeSymbol.TypeArguments.Single(); var fullName = namedTypeSymbol.ConstructedFrom.ToFullName(); + // If user has passed in a type that is not accessible then it likely means they have a compile error in their code + // since the compile error will be shown in the editor, we can safely ignore reporting it ourselves + if (typeArgSymbol.DeclaredAccessibility == Accessibility.NotApplicable) + { + Invalid = true; + return null; + } + switch (fullName) { // Dynamic Buffer diff --git a/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityModule.cs b/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityModule.cs index f21e5f95..1b3e35f5 100644 --- a/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityModule.cs +++ b/Unity.Entities/SourceGenerators/Source~/JobEntityGenerator/JobEntityModule.cs @@ -59,12 +59,12 @@ public void OnReceiveSyntaxNode(SyntaxNode node, Dictionary(candidates.Count); + var validCandidates = new Dictionary(candidates.Count); foreach (var candidate in candidates) if (JobEntityInstanceInfo.TryCreate(ref systemDescription, candidate, out var knownJobEntityInfo)) { - validCandidates.Add(knownJobEntityInfo); + validCandidates[candidate.Invocation] = knownJobEntityInfo; systemDescription.CandidateNodes.Add( key: candidate.Invocation, value: new CandidateSyntax(CandidateType.IJobEntity, CandidateFlags.None, candidate.Invocation)); diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.Common.dll b/Unity.Entities/SourceGenerators/SystemGenerator.Common.dll index eed31056960e10f5e6ad8bf2a58302a79da2cd8e..ea0d6220516870c41d9abdc0cced5a0ae94092ea 100644 GIT binary patch delta 737 zcmXw1O-vI(6n?X!A(ttvsdO*dj-FDfs!~iNF2`a=Q1YKkISBkR5-K_>qpmH)% z5}WZZ9&0#|Y&>|!U>YGsJa{0%codXGg`je9w$eBGzIpS#_a<*LFFoT*&$ymFc5i+9 zyPbJjjjm;~1Lb?y0eZkO1Us%w&|g}Ipp+cvz5?{&Aax24qIwj^j|lJJEE+(~7*YN` zo+qRPGmBBXmzry(D*blg+>rZ_2fkHq1psQG4PJr=Pjwza9y{Clwu&nC`Q-^m5YP-AqC*WD%PR~Q;gzOFR%2L=<1|T> z_%I)4wTR3ya#Z3&k}TTU+)u=kM_-PzuK-=@rHDUIP`O61K%8AeWcL%)6ReWhDqeVh zY$CO(!n*HZ_teJS?C-UQJ}2vZvv5^USYt6m78LcKkP?)nWeOvrX{mZ&1HNy8NW3*$m;j9fKB0{DKetXfD)!@?Ey zjw+g}psSW?iMk>hN|+7_SkDDo=ut(2Sl8KbBL}+;UoST7Jp1CtgIxd0_*VJQyB{X1Dy9HT79u#1JgGj+^f<~fgL~)oSO9Kf+0v^HzIC=zR5@85O3y~0EnPdS@EVm!{423xr N&e-0M8z>Xn_YZiy-~Ipq delta 575 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 Lm}QK{f86wc0fRMO delta 2495 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 H<=OuStcWs< diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.EntityQueryBulkOperations.pdb b/Unity.Entities/SourceGenerators/SystemGenerator.EntityQueryBulkOperations.pdb index 4da234f0129ffde283f9a66d44c9476f5a07b848..e8d18861cb5975870ad29224d84a535172d2b7ea 100644 GIT binary patch delta 1303 zcmZuw3rv$&7`^{*DdnLSRskVao&_oG{ywBF=!EhbB3K?30o{N;pjrznl|@l0vH~L* z!M_29u&#gtQK!7-BhCm!mI_Xo!#N)fpd%=VC}Ze&?dp=nExWnro^#LrzTBMT-i3s# zN#)#K`V|0p90A}E0f1~2>UfP>p~}bsa7+>bfHv?D$Af98Q{UXa)Vi^EJ6JD3AwXX*XSP*=OEfBE~^PVU`;jMoU6j;5}C?LP*IsT(z6<&+j z;@=<^?ajzhRJ7;@69Sm{T`UX8FcrL>;z5FJ1z`QmMkh75R^52ws?TCx!_Kak*|#qrSVgye7}fTqyru9^9j%K_H&Qp@ zNl8l$`~mSDojB{UTKK}$anL8|*|o6Ulm-VsddTRN%`%CbFr_xep-=QHvBy1w&E3v50C=>H{H?gt|JjW zW>S6ZnD6|O*Rdk~Z0y3bllCoLYlo;ashMZ4(+l=S!N=K&M@6k*QFL>QcZ7b zXF&27$!9N-4dcRHQZ|p%wJq+1OW#5sr!LO#qj4cFp4u$N5T7Ej7JL=S%-;Y0a zY#wBHFDR3gy^;;cURY=Im6?^4-(8_f3cNN|0kf(5)D^HNqQvhWi5vEtgvz z1i?jKc~!mW9f4nCoDsdrM>pJ6C8YPQigEa5+RMK8B`;%XqUmYwRs4#!_`cnarjvc+ zRGoEIMR;+{#hLEf9^d#`Q(|yFH);0t=^D=N?ImaXH;u%cANu6GIn4jcfM?6Knaqit z^Jdjp^yZzH%u^G0$qebpgTn^VTyweLp*hoG>4nv~2OW|1i*i*~&M95%&@1k?#o>$I zMT)P>h>9bJ_!N_ zSvm%Njz3Q>74RfnjEALhSpq&EW6Nd!ED6@W$(n{Z-S0>?zWt+rhHADe&bx+GFfTH; znfp@kGqiQ>RW=RIPJi5+e+_~VFgy5zdNf}jb|EVvNc+>^6dp(W-p(jOjG2hB5HZ#u c#!HCtQM;=*5ure@{@(jGQvakqz(%Meul+KXUJUQ?q^>}tZce;?Ug+)n%iHJgOZWFiv3W~z=A}=De46>pwQWr(tSYGsB7h%u~Kc44(&hvhq`;FVD#>D2) z6aeQ1fGz_<(bt8$+dJEO0LMEM0LI{~uY-^1Ym>gZ{+I_8;#)hFbf3k0)+(XFVr?dV1Q6qMqNiGurHs$CPEns41-Is zW!g`{hB%NMq#Ri(pzyXJ`8_!(eEQ=lZ0^Xu|MghWrb)UMCq{jSj8M<(e2Q7}O37y# z5quRM|COPe-`O7StLttx z_(S0yEo7dw+bVz{4_bFZUaZw_g()Pu@@R!%bprJ-o>Dc{%femtwBH?4N?N!5>L zedzqNjKt!?&pi7`h8D5r$ui583oI}2E}rE}{fgV`k_Df{OF_RP1cE+Ab_c~E$ElK} zazWMW4+x^HYA>w=ATQln{m08pDrtN4+^Q%d-rY&7lI~lEY)oR=KM_*oEX1g|# zBpr-7P4@jXn6?+-;YH`tVkV8w_aG*qGgbb_LkiP}O3Iv66t{t%?zd)tEEa6b8- z?>+C_`^de?UbbehTHn6xSbo=j1@^`!IP3?|4G<;(6}zTmGWXF~^_>X<&v9dl0F`qM zHI-Qcl`OwFPT+-n18K{TV>4;#%3r{yN2t7831#_Du@xivU(iuUCRtN9j?XnG5i1EL4J^LDLI6?t4hmocYtwG_qsU&_o4YHrEC0)e{+lf? zmXh7&1GJenn$P3TAP(f8-DwZ@(gLJmw)Q$`f=30LIT+xPzCAG{XeW&KB$7ZcN&v!f|ZiRovQc_o(2q?I`} zozYXuh^n1dPw8nzOU}9Gd7Vp7WTrFI%o2~e2KLj@Mmed^>S|h75_%?`Q4=vW74y2>iurVyJZUDwq|&>$*VUoDy|Pz6 zL!Y0iptj#`-KctO>>+!t{bA!*+Ma88f{;n`n=m?J6ETM*hH@yZm2}flY4! delta 1112 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 Cb~Et+ diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.Query.dll b/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.Query.dll index 755d1ebbf6e4cb18469e522fc58baa3dfd278c67..118530d53eeed517055682840ed047c566043189 100644 GIT binary patch delta 5360 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 delta 5287 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 EFZTbYO#lD@ delta 1767 zcmZwG3v5$W7zgn0+}=J0tnAT^QQDO~aC48Y_uf8vZA@fC9s}kW2rjg1JBPTz*aQSE zY)dqQC~)KvFvc~(Xoe8%AZSQL7l}$7s1X=wCW4|Uz92zf;=cn1H8%O3|GD2e_ngz4 zdynsB?Okl6eW59ZDC-3xT`JKPHTsp!P4x|R%L%`mqliRgR#hdDiD+rGUsg4BGIA-d z4IW&VE@|}P`qr*JY1YiekG^KIuKaq)-r9uTLvL={xFM8)v6qR_P7@zai_B3ma;OCAMD9mwL`FtYz)tsnjOJu8 zIu=561}?y5xD7)y8I6D}D9RLQ9F)RTm<82f$`U9G@<0MN6vGsl0gpp349muG!3Y_U z3q|0B2@sl$W*W?a`QXh~(YYLf4&(}S60YV(&#a<_5349OPo%NngT=56Rze^Akguj+ z;WAtYR-h&wd;srRHMCmN&`#I~$0RLXf-90XL^se8WG%%(0*ruk7y|{Mz*v|BuUO4QPWkp4O;uX#kDlt zuBBAFj?CbOVwf^GuA}OEeXbMJ@N{Xf9jCEGd#^b8SyftOytpVq_&9^VZZHZrGWq)k zJv`6N?lqoeLO%QWPO_iD+rlN78Tc@ENx!dD4bl!FltwB14c9Qfr+NUJaYw0;< zo<2Id60JenKF}T-HX z(cjp-oOhX4#}6warq(B$iY8W6ui#FzqK|)|vi1;PWu6dQy2X!}tudu_ZFAe6 zX!Er#8$Ho8`PxILQ_EH@*fOKQ=kB+DdgSzny0;hn++(ml^T<2T7x6z#7G9o_;Q621 zPmEq~YTR^u%zSO@U+uMzQV!(`qYJtg<3Y zvQ^IayWC#MsrVeSBj|T2fuPUjbO-H0o6X~Jcx*wB*B?;qP7klhT2tz>+N_Rzx6Lm5 zosv&-IqbH8-4k#q4yPxexMa6q4tl*(t;6GVxD{IBZK!MU)&&Zm4KyvUZ)_k*io|Cp zv9!-y+Al@lF74*;&s>Y|n$~?_UswG6p*JJ0F^7$59q;yTqY_5H{PyLaqe7Y)Z#hrw z(Dz@|^5G>dy3QKb*}^)vL^hOInK@j;!T}au%fcNDBjK$q+|9y$cc+}3)TmCpJLS%J zH%21WW!)?>dfWY4bV1Y93L!ds_p1YIVsK!eHPeoYiFay)J9M`2d9(WTv1{<+*;e(y MZjq+hH5x|$0$t*QF#rGn diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.QueryBuilder.dll b/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.QueryBuilder.dll index 5c1b2fbf4a00d17f698286217fe8b9e6619aa063..a05fd3cf336d84a8a9595079cb32539bc995bbb5 100644 GIT binary patch delta 831 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 WW6mQ#-kE7-NB*9AOYxWBtLz^c6$N|% diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.dll b/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.dll index ec7745918cc2c65c961abb462a53c8b0e94bdc90..cd0ee075956b245ac545280712d3d8849c0ac727 100644 GIT binary patch delta 4573 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 J3h55X{{htjWPShu diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.pdb b/Unity.Entities/SourceGenerators/SystemGenerator.SystemAPI.pdb index 1a3665b86fc3c98c029fa45f80a62f1aab9278dd..1c965f9bb342c79f998055db0d886f2618a18b83 100644 GIT binary patch delta 2553 zcmaKu30PBC7RS$fc`PD?u&-)BKS>OPYyttREG~e6R=@>i6tZ9xiLAq72?$KtY@siT zGa$&)QA>5O(6Jq<77%Se>xdNXR4L9N+N#v0qKMPdIpAZ^>eu(>f%5MP>jLwsWH+!5`muPQ0&(4q1wA3v$0Z za$ur19@!@G@lQ=2_I@Dy8P zf`kx)fDPDIVS5N$E0O>{NrDZF009f-Fb@G|TnON~k|0OB<;sH7ZY=l(Z6S{Z!F(2E zq8&l|oKM0Xw1@nOPzv-5D5yp|KMTJG(e9v$1r#Kr_~#D=1@3eQVMX^4)TDh)yg^)} zEyy{#VjN)zX23zc&j^4BhAokUQC_k2^M0G(uq`sl0@#N!6Y&nnZy+m}cqimu7Gr=mCSHte zjisL&FGD_oJk{@wyxl}MJ-` zrsKCG#~^1g0+NvTB2UHdM4n?i9iI#Y3vz5*k5QopIu|_l0C-|1e~?&sJXU}KJ+4?( zz`_CkegW$Nm~-?Gxnb%6(}PDB0Mh`tRrD7wK!p>k09OJ#GA@~#M^3Y~vmjhZ+O(PeV1267^jrEUo6C7QDxXhZV=w-#Gn;lZ zPt@7GG=KgV`CsMt<=^0v;gKJe{$)U2oRW9BUtT)fiPL50@o3!=;;infM^1uYUR@97 zCA$2$NvFtq*=XRe|G5+ruqOG#wVb}=1s=k|2ixjg_BXxP&if^&aec?bofkjNVhc?B zSAH~9ain0^f%zQ*LH+DS^oE%6MxUPOuZyC!H&O!cf7zDJ^S^UyS*&%Vt-By-F!-M< zyk{319+)@aCmR|5Zb#Q}l+*tCe?FWMeqpO$+IPbn_3sw#Pmn$x+j#T7# z%K!ai#6`_dB%dBObI=I`Qd3ns;uEt%lGIwEBK39K-F=rE9;QewjJ-XavhQX|MC#^Z z`S&LAr~hz$_(^AZ;NA2ye)(IR@b)=MUtHNGvOageVBGxO1J)Z(Cbh=Q>U0jv;GFdu z;m+mO{_xNW|*RK0bRVd7_Wa{lTH6CU4;tcud?=?mN~9~%l~ zRq~xb;Rwkk(p3v};bcgy9)ACIoSs{N+yLU!g@u2+<#c5l+@ zvfLo;n_O|`;;lCa?ize7?=Bqwr1pEomG}6uvO_L|<^wj>-5UGw8zWD$&vrVLx$di& zS9^wbsP5%8d50{D;K{FNG)Bj)xuzBF80|M1wj0wGRbPK==){4wqaBa#9UpQnT6e)i z7#sPa>`N29?ctrZ$K2XG>~`DGe9kN%u}CQLkP0O-saPfy%LI~za+QxnC09#CN~IJ( zDuvujtd=g6D3uDeJYFG@i@YVOIC>W+C(uVI5_$_HadAqOSG+1-gnp@)w^}LpR>(x& zqBxmY?&Bkps8wEKg-8mCaY+g3aS1Aq3{^_1Mwb7r zldZsk#7k?^y^hMF9|<*H6Qcg>vbV7 zibZw5vu?7e)9+O|Y$_LJ6M1cux_>9WHAY-U*kSGuef4VkTYr{3BZ#N;sO%l~2b#&+ MFokKQ7Y39610N=d+W-In delta 1888 zcmZXVdu&s66vxl+_O|QjdNB90cGpjJruSvw#5ac z8!{cDNWCHp7+FG;DFKB}!i*TfNt~jf5)pii;9nq*D2Wjt!Ed`;I^`y(zxz3_-}#;2 zY5PL^56!!5YkK2}rfwl>n?UpdhxdxM*2bp#jfBUnCE~G8t*js$-mAm!C6$YcvAzOc zmy(DhUeb+tEK>ACY)aMujBJ2+Ipgy1zX5YDuN81)fH*RlSA z)y)`{Fphe#N?7k<)pHy@&M|7m8hscYoWe+B;3yL^Vo*@-bOkj)`XQlg1^o<3HYzC3 z$WbL^jWHa{(>)_ksu?^vvhd-7R6<^ZT+E3k=jm3Cbc*Sv^Nf$kH*7XjOB1;%flm0S zNJ~km_ZLP~DzgskMtQ^fF?-7YI2Ak!`>Tiv$4>%hD2Qt1_{rdRz=vec1Z&WsGMTf$ zn|TV*URhy)B2`KBqRdml2gY$W*sO}#bHFFTZn*#x_@6kspU(o`qmKF8zXlOTg1G zQ_%x11|JQKQ+S{#6k-m`z@LNf$_XmL!-+&nxqy}6ktCu|W&2~`;6$QLvb`F77Q9ln zd%-Jou>xzsfn!iaEA&B;fcuUns0WvTqX`{pn;Uo5q_~Uz+>!*FfoxYBrYCfMFI3w~8@I?w0&CKl+lr$$B=6MyNXD0l}NiEt( zbc*JdHg#oFV_RoMYc20|q5C?KX3^qB>PWmOxb6+(G|cATbb$gutPyF5F& zOnqkAn~A*_6P>+A9k<)OJXm&PuEsXJy;!;=7=-aL-IJvF#KQlo8l_d;&gT^UbzY~#RcEU+o85N1+g#_a@%crY!!5n1+cei{GMnsqF0;+*b6C6< zr`=}u+uVM;Xm_~%qSNZ~S?g+QEVXvG!|oDkT}@McdriGRzr)|Uv9Y;{ES6BKUdPhE zXy0}-e2H-{U;X~B_Rx~S<3|r^S84v13e8!eq2vP@>CYegat{^Zx9Zl{zfKOQJOhqz z_X?xeMa(55c>n+a diff --git a/Unity.Entities/SourceGenerators/SystemGenerator.dll b/Unity.Entities/SourceGenerators/SystemGenerator.dll index 7218ab76c470f64490ee9131438f0ee085b5267e..2ef96d7b4a2a50229f71eddb32e68e8bf630b9d1 100644 GIT binary patch delta 809 zcmXw%O=uHQ5Xa{wt)gtd2nfZGCT*ok?V8IEQdHr!o~+HN+GedP~L9|c=W9ecW`Cu<5J*bb&Z;Vfr0rm!sJxsvDEJWzNk z6uDC5N)eTx!Wv9~qpkuOoZCyR6+)bpGtXJ%T;r^8+HF>))1q5ww7Mj7S`SX8I0QSE}x-K;eAf^W3XWa z{|@vHbO|3p3NyLCHQQA?^7>jq4n4k?7&_^5c35ShL(1voxH%n5Q$^FSDwB$qGBZj- z&6s*xiK=u$y{Kmtno5Y1R-LFP&2e)aB|c5;+Z@JHlWD4l^`xFw%~U$0RE6tGY#NtJ zV4}5}QBv{C$|?Pdu4Z&4shb&7O=@adlSQ|}e)R8@H@3-=8{5Rw4!$4$b!*}Clk=B` zXR(Y$-`jsF_>g#0;yC0kp?`wq{Q1&Alxx{0&>1G4_PO^$L?sxMhQ*RfS#g5xYsn*{-Z zea{$y3ia~~O7uhXGD|9hi<0$I@=J>K0}_+76Vp?R^^@~+^-4ifdZ~FOnI)M(A+Sn4 zR~R=qzqBYh)jc&YwJ5P9zo=LrB2cFvTv=R_nhTfE&rizI7Y|C!Nlh$H)z3>UDK1IO zOGzwBG14>8pDgPxZ3K1OLYUit9nBfZgG zlM~4MugajnATU|br*AT!haKM^P&h!rAEwDs9`hJuCjazMX0+HW>v^7$*?@s<@_R4s b$$8$BCoA}ba3(-fSB>drL7(@G6Ajn_h0kqbd0YF6TCW-{vNM1QA&l82uMcjk*OAMq3CoAKT?qw2n zWlbSB`ioD7&o1u4jff!*cBUKWDRF(nLiBhFHjg%rzQ_EENHM0yW%Q#51 zu$kcKGR;pID@ntbn)9r!KC@}h<0a;^zA)yP;eFUzC5syoqfWIvo7|ZhLsp zci$gfYJL4gt{3axVB&$PCHft8(?+s%%Nn1rZmZ3-WRiR4S3M{w%gx?LYh*GHQvC7g z=yy8btD@XrAPjuR;`FB&y0!ocTVr#@{A(f-g?JW z=YBu)VMgs^pFWa_ZEkZ=(y(xbp@l;;r?pJpmRYpmNmYP_jb@P5>3{jq+FjD$iqjlg zq9+@R^p|Lx zbnr;+`JG8`YiOB2c3}3c*V4}ntb-fuaToFwUk;na_VQ+NdEOizi^F4bX9{G#T$vz& z%a%&L(Ib-x_?!gqnOvzMk`>@44j=iSH~P2y#(IO zRWDK;r-l@=PI@iqy%H-_#)qb=(eF4KQa^JUe9)~KMP`8O83-kp|+Te6)f zAG!#;`o0YG0g$%l_qO(iQ}aqXPI-~p;uI9(^4~jLn>?z)N(jRELs5maS;Bnf+Uw%P z)mA8mhHDt6j(hl?H$VfLDZ2#p{9+wkS?@AJsl?Uzeny+!p%JKaf;t-11wdUa)M=qk zhvzWco%A74FNAv8=WZR;uQeu5Z^SH-^J8M{sLgLi4di~vK_x$=8LNB{r; delta 1223 zcmZva4@?tx6vyB1+CmHTKp?Jyx)vyODU{x|cWsd|uw+CXq9M!yGp_Bml~^f(>SD~~ zPav6srrS-ov6!?t3J%Pyo%@qz2yrp{>w-&MMW>64n`6VcELlc$*d&Y;iaV?S}EK{gd!>ILHaxK zF@a>^Q5P2hUPs_bqDuYeh=VUUN(&9FIeL;DJb=NMRKlV@3NlF}7 zFqsm6TR`5>+7dWW-|mtM{y>NLK(Sw$RtiK$XRR%*sN3NcyHd=wa#^M81M$<8vX!NI zkxsR(D0NqfJ5qgI*0RR#m%9hLU+X@luCP_l7tXA%InaE(w%BRCW%&Hk%#{3e^Dh^( z4SVfpUJ~C*Q(OMq*&|msDef1}F-`PvZrg@{>*85W+2P}tdMiJw%iH?ywWsrio-A=Y zy^iM%#uAf(HL(n9VD*B<>R@=2lVdrLU@^HpP781Km_0_LjpJ-akIf;tO=jLEM(BeZ zEe4~3(_4*ZR^S;YW8ut3x7p_AOdM}>n=GtVU_A~8QXElM((dymj@VZO(yW2Zj z{H?$+F;{vfQGLCycP{Z=lV81keO@`X<-PZ#W6H+VhvLzUHL7P$cie>#fl|+nH>Vp@ zHc#YwH&k2u%3>24lR2s*=Pthvl>~mhcjfoo&ZOE={^}roYc^Rtp*N}ue_Z<=gzyir zYihr`@KoiI#&w2ktMpOvre32OaoxEJAqwPj$8^t`bCrXm>Cuo!h>LZ_IqLREzjkSN3{1$? zeKCq?xmM6aC`Mou1p__wr0IhcQcyt;3EIa?kQhPKQ=PfC-I@EF|2gMBckboh$xf2& zB)KtR?A~~_mcLd-p66#fN(avZ90zPsyp4HVg(VAM!PwXhaFW`%ee^V`BTIA)8KtwN zgG^JxRTK$(0SL_t^;(2`yOk_zwcG1TMgx2ZN+7_?(8ai^WjMm;SSH7+Igla6&pfoMVmgZ2XO@}HqP{X}&aq$$gB9}( z(+iAiWEV8@R&Ectd4Vy?m}Q(|oMW8lbSD@nepq14GEN)x{2bF@WL3s2!htr<$2IDTjCm0X- zya|^#;rAzEQY`2Wy1faH?03oav7j?1O8{*Ij?%UUm*#AE$W`J#<@>6Yf2(FvdB{QY~&!kwOHUqY`}z7q6>4v43cz3Om#S{CEVMR7=s zr__u%C}mV7Ek-1{U+PgZqMRCZ4Cy|Hl2m)uUQDsq9Ib`0JvEe;mBUI>NlR)foe?(^ zm&JnPkU1$03}3=gapINqX>AYl)J nn{_?!!ISMrj|}y!;zY{m0&Tfb;HFqn@YS$&Cw3$`VzC_3MBOkQ3+z_*D$Jrs)kJ)Wz1YIG= zwg(FzT&_ffq-GF8!NN#H_29=#Bm_Z4ZyLS^67*1S-MO|G?(hE3IsZFz5BD0g$e2Yl zQ})i5t>@Y4GW0OJ++9@H2XGn4hyl3m*+8k=AcDl-ZvaGbfT_Ygr~=L4NkTVXM%`!t zBc{~hJq3X9XW@()VZQ7~kIfUlioyvG+YE)^VI}CL+|v>qXEQXDq16mX(8eyoAPf^~ z#JNGM+b|CAoI6wl8i#!@8?wIRC;GlCNVP!pM^`h|F{0fC64eILv5A5V4HihSQm{nz z2IUWQ7`&{XDF>DnC}WfcYvC%);UQsDHPmbb4;f}gsV=MnMo$&}7t zQxf`Emn!k`q^|K1Q5qC)%Nj2whq)1}#L0@D&=Vv@om^`^>`IQPl6+BCWL4CYs>bgn z?(%s@lOhg{rDfIHh=14n@a6@!j8FCt@K@y_S=3}+k#$WMmAI(JYq$_kIyz*T8n{%v zAG+F`YHI5sfAIAGgOg@QKRoMsaz1tBQglvB_mLL!W7N|AY~TQSbdQ8eb6w~_cw0D& zi^2^>Ia}Takh9_I;isq={|yJ3pNx5|`5t2nffFyaR+{B)Th^{98`*o>(+y@x`!33c GT>k+4LCz-t diff --git a/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.CodeFixes.pdb b/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.CodeFixes.pdb index 7bd4e6210d5289b5edc0e8b632600226530eef2b..df4f0311d6d7406c982dbfa284b75124ece1b41b 100644 GIT binary patch delta 1371 zcmZvcc~Fx_7{+(Mgajp(K&evD7)tnp#)MpuL{O24f*Oy8(|8bakZ1%65v4dJ-iQ>B zPzO_~&_qi|DqtvLN9sYx3*(8c5ih6q4t5daJ?07@ZZxyh){&dLL5)RO=}Z4jC)2aSl=jPRV~#91gAWB}eU(LBzO zlZocVkrdrwhbz{W_0vP?wa(r>D}(p!+9C8utp)(WS%3i!gdiSbK!QQA2*Xh4!vVqU zPzV|r*2OT?ngPA$L(t5C;1tq1Bo|UUk{ijx7+DH|DC}Ksf1l^xrwV^pZ+V}Kn9kGi zGKTG7Sj&i$%|zfPFo757_euc-poRI!bFprW1OmglF*3lz=mZkbAt!_Uunfe_$Va#e zu@J999EW!!{suW2)Z%m^3GkS7A{oqJW+3iCP6qwxfPhrah?y>4vBHp}QX2BOK&^MO zyec6zIJIO9uFsy`_(MtkY`=kF>jlzG8YZ3Uot&*V708V$f?AUg*Amq^raaPWWu8f6 zv<8#+`caoc;zxcT2Tlx+o~uxqEc>h{$p-V-|5SS{zgzk&!*on0KUQMv(iR&nx9&$|+7xPg!)7+e^K|9G zkP64%li_a*?P+KF*IYeOFos3BJMY+o-QRECP>G*mv8rh?Rz>=-U3@M1=GNq#9%EeJ z#l|nfV|#y&Ulw2=JB20nBwU#zq7{=W8C}uB7mqtvw?0k^uE6)#(#rnGRXtkr@OzZiLIsv-IKgwkbTe*~$g&pR4@kT0pGcTO(;6aaN%U}$B zOm?qn-wk3IXHn5K{mh%xi5*JDcef+@?nLC;vZt&aDAbSMZcf|j4!^i}PPM1Tr|D1a zC0Ne#Ud}yD0R;qa&w<1xe^93H|CT-J7fM2*+!<0+54WzRXB;{3%0V>RJc4LnozHru zDwA01gVkmk_=kL-TzH_zyAsbThor8yro;D+5ZwMpzosWm*f0%Gb;u0cD!<%c)CZ+i zlSQuKb+LT&@MYQ3fh|p+?p%LmRrRf}6m2&c%#^f>IDV7PCVF;}kzaJFE+FMs+Bp2U zt!?U%pFPh%Rqah+FE9n&ds4PxaIPRB%H1M%ow#)+by=jY=)U5&*4n_*CTC_&Rt;G? zE$Gqs=LVKLsCRW_P)%oy`|>9oPT`|vi&?KH?#fA{FyHzP+$&pmYS>VOxnDOoPd|Dm zU`=0o&CM5SDQd6s9k$$*p_X-<0<0IjCy04m4wo(9@Pz`Nki!$Q_>mHgn6Hs&`CPSH zfIf{%62;RBBKc~yN-N1!@g-alU!$}Jk1Aw~Ib4p2#aAlTny5@oCKuHOQ6jBcB2o#t zBCb-%lZeG!zE%^(Q*oWGqi`75(YT~~4Oqf7U2j;O!uAeu0%;oX*IZ3gW8`u9rS1XXFHW<*#_7KG-&<%h%IQ2H(BTlGD!0XK|t~<_% u@OX&ZWze1k?W>@@4BG3Uy&c;7p@Rq=u1H_2$9= delta 767 zcmZvZZ%9*N6voflpF3q}Wm>~5=C0FndcC{bz1tw9auS*nVJbEdo!e4T7rID^(xML~ zW#&ahq1qjWiYVwbN+b#+h{_KGrL1t71{GNmL_$dK&@V*?p6B_Ub2uMfUVr&=S*O{- zDgfy702(F0RU};GYpiKF*#xBeDFCtty0{1i30Fk;aB-fUWRwcvjh^&}>by?U&-m$2`PTUbV`_TD{%_0rDzpOh|_Bo6lnDo zgdY>9AfylKl;bEaQwQVZ-c!D);)WVuOHpH$!sYcfi8-pSEwNdE%Gm8mS=mQRtJ~Ve z52`vL{;%0w+pD&BZQr!nHv3xY!j8i&j_$$?r*)Be`eflz)R5!jOgvMcGjdKeM03{v zoL(r=ol8U>S+=Xj6HVsd+&7QyN$RBSBNKPWhGWXq zzk~Z@!bzI;@!1|Yfbe-W^nF(=RX8Zj_r)%LQi&PSnmw+%I&zudESrEZz-a%9^L?x? zx5M%5$MW0Mo?vZyE~ZKhN<2yhD0xxpL}?PG5K1d3{lb6(0|^+&z(9U*&X6zv1C&qD A*#H0l diff --git a/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.dll b/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.dll index dcc0416edb58f762f2e7cea8ddcc35db19be68f8..656ce62415c6162949803155b1618e11b13020d2 100644 GIT binary patch delta 685 zcmXw1O=uHA6n?X@G-?b=lwupvSc#a(cJsH%7F0?UD^wa2wG{WV*_~};lTFNS#0uIN zp%hHPFeqNEg@T}X5VkiF1F085@Zg~qZ$T(h5f2`eg3fN6H@uJczW2>AZ{}4uP;~=6 zoZIo)ckM%??qz!C8!xZA-`4>~f!ZR#rlaBWxS9YinwK5`TqZu|BpFA?nIi>KLw>YL zUZ64bhakq&l}`g8@=J@GDQ5pcv~J=)?7mQUE`bbByO&^>jZSP_+? zp^F7cH*i@@N%E95fpt+X7TAiVW3guBj2xxxZS1*DnkiPwGCq$rT$YStSr@m6yJAN% zhil2 zk8A%f4gH{fb*y`yENZ><3*Tr#@=g0q+@;fd79E{3odYsndd7f*{4E_tU(G`|4l|A# z43IN=FcSn7q9A|*A>bimM+t~gPNj^6JY6beL82}|*mjGL(4pX|Muxau;V8;f1th1R S-C5llIqxZRpYanlxbFWg|I#!7 delta 589 zcmZp8!`SeKaY6@+Xj0^si9Iq*&w3`V3ges9!@%Ir00avd7*;S(R21epz`(!*4W9rGC&eFK<)jz15?bATS0lM7@(0V9wW24Zy}&IbBAd-Bp;<@yb0H+31Rtn`_< zrmJwLL7OQ^m41FfiGFBaW=UmmQL=tYeo3)@Kw@%sVtQ(^esX@UUMWaQFEy_uvm_HJ z1Xii%3gZUnmlh?bx~Jx)7A2PC7ZvM61nTr*Djf3?b1JJ+i$EGD2jz*#=;tS8=?A6e zq$U=p>gT1F6qh9Cr6d-m80i`4Pxj9fpFA^<#|Y}s96_i qV(i!~TPV-OY{0-a*}hnN^1fo{$-4O=oDGm9@xlgZ#Cyhx2J8Ss8Mp`l diff --git a/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.pdb b/Unity.Entities/SourceGenerators/Unity.Entities.Analyzer.pdb index cb9a881c39d277534c40d08886f11e9859568d55..0db901fe0000b329013e0a7c273ec40234fd4a91 100644 GIT binary patch delta 1905 zcmZvd2~bm46o&782@o|25o8gRMIecZNwWa~v=tErS+ueh(JCYX!zzfjs5L;eDuWh% zv|>9V7(sED&|1M!6gLJ?7I(x^svTKWa7C%ulel!0&b;sa=ltirbML!%a&tYYWJ!T+ zezO@uE~^o$q9KGR5Qk-Es8bV`LWZhFAw&gri3me~LcGWj&x{D14r)tBh&BoGX~}7E zkayGPx{DTj1n1CezyDdmbS+P)eXzM;O^gZDN)bkth(NudZ$JeYqc1UmGC;MUHK2{4 z1c8wyL7)K8XwY9kcY|IB?E;OUV3bTDP$U(j6e>ZcV@nN!o^%(C#<*g{1EPVoKn)P) z27^Q0j!hsrPz1CB-*O0)$T8F?D4jz^*MK(wm22=!P%GCIJp&>qnxX~3QeeYGL(LTZ z4e?80GS3VJ@MsHBDvyTN1I0YU10zrkZv^TFYWRj6qtixx7q`9l+W8oD0$m?#1nT=3 z!vMzE6bWr!bd533=em+DtjuJZ%e%`c*RCQ)n zScZb4R4vELsLHg=rKTydOEXm&q&YozG;2PlGDch4I&ytx#V9hf^T`sr_b|7O?4pZ4 zcXJ#_E<-lVT}UP|`Z4M1+J@=KXp*etkyvm0MnU4)&}%8^P14ukbm|O~J|ppX?pYu)Y!bM@F6& zjq!gu?d{!`K;OCP`y*MGk7xzL&c4JQ&PBVn9Ou4Ssr%+s|B_3`vY34Ot)R+#1r^#= z+u5i1{8ER>+ZVC7?O7huwAd%Jqc^7Tr?o{1(t%eo_aED><4q{+Q!mQD^Dy+1`Uyd* z&AI>od257Dj8j6#$pZ&O$JyN&T>PD+ z{!IE{$<^dDVom;GW&6eY0>AR!#E1J+j)Xg`X`)3wh$WHQgqD0@Q}^YN*UAlSj^l*d z=YbV6-yAF2q$xR))7~?4oy*)#@Ow~*DZgx4U-loxzV(caTc4GU57^|@JK8RdoL&3opXzXLZNly%cI>!v=F?odw%J!2?5FP^fhoCGWP|y5 zxmY9=38X@aOe&TM#WKFc-Ag5xsJ!AOBBfFamrCK~A&!^2OO#4QyjPq;;wAEwsA5S6 z)+&KqC=z<|C9$zel}DT^P6WQx!!us#<*AT~JVmiGv6oyflEkY##0ruAJd2HOZ&uAK zHJm`Nr)SPqA9C{BEIcX*zTFT*`dZkKKM2h9E*3lOY+qa-96(bsdfswAqf=Ape>g3C zYIbYOBeG*szm3ik>v&iff^|t)w;t;XvF;ewwd?N-Qiu=5BwQY9D3-?>>+O2AXbR@) zEUnU)Dr*OqcJx6Md o$L*aBr!Ahsh_oncBZWaLYXlLs z1+~MgtvA947+*l$a9Rlq8xhO?5jeqK~?Md1HQG$yS3BQ>c$CQ9a6hi7s`vr zm}b3TfGY-;uyCHuPnta}ohuP+?7-fHxwF4FvA<*AuA=BbVu-4iWGNQ_V&Lr6fsGG7 z^5nsT^h?Wz0&j}0w(={z=Qz5}8Z7YI=_}SyftRAcSd{|rJKDg>E4^ej9pst{yl#4y z6AHWuN=o;r<^Mf%az6QI@~`JjwHw2mZ+R|OwC?X3ZEuW(X8q^BxcG_rWY^Wt%Kd$t zPCw(NFIp<;j!s-#+u!DeI#p3-okgZGLz8>s5}C$*+z>3xVJNn7OfL*w~&`zI~aS{mn#O zfg6?SIg(x^nL3hbA(`zY(@QchkxVY%$oDaKiY;W!sTIc*y`IbG#3sU|=je6G!QI{f zyR|;LI(XBdZ$d5dma2b?%iY>4a$+{$FISN2toA>UChInvHXm0njnGb%qiJR9iWA%! KuXQtO4fzLWcQ public bool HasNoBlobReferences; + /// + /// Configures the TypeManager to set the component type's to zero. + /// + /// + /// You can use this to bypass the TypeManager check and force the component type's reference to zero. + /// Set to `false` to set the component type's to zero. Set to `true` to set the value to zero only when the component has a Unity object reference. + /// + public bool HasNoUnityObjectReferences; + + // Use this to bypass the TypeManager check which complains if you say no references but it actually has them + internal bool AllowForceNoReferences; /// /// /// /// Set to true to ignore entity references in type. /// Set to true to ignore blob asset references in type. - public TypeOverridesAttribute(bool hasNoEntityReferences, bool hasNoBlobReferences) + /// Set to true to ignore unity object references in type. + public TypeOverridesAttribute(bool hasNoEntityReferences, bool hasNoBlobReferences, bool hasNoUnityObjectReferences = false) { HasNoEntityReferences = hasNoEntityReferences; HasNoBlobReferences = hasNoBlobReferences; + HasNoUnityObjectReferences = hasNoUnityObjectReferences; + AllowForceNoReferences = false; + } + + internal TypeOverridesAttribute(bool hasNoEntityReferences, bool hasNoBlobReferences, bool hasNoUnityObjectReferences, bool allowForcedNoReferences) + { + HasNoEntityReferences = hasNoEntityReferences; + HasNoBlobReferences = hasNoBlobReferences; + HasNoUnityObjectReferences = hasNoUnityObjectReferences; + AllowForceNoReferences = allowForcedNoReferences; } } @@ -810,7 +832,7 @@ public TypeInfo(int typeIndex, TypeCategory category, int entityOffsetCount, int int alignmentInBytes, int maximumChunkCapacity, int writeGroupCount, int writeGroupStartIndex, bool hasBlobRefs, int blobAssetRefOffsetCount, int blobAssetRefOffsetStartIndex, int weakAssetRefOffsetCount, int weakAssetRefOffsetStartIndex, - int unityObjectRefOffsetCount, int unityObjectRefOffsetStartIndex, int typeSize, ulong bloomFilterMask = 0L) + bool hasUnityObjectRefs, int unityObjectRefOffsetCount, int unityObjectRefOffsetStartIndex, int typeSize, ulong bloomFilterMask = 0L) { TypeIndex = new TypeIndex() { Value = typeIndex }; Category = category; @@ -827,6 +849,7 @@ public TypeInfo(int typeIndex, TypeCategory category, int entityOffsetCount, int WriteGroupCount = writeGroupCount; WriteGroupStartIndex = writeGroupStartIndex; _HasBlobAssetRefs = hasBlobRefs ? 1 : 0; + _HasUnityObjectRefs = hasUnityObjectRefs ? 1 : 0; BlobAssetRefOffsetCount = blobAssetRefOffsetCount; BlobAssetRefOffsetStartIndex = blobAssetRefOffsetStartIndex; WeakAssetRefOffsetCount = weakAssetRefOffsetCount; @@ -903,6 +926,7 @@ public TypeInfo(int typeIndex, TypeCategory category, int entityOffsetCount, int internal readonly int EntityOffsetStartIndex; private readonly int _HasBlobAssetRefs; + private readonly int _HasUnityObjectRefs; /// /// Number of s this component can store. @@ -975,22 +999,26 @@ public int AlignmentInChunkInBytes public bool HasWriteGroups => WriteGroupCount > 0; /// - /// For struct IComponentData, a value of true gurantees that there are fields in this component. + /// For struct IComponentData, a value of true guarantees that there are fields in this component. /// For class based IComponentData, a value of true means it is possible, but not guaranteed, that there are blob asset references. (Polymorphic members can not be proven statically) /// public bool HasBlobAssetRefs => _HasBlobAssetRefs != 0; /// - /// For struct IComponentData, a value of true gurantees that there are fields in this component. + /// For struct IComponentData, a value of true guarantees that there are fields in this component. /// For class based IComponentData, a value of true means it is possible, but not guaranteed, that there are WeakReferences. (Polymorphic members can not be proven statically) /// public bool HasWeakAssetRefs => WeakAssetRefOffsetCount != 0; /// - /// For struct IComponentData, a value of true gurantees that there are fields in this component. - /// For class based IComponentData, a value of true means it is possible, but not guaranteed, that there are WeakReferences. (Polymorphic members can not be proven statically) + /// Returns whether there are any UnityObjectRefs fields in this component. /// - public bool HasUnityObjectRefs => UnityObjectRefOffsetCount != 0; + /// + /// For struct IComponentData a value of `true` means that there are UnityObjectRefs fields in this component. + /// For class based IComponentData, a value of `true` means that there might be UnityObjectRefs fields in this component. This is because polymorphic members can't be proven statically. + /// A value of `false` means there are no UnityObjectRefs fields in this component. + /// + public bool HasUnityObjectRefs => _HasUnityObjectRefs != 0; /// /// Returns the System.Type for the component this is describing. @@ -1590,7 +1618,7 @@ static void RegisterSpecialComponents() new TypeInfo(0, TypeCategory.ComponentData, 0, -1, 0L, 0L, -1, 0, 0, 0, TypeManager.MaximumChunkCapacity, 0, -1, false, 0, - -1, 0, -1, 0, -1, 0, 0L), + -1, 0, -1, false, 0, -1, 0, 0L), "null", 0); // Push Entity TypeInfo @@ -1610,7 +1638,7 @@ static void RegisterSpecialComponents() 0, entityStableTypeHash, -1, UnsafeUtility.SizeOf(), UnsafeUtility.SizeOf(), CalculateAlignmentInChunk(sizeof(Entity)), TypeManager.MaximumChunkCapacity, 0, -1, false, 0, - -1, 0, -1, 0, -1, UnsafeUtility.SizeOf(), + -1, 0, -1, false, 0, -1, UnsafeUtility.SizeOf(), bloomFilterMask:0L), "Unity.Entities.Entity", 0); @@ -2876,14 +2904,14 @@ internal static void CheckIsAllowedAsComponentData(Type type, string baseTypeDes #endif } - internal static void CheckTypeOverrideAndUpdateHasReferences(Type type, Dictionary cache, ref bool hasEntityReferences, ref bool hasBlobReferences) + internal static void CheckTypeOverrideAndUpdateHasReferences(Type type, Dictionary cache, ref bool hasEntityReferences, ref bool hasBlobReferences, ref bool hasUnityObjectReferences) { // Components can opt out of certain patching operations as an optimization since with managed components we can't statically // know if there are certainly entity or blob references. Check here to ensure the type overrides were done correctly. var typeOverride = type.GetCustomAttribute(true); if (typeOverride != null) { - EntityRemapUtility.HasEntityReferencesManaged(type, out var actuallyHasEntityRefs, out var actuallyHasBlobRefs, cache, 128); + EntityRemapUtility.HasEntityReferencesManaged(type, out var actuallyHasEntityRefs, out var actuallyHasBlobRefs, out var actuallyHasUnityObjectRefs, cache, 128); if (typeOverride.HasNoEntityReferences && actuallyHasEntityRefs == EntityRemapUtility.HasRefResult.HasRef) { throw new ArgumentException( @@ -2899,12 +2927,22 @@ internal static void CheckTypeOverrideAndUpdateHasReferences(Type type, Dictiona $"BlobAssetReferences, however the type does in fact contain a (potentially nested) BlobAssetReference. " + $"This is not allowed. Please refer to the documentation for {nameof(TypeOverridesAttribute)} for how to use this attribute."); } + + if (typeOverride.HasNoUnityObjectReferences && !typeOverride.AllowForceNoReferences && actuallyHasUnityObjectRefs == EntityRemapUtility.HasRefResult.HasRef) + { + throw new ArgumentException( + $"Component type '{type}' has a {nameof(TypeOverridesAttribute)} marking the component as not having " + + $"UnityObjectRef, however the type does in fact contain a (potentially nested) UnityObjectRef. " + + $"This is not allowed. Please refer to the documentation for {nameof(TypeOverridesAttribute)} for how to use this attribute."); + } } if (typeOverride != null && typeOverride.HasNoEntityReferences) hasEntityReferences = false; if (typeOverride != null && typeOverride.HasNoBlobReferences) hasBlobReferences = false; + if (typeOverride != null && typeOverride.HasNoUnityObjectReferences) + hasUnityObjectReferences = false; } #if !UNITY_DISABLE_MANAGED_COMPONENTS @@ -3126,6 +3164,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, bool hasEntityReferences = false; bool hasBlobReferences = false; bool hasWeakAssetReferences = false; + bool hasUnityObjectRefs = false; if (typeof(IComponentData).IsAssignableFrom(type) && !isManaged) { @@ -3141,7 +3180,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, else sizeInChunk = valueTypeSize; - EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); + EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, out hasUnityObjectRefs, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); } #if !UNITY_DISABLE_MANAGED_COMPONENTS else if (typeof(IComponentData).IsAssignableFrom(type) && isManaged) @@ -3150,10 +3189,11 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, category = TypeCategory.ComponentData; sizeInChunk = sizeof(int); - EntityRemapUtility.HasEntityReferencesManaged(type, out var entityRefResult, out var blobRefResult, caches.HasEntityOrBlobAssetReferenceCache); + EntityRemapUtility.HasEntityReferencesManaged(type, out var entityRefResult, out var blobRefResult, out var unityObjRefResult, caches.HasEntityOrBlobAssetReferenceCache); hasEntityReferences = entityRefResult > 0; hasBlobReferences = blobRefResult > 0; + hasUnityObjectRefs = unityObjRefResult > 0; } #endif else if (typeof(IBufferElementData).IsAssignableFrom(type)) @@ -3168,11 +3208,6 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, elementSize = valueTypeSize; - // Empty types will always be 1 bytes in size as per language requirements - // Check for size 1 first so we don't lookup type fields for all buffer types as it's uncommon - if (elementSize == 1 && type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Length == 0) - throw new ArgumentException($"Type {type} is an IBufferElementData type, however it has no fields and is thus invalid; this will waste chunk space for no benefit. If you want an empty component, consider using IComponentData instead."); - var capacityAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute)); if (capacityAttribute != null) bufferCapacity = capacityAttribute.Capacity; @@ -3180,7 +3215,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, bufferCapacity = DefaultBufferCapacityNumerator / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic sizeInChunk = sizeof(BufferHeader) + bufferCapacity * elementSize; - EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); + EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, out hasUnityObjectRefs, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { @@ -3191,25 +3226,21 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, #endif valueTypeSize = UnsafeUtility.SizeOf(type); - // Empty types will always be 1 bytes in size as per language requirements - // Check for size 1 first so we don't lookup type fields for all buffer types as it's uncommon - if (valueTypeSize == 1 && type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Length == 0) - throw new ArgumentException($"Type {type} is an ISharedComponentData type, however it has no fields and is thus invalid; this will waste chunk space for no benefit. If you want an empty component, consider using IComponentData instead."); - category = TypeCategory.ISharedComponentData; isManaged = !UnsafeUtility.IsUnmanaged(type); if (isManaged) { - EntityRemapUtility.HasEntityReferencesManaged(type, out var entityRefResult, out var blobRefResult, caches.HasEntityOrBlobAssetReferenceCache); + EntityRemapUtility.HasEntityReferencesManaged(type, out var entityRefResult, out var blobRefResult, out var unityObjectRefResult, caches.HasEntityOrBlobAssetReferenceCache); // Managed shared components explicitly do not allow patching of entity references hasEntityReferences = false; hasBlobReferences = blobRefResult > 0; + hasUnityObjectRefs = unityObjectRefResult > 0; } else { - EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); + EntityRemapUtility.CalculateFieldOffsetsUnmanaged(type, out hasEntityReferences, out hasBlobReferences, out hasWeakAssetReferences, out hasUnityObjectRefs, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, ref s_WeakAssetRefOffsetList, ref s_UnityObjectRefOffsetList, caches.CalculateFieldOffsetsUnmanagedCache); } } else if (type.IsClass) @@ -3219,6 +3250,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, alignmentInBytes = sizeof(int); hasEntityReferences = false; hasBlobReferences = false; + hasUnityObjectRefs = false; #if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG if (UnityEngineObjectType == null) @@ -3234,7 +3266,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, } // If the type explicitly overrides entity/blob reference attributes account for that now - CheckTypeOverrideAndUpdateHasReferences(type, caches.HasEntityOrBlobAssetReferenceCache, ref hasEntityReferences, ref hasBlobReferences); + CheckTypeOverrideAndUpdateHasReferences(type, caches.HasEntityOrBlobAssetReferenceCache, ref hasEntityReferences, ref hasBlobReferences, ref hasUnityObjectRefs); AddFastEqualityInfo(type, category == TypeCategory.UnityEngineObject, caches.FastEqualityLayoutInfoCache); @@ -3319,7 +3351,7 @@ internal static TypeInfo BuildComponentType(Type type, TypeIndex[] writeGroups, elementSize > 0 ? elementSize : sizeInChunk, alignmentInBytes, maxChunkCapacity, writeGroupCount, writeGroupIndex, hasBlobReferences, blobAssetRefOffsetCount, blobAssetRefOffsetIndex, - weakAssetRefOffsetCount, weakAssetRefOffsetIndex, unityObjectRefOffsetCount, + weakAssetRefOffsetCount, weakAssetRefOffsetIndex, hasUnityObjectRefs, unityObjectRefOffsetCount, unityObjectRefOffsetIndex, valueTypeSize, bloomFilterMask); } diff --git a/Unity.Entities/Unity.Entities.asmdef b/Unity.Entities/Unity.Entities.asmdef index 1186ca37..4dc15bcc 100644 --- a/Unity.Entities/Unity.Entities.asmdef +++ b/Unity.Entities/Unity.Entities.asmdef @@ -33,7 +33,17 @@ "name": "Unity", "expression": "2022.3.11f1", "define": "UNITY_2022_3_11F1_OR_NEWER" + }, + { + "name": "Unity", + "expression": "2022.3.43f1", + "define": "UNITY_2022_3_43F1_OR_NEWER" + }, + { + "name": "Unity", + "expression": "6000.0.16f1", + "define": "UNITY_6000_0_16F1_OR_NEWER" } ], "noEngineReferences": false -} +} \ No newline at end of file diff --git a/ValidationExceptions.json b/ValidationExceptions.json index 425d80ce..0125603d 100644 --- a/ValidationExceptions.json +++ b/ValidationExceptions.json @@ -3,7 +3,22 @@ { "ValidationTest": "API Validation", "ExceptionMessage": "Breaking changes require a new major version.", - "PackageVersion": "1.3.0-pre.4" + "PackageVersion": "1.3.2" + }, + { + "ValidationTest": "API Validation", + "ExceptionMessage": "Additions require a new minor or major version.", + "PackageVersion": "1.3.2" + }, + { + "ValidationTest": "API Validation", + "ExceptionMessage": "New assembly \"Unity.Entities.TestComponents\" may only be added in a new minor or major version.", + "PackageVersion": "1.3.2" + }, + { + "ValidationTest": "API Validation", + "ExceptionMessage": "New assembly \"Unity.Scenes.PerformanceTests\" may only be added in a new minor or major version.", + "PackageVersion": "1.3.2" } ], "WarningExceptions": [] diff --git a/package.json b/package.json index ca0e3e52..03f5f8d3 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "com.unity.entities", "displayName": "Entities", - "version": "1.3.0-pre.4", + "version": "1.3.2", "unity": "2022.3", "unityRelease": "11f1", "dependencies": { - "com.unity.burst": "1.8.16", + "com.unity.burst": "1.8.17", "com.unity.serialization": "3.1.1", - "com.unity.collections": "2.5.0-pre.2", + "com.unity.collections": "2.5.1", "com.unity.mathematics": "1.3.1", "com.unity.modules.assetbundle": "1.0.0", "com.unity.modules.audio": "1.0.0", @@ -16,7 +16,9 @@ "com.unity.test-framework.performance": "3.0.3", "com.unity.nuget.mono-cecil": "1.11.4", "com.unity.scriptablebuildpipeline": "1.21.21", - "com.unity.profiling.core": "1.0.2" + "com.unity.profiling.core": "1.0.2", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.uielements": "1.0.0" }, "description": "The Entities package provides a modern Entity Component System (ECS) implementation with a basic set of systems and components made for Unity.", "keywords": [ @@ -25,15 +27,15 @@ "unity" ], "_upm": { - "changelog": "### Changed\n\n* Updated Burst dependency to version 1.8.16\n\n### Deprecated\n\n* The `ENABLE_SIMPLE_SYSTEM_DEPENDENCIES` feature will be removed in a future package release, as it no longer provides significant benefit for expected DOTS workloads.\n* The `EntityQueryCaptureMode.AtRecord` enum value in `EntityCommandBuffer` is now deprecated. All users should migrate to `EntityQueryCaptureMode.AtPlayback`. Capture-at-record mode can be several hundred times slower than capture-at-playback. If capture-at-record semantics are required and performance isn't a concern, the array of entities matching the query can be captured manually and passed to the corresponding `EntityCommandBuffer` command.\n\n### Fixed\n\n* Usage of SystemAPI.GetComponentRW and SystemAPI.GetComponentRO in Entities.ForEach.\n* Regression in compilation time with assemblies with lots of system methods.\n* EntityComponentStore leaked memory during domain reload." + "changelog": "### Added\n\n* Overloads for `ComponentLookup.HasComponent`, `ComponentLookup.TryGetComponent`, `BufferLookup.HasBuffer`, and `BufferLookup.TryGetBuffer` adding parameter `out bool entityExists`, as well as dedicated `ComponentLookup.EntityExists` and `BufferLookup.EntityExists` APIs, to allow user-code to distinguish entity non-existence from component non-existence without additional boilerplate, inside jobs.\n* adding missing dependencies `com.unity.modules.physics`, `com.unity.modules.uielements`.\n\n### Changed\n\n* Updated Burst dependency to version 1.8.17\n* Add API docs discouraging the use of the `ExclusiveEntityTransaction.EntityManager` property. Many EntityManager operations are not safe to use within the context of an ExclusiveEntityTransaction; only the methods directly exposed by `ExclusiveEntityTransaction` are guaranteed to work correctly.\n* Add API docs discouraging the creation of `EntityQuery` objects with multiple query descriptions. This feature works in narrow contexts, but is known to cause errors and incompatibilities with other DOTS features.\n* Add API docs to note that enabling and disabling components inside `IJobEntityChunkBeginEnd.OnChunkBegin()` does not affect the entities iterated in the current chunk, as its `chunkEnabledMask` has already been computed.\n* Zero-size `IBufferElementData` and `ISharedComponentData` structs no longer cause the TypeManager to throw during initialization. Zero-size buffer and shared components are usually a sign of pointless waste (especially buffer components, which have a significant chunk-memory cost even if the actual elements are empty), but they shouldn't cause a fatal error.\n\n### Fixed\n\n* Various SGICE002 errors that happen if you type invalid C# code\n* Various SGICE003 errors that happen if you type invalid C# code\n* NullReferenceException on UnityObjectRef after Asset Garbage Collection (This fix requires editor versions 2022.3.43f1 and 6000.0.16f1 and beyond)" }, "upmCi": { - "footprint": "ad441cc1d5a05669016d42fc54556c8672e3000d" + "footprint": "5ee7373e0991ffdf47a7a47d2d5ea184ea08d0df" }, "documentationUrl": "https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html", "repository": { "url": "https://github.cds.internal.unity3d.com/unity/dots.git", "type": "git", - "revision": "6b0c8d27a0224c9cf76032c48d1b981e9750f10d" + "revision": "921920e681054c59b440cc1e2aef10f781dc4124" } }