diff --git a/README.md b/README.md index 1f71b2c6..ae340b38 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,15 @@ The code is reasonably clean but documentation and examples are sparse. Feel fre ⚠️ We welcome PRs and bug reports but making this repo a public success is not our priority. No promises on when it will be addressed! # Dependencies -- [Unity 2021.3.5+](https://unity.com/) +- [Unity 2022.3.15+](https://unity.com/) - [anvil-csharp-core (main...usually 😬)](https://github.com/decline-cookies/anvil-csharp-core) - [anvil-unity-core (main...usually 😬)](https://github.com/decline-cookies/anvil-unity-core) - *DOTS Packages* - - [com.unity.entities (0.50.1-preview2)](https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/index.html) - - [com.unity.rendering.hybrid (0.50.0-preview.44)](https://docs.unity3d.com/Packages/com.unity.rendering.hybrid@0.50/manual/index.html) - - [com.unity.burst (1.6.4)](https://docs.unity3d.com/Packages/com.unity.burst@1.6/manual/index.html) - - [com.unity.collections (1.2.3)](https://docs.unity3d.com/Packages/com.unity.collections@1.2/manual/index.html) - - [com.unity.jobs (0.50.0-preview.9)](https://docs.unity3d.com/Packages/com.unity.jobs@0.50/manual/index.html) - - [com.unity.mathematics (1.2.5)](https://docs.unity3d.com/Packages/com.unity.mathematics@1.2/manual/index.html) + - [com.unity.entities (1.0.16)](https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/index.html) + - [com.unity.entities.graphics (1.0.16)](https://docs.unity3d.com/Packages/com.unity.entities.graphics@1.0/manual/index.html) + - [com.unity.burst (1.8.11)](https://docs.unity3d.com/Packages/com.unity.burst@1.8/manual/index.html) + - [com.unity.collections (2.1.4)](https://docs.unity3d.com/Packages/com.unity.collections@2.1/manual/index.html) + - [com.unity.mathematics (1.2.6)](https://docs.unity3d.com/Packages/com.unity.mathematics@1.2/manual/index.html) At this point in time, all DOTS related functionality is in this one repository. In the future, we may split the functionality into specialized repositories. Maintaining a repository per Unity DOTS package seems overly tedious at the moment. diff --git a/Scripts/AssemblyInjections/Unity.Collections/FixedListInternalExtension.cs b/Scripts/AssemblyInjections/Unity.Collections/FixedListInternalExtension.cs index 549b3004..1a529872 100644 --- a/Scripts/AssemblyInjections/Unity.Collections/FixedListInternalExtension.cs +++ b/Scripts/AssemblyInjections/Unity.Collections/FixedListInternalExtension.cs @@ -12,7 +12,6 @@ namespace Anvil.Unity.Collections /// A collection of extension methods for (and friends) that require internal /// access to function. /// - [BurstCompatible] public static unsafe class FixedListInternalExtension { /// @@ -153,7 +152,6 @@ public static int IndexOf(this in FixedList4096Bytes /// /// /// This is a copy of that supports elements /// - [BurstCompatible(GenericTypeArguments = new[] { typeof(int), typeof(int) })] public static bool Contains(this in FixedList32Bytes list, TUnderlying value) where TEnum : unmanaged, Enum where TUnderlying : unmanaged, IEquatable @@ -174,7 +172,6 @@ public static bool Contains(this in FixedList32Bytes /// /// /// This is a copy of that supports elements /// - [BurstCompatible(GenericTypeArguments = new[] { typeof(int), typeof(int) })] public static bool Contains(this in FixedList64Bytes list, TUnderlying value) where TEnum : unmanaged, Enum where TUnderlying : unmanaged, IEquatable @@ -195,7 +192,6 @@ public static bool Contains(this in FixedList64Bytes /// /// /// This is a copy of that supports elements /// - [BurstCompatible(GenericTypeArguments = new[] { typeof(int), typeof(int) })] public static bool Contains(this in FixedList128Bytes list, TUnderlying value) where TEnum : unmanaged, Enum where TUnderlying : unmanaged, IEquatable @@ -216,7 +212,6 @@ public static bool Contains(this in FixedList128Bytes /// /// /// This is a copy of that supports elements /// - [BurstCompatible(GenericTypeArguments = new[] { typeof(int), typeof(int) })] public static bool Contains(this in FixedList512Bytes list, TUnderlying value) where TEnum : unmanaged, Enum where TUnderlying : unmanaged, IEquatable @@ -237,7 +232,6 @@ public static bool Contains(this in FixedList512Bytes /// /// /// This is a copy of that supports elements /// - [BurstCompatible(GenericTypeArguments = new[] { typeof(int), typeof(int) })] public static bool Contains(this in FixedList4096Bytes list, TUnderlying value) where TEnum : unmanaged, Enum where TUnderlying : unmanaged, IEquatable diff --git a/Scripts/AssemblyInjections/Unity.Collections/NativeParallelHashMapInternalExtension.cs b/Scripts/AssemblyInjections/Unity.Collections/NativeParallelHashMapInternalExtension.cs index 5148b317..a792466b 100644 --- a/Scripts/AssemblyInjections/Unity.Collections/NativeParallelHashMapInternalExtension.cs +++ b/Scripts/AssemblyInjections/Unity.Collections/NativeParallelHashMapInternalExtension.cs @@ -19,8 +19,8 @@ public static class NativeParallelHashMapInternalExtension /// The value type. /// The . public static Allocator GetAllocator(this NativeParallelHashMap map) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { return map.m_HashMapData.GetAllocator(); } @@ -34,8 +34,8 @@ public static Allocator GetAllocator(this NativeParallelHashMapThe key type. /// The value type. public static void GetKeyArray(this NativeParallelHashMap map, NativeArray result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { map.m_HashMapData.GetKeyArray(result); } @@ -49,8 +49,8 @@ public static void GetKeyArray(this NativeParallelHashMapThe key type. /// The value type. public static void GetValueArray(this NativeParallelHashMap map, NativeArray result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { map.m_HashMapData.GetValueArray(result); } @@ -64,8 +64,8 @@ public static void GetValueArray(this NativeParallelHashMapThe key type /// The value type public static void GetKeyValueArrays(this NativeParallelHashMap map, NativeKeyValueArrays result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { map.m_HashMapData.GetKeyValueArrays(result); } diff --git a/Scripts/AssemblyInjections/Unity.Collections/UnsafeParallelHashMapInternalExtension.cs b/Scripts/AssemblyInjections/Unity.Collections/UnsafeParallelHashMapInternalExtension.cs index 2db1f7c1..72f417b7 100644 --- a/Scripts/AssemblyInjections/Unity.Collections/UnsafeParallelHashMapInternalExtension.cs +++ b/Scripts/AssemblyInjections/Unity.Collections/UnsafeParallelHashMapInternalExtension.cs @@ -20,8 +20,8 @@ public static class UnsafeParallelHashMapInternalExtension /// The value type. /// The . public static Allocator GetAllocator(this UnsafeParallelHashMap map) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { return map.m_AllocatorLabel.ToAllocator; } @@ -35,8 +35,8 @@ public static Allocator GetAllocator(this UnsafeParallelHashMapThe key type. /// The value type. public static unsafe void GetKeyArray(this UnsafeParallelHashMap map, NativeArray result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { UnsafeParallelHashMapData.GetKeyArray(map.m_Buffer, result); } @@ -50,8 +50,8 @@ public static unsafe void GetKeyArray(this UnsafeParallelHashMapThe key type. /// The value type. public static unsafe void GetValueArray(this UnsafeParallelHashMap map, NativeArray result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { UnsafeParallelHashMapData.GetValueArray(map.m_Buffer, result); } @@ -65,8 +65,8 @@ public static unsafe void GetValueArray(this UnsafeParallelHashMap /// The key type /// The value type public static unsafe void GetKeyValueArrays(this UnsafeParallelHashMap map, NativeKeyValueArrays result) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { UnsafeParallelHashMapData.GetKeyValueArrays(map.m_Buffer, result); } diff --git a/Scripts/AssemblyInjections/Unity.Entities/ComponentTypeDependencyExtension.cs b/Scripts/AssemblyInjections/Unity.Entities/ComponentTypeDependencyExtension.cs index c9f00cc2..7bc3f13d 100644 --- a/Scripts/AssemblyInjections/Unity.Entities/ComponentTypeDependencyExtension.cs +++ b/Scripts/AssemblyInjections/Unity.Entities/ComponentTypeDependencyExtension.cs @@ -11,11 +11,10 @@ /// A collection of extension methods to help calculate and modify the dependencies on s /// directly. /// -[BurstCompatible] public static class ComponentTypeDependencyExtension { - private static UnsafeList s_WriteTypeList_ScratchPad; - private static UnsafeList s_ReadTypeList_ScratchPad; + private static UnsafeList s_WriteTypeList_ScratchPad; + private static UnsafeList s_ReadTypeList_ScratchPad; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Init() @@ -24,13 +23,13 @@ private static void Init() { s_WriteTypeList_ScratchPad.Dispose(); } - s_WriteTypeList_ScratchPad = new UnsafeList(0, Allocator.Persistent); + s_WriteTypeList_ScratchPad = new UnsafeList(0, Allocator.Persistent); if (s_ReadTypeList_ScratchPad.IsCreated) { s_ReadTypeList_ScratchPad.Dispose(); } - s_ReadTypeList_ScratchPad = new UnsafeList(0, Allocator.Persistent); + s_ReadTypeList_ScratchPad = new UnsafeList(0, Allocator.Persistent); } @@ -55,7 +54,6 @@ public static unsafe JobHandle GetDependency(this EntityManager manager, Compone /// The 's . /// The component types to calculate the dependency of. /// The combined dependency for the component types - [NotBurstCompatible] public static unsafe JobHandle GetDependency(this EntityManager manager, params ComponentType[] componentTypes) { return GetDependency(manager.GetCheckedEntityDataAccess()->DependencyManager, componentTypes); @@ -70,7 +68,6 @@ public static unsafe JobHandle GetDependency(this EntityManager manager, params /// The 's . /// The component types to calculate the dependency of. /// The combined dependency for the component types - [NotBurstCompatible] public static unsafe JobHandle GetDependency(this EntityManager manager, T componentTypes) where T : class, IEnumerable { @@ -110,7 +107,6 @@ public static unsafe JobHandle GetDependency(this ComponentType componentType, E /// The component types to calculate the dependency of. /// The 's . /// The combined dependency for the component types - [NotBurstCompatible] public static unsafe JobHandle GetDependency(this T componentTypes, EntityManager manager) where T : class, IEnumerable { @@ -124,7 +120,6 @@ public static unsafe JobHandle GetDependency(this T componentTypes, EntityMan /// The component types to calculate the dependency of. /// The 's . /// The combined dependency for the component types - [NotBurstCompatible] public static unsafe JobHandle GetDependency(this ref NativeArray componentTypes, EntityManager manager) { return GetDependency(manager.GetCheckedEntityDataAccess()->DependencyManager, ref componentTypes); @@ -151,7 +146,6 @@ public static unsafe void AddDependency(this EntityManager manager, JobHandle de /// The 's . /// The handle that represents when the consuming job is complete. /// The component types to set the dependency of. - [NotBurstCompatible] public static unsafe void AddDependency(this EntityManager manager, JobHandle dependency, params ComponentType[] componentTypes) { AddDependency(manager.GetCheckedEntityDataAccess()->DependencyManager, dependency, componentTypes); @@ -166,7 +160,6 @@ public static unsafe void AddDependency(this EntityManager manager, JobHandle de /// The 's . /// The handle that represents when the consuming job is complete. /// The component types to set the dependency of. - [NotBurstCompatible] public static unsafe void AddDependency(this EntityManager manager, JobHandle dependency, T componentTypes) where T : class, IEnumerable { @@ -206,7 +199,6 @@ public static unsafe void AddDependency(this ComponentType componentType, JobHan /// The component types to set the dependency of. /// The handle that represents when the consuming job is complete. /// The 's . - [NotBurstCompatible] public static unsafe void AddDependency(this T componentTypes, JobHandle dependency, EntityManager manager) where T : class, IEnumerable { @@ -220,7 +212,6 @@ public static unsafe void AddDependency(this T componentTypes, JobHandle depe /// The component types to set the dependency of. /// The handle that represents when the consuming job is complete. /// The 's . - [NotBurstCompatible] public static unsafe void AddDependency(this ref NativeArray componentTypes, JobHandle dependency, EntityManager manager) { AddDependency(manager.GetCheckedEntityDataAccess()->DependencyManager, dependency, ref componentTypes); @@ -235,7 +226,7 @@ private static unsafe JobHandle GetDependency(ComponentDependencyManager* depend // 1. Get the pointer to the one type index. // 2. Use the pointer for both the reader and writer parameters // 3. Calculate the reader/writer count based on the component type's access mode. - int* typeIndexPtr = (int*)UnsafeUtility.AddressOf(ref componentType.TypeIndex); + TypeIndex* typeIndexPtr = (TypeIndex*)UnsafeUtility.AddressOf(ref componentType.TypeIndex); int writerCount = componentType.AccessModeType == ComponentType.AccessMode.ReadWrite ? 1 : 0; int readerCount = 1 - writerCount; @@ -243,7 +234,6 @@ private static unsafe JobHandle GetDependency(ComponentDependencyManager* depend ->GetDependency(typeIndexPtr, readerCount, typeIndexPtr, writerCount); } - [NotBurstCompatible] private static unsafe JobHandle GetDependency(ComponentDependencyManager* dependencyManager, T componentTypes) where T : class, IEnumerable { @@ -266,7 +256,7 @@ private static unsafe void AddDependency(ComponentDependencyManager* dependencyM // 1. Get the pointer to the one type index. // 2. Use the pointer for both the reader and writer parameters // 3. Calculate the reader/writer count based on the component type's access mode. - int* typeIndexPtr = (int*)UnsafeUtility.AddressOf(ref componentType.TypeIndex); + TypeIndex* typeIndexPtr = (TypeIndex*)UnsafeUtility.AddressOf(ref componentType.TypeIndex); int writerCount = componentType.AccessModeType == ComponentType.AccessMode.ReadWrite ? 1 : 0; int readerCount = 1 - writerCount; @@ -274,7 +264,6 @@ private static unsafe void AddDependency(ComponentDependencyManager* dependencyM ->AddDependency(typeIndexPtr, readerCount, typeIndexPtr, writerCount, dependency); } - [NotBurstCompatible] private static unsafe void AddDependency(ComponentDependencyManager* dependencyManager, JobHandle dependency, T componentTypes) where T : class, IEnumerable { @@ -290,7 +279,6 @@ private static unsafe void AddDependency(ComponentDependencyManager* dependencyM ->AddDependency(s_ReadTypeList_ScratchPad.Ptr, s_ReadTypeList_ScratchPad.Length, s_WriteTypeList_ScratchPad.Ptr, s_WriteTypeList_ScratchPad.Length, dependency); } - [NotBurstCompatible] private static void BuildTypeLists(T componentTypes) where T : class, IEnumerable { @@ -313,4 +301,4 @@ private static void BuildTypeLists(ref NativeArray componentTypes CalculateReaderWriterDependency.Add(componentType, ref s_ReadTypeList_ScratchPad, ref s_WriteTypeList_ScratchPad); } } -} \ No newline at end of file +} diff --git a/Scripts/AssemblyInjections/Unity.Entities/WorldInternal.cs b/Scripts/AssemblyInjections/Unity.Entities/WorldInternal.cs index 764efe0a..182c602b 100644 --- a/Scripts/AssemblyInjections/Unity.Entities/WorldInternal.cs +++ b/Scripts/AssemblyInjections/Unity.Entities/WorldInternal.cs @@ -8,30 +8,6 @@ namespace Anvil.Unity.DOTS.Entities /// public static class WorldInternal { - /// - /// Dispatched after a world is created. - /// - /// - /// This is a proxy for the internal static event that Unity has made internal. - /// - public static event Action OnWorldCreated - { - add => World.WorldCreated += value; - remove => World.WorldCreated -= value; - } - - /// - /// Dispatched before a world is destroyed. - /// - /// - /// This is a proxy for the internal static event that Unity has made internal. - /// - public static event Action OnWorldDestroyed - { - add => World.WorldDestroyed += value; - remove => World.WorldDestroyed -= value; - } - /// /// Dispatched after a system is created. /// diff --git a/Scripts/Editor/Tests/Entities/Transform/TransformUtilTests.cs b/Scripts/Editor/Tests/Entities/Transform/TransformUtilTests.cs index 15f510c3..21210957 100644 --- a/Scripts/Editor/Tests/Entities/Transform/TransformUtilTests.cs +++ b/Scripts/Editor/Tests/Entities/Transform/TransformUtilTests.cs @@ -61,9 +61,9 @@ public static void AddMissingStandardComponentsTest_NoComponents() TransformUtil.AddMissingStandardComponents(entity, entityManager); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(float3.zero)); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(quaternion.identity)); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(1f)); + Assert.That(entityManager.GetComponentData(entity).Position, Is.EqualTo(float3.zero)); + Assert.That(entityManager.GetComponentData(entity).Rotation, Is.EqualTo(quaternion.identity)); + Assert.That(entityManager.GetComponentData(entity).Scale, Is.EqualTo(1f)); } [Test] @@ -73,37 +73,14 @@ public static void AddMissingStandardComponentsTest_AllComponents() using World world = new World(nameof(TransformUtilTests) + "World"); EntityManager entityManager = world.EntityManager; - Entity entity = entityManager.CreateEntity(typeof(Translation), typeof(Rotation), typeof(Scale)); + Entity entity = entityManager.CreateEntity(typeof(LocalTransform)); - entityManager.SetComponentData(entity, new Translation() { Value = new float3(5f) }); - entityManager.SetComponentData(entity, new Rotation() { Value = quaternion.Euler(45f, 45f, 0f) }); - entityManager.SetComponentData(entity, new Scale() { Value = 5f }); + entityManager.SetComponentData(entity, LocalTransform.FromPositionRotationScale(new float3(5f), quaternion.Euler(45f, 45f, 0f), 5f)); TransformUtil.AddMissingStandardComponents(entity, entityManager); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(new float3(5f))); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(quaternion.Euler(45f, 45f, 0f))); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(5f)); - } - - [Test] - public static void AddMissingStandardComponentsTest_AllAltComponents() - { - Assert.That(nameof(AddMissingStandardComponentsTest_AllAltComponents), Does.StartWith(nameof(TransformUtil.AddMissingStandardComponents) + "Test")); - - using World world = new World(nameof(TransformUtilTests) + "World"); - EntityManager entityManager = world.EntityManager; - Entity entity = entityManager.CreateEntity(typeof(Translation), typeof(CompositeRotation), typeof(NonUniformScale)); - - entityManager.SetComponentData(entity, new Translation() { Value = new float3(5f) }); - entityManager.SetComponentData(entity, new CompositeRotation() { Value = float4x4.RotateX(45f) }); - entityManager.SetComponentData(entity, new NonUniformScale() { Value = new float3(1f, 2f, 3f) }); - TransformUtil.AddMissingStandardComponents(entity, entityManager); - - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(new float3(5f))); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(float4x4.RotateX(45f))); - Assert.That(entityManager.GetComponentData(entity).Value, Is.EqualTo(new float3(1f, 2f, 3f))); - Assert.That(entityManager.HasComponent(entity), Is.False); - Assert.That(entityManager.HasComponent(entity), Is.False); + Assert.That(entityManager.GetComponentData(entity).Position, Is.EqualTo(new float3(5f))); + Assert.That(entityManager.GetComponentData(entity).Rotation, Is.EqualTo(quaternion.Euler(45f, 45f, 0f))); + Assert.That(entityManager.GetComponentData(entity).Scale, Is.EqualTo(5f)); } // ----- ConvertWorldToLocalPoint ----- // diff --git a/Scripts/Editor/anvil-unity-dots-editor.asmdef b/Scripts/Editor/anvil-unity-dots-editor.asmdef index 5a108704..e16ffd51 100644 --- a/Scripts/Editor/anvil-unity-dots-editor.asmdef +++ b/Scripts/Editor/anvil-unity-dots-editor.asmdef @@ -8,7 +8,6 @@ "Unity.Burst", "Unity.Collections", "Unity.Entities", - "Unity.Jobs", "Unity.Mathematics" ], "includePlatforms": [], diff --git a/Scripts/Runtime/Data/BurstableAtomicIDProvider.cs b/Scripts/Runtime/Data/BurstableAtomicIDProvider.cs index f6265383..612bd846 100644 --- a/Scripts/Runtime/Data/BurstableAtomicIDProvider.cs +++ b/Scripts/Runtime/Data/BurstableAtomicIDProvider.cs @@ -12,7 +12,6 @@ namespace Anvil.Unity.DOTS.Data /// An that is compatible with Burst and will get the next ID atomically so it is /// safe to use in threaded context. /// - [BurstCompatible] public readonly unsafe struct BurstableAtomicIDProvider { public const uint DEFAULT_SUPPLY_WARNING_THRESHOLD = uint.MaxValue - 1_000_000; diff --git a/Scripts/Runtime/Data/Collections/DeferredNativeArray.cs b/Scripts/Runtime/Data/Collections/DeferredNativeArray.cs index 33990504..b9bec22a 100644 --- a/Scripts/Runtime/Data/Collections/DeferredNativeArray.cs +++ b/Scripts/Runtime/Data/Collections/DeferredNativeArray.cs @@ -69,15 +69,13 @@ internal DeferredNativeArrayScheduleInfo(void* bufferPtr) /// The type to contain in the [StructLayout(LayoutKind.Sequential)] [NativeContainer] - [BurstCompatible] public struct DeferredNativeArray : INativeDisposable where T : unmanaged { //************************************************************************************************************* // INTERNAL STRUCTS //************************************************************************************************************* - - [BurstCompatible] + [StructLayout(LayoutKind.Sequential)] private unsafe struct BufferInfo { diff --git a/Scripts/Runtime/Data/Collections/UnsafeTypedStream.cs b/Scripts/Runtime/Data/Collections/UnsafeTypedStream.cs index 98e90366..c0a2efa6 100644 --- a/Scripts/Runtime/Data/Collections/UnsafeTypedStream.cs +++ b/Scripts/Runtime/Data/Collections/UnsafeTypedStream.cs @@ -30,13 +30,11 @@ namespace Anvil.Unity.DOTS.Data /// fill up the buffer. /// /// The type of elements to store in the collection. - [BurstCompatible] public unsafe struct UnsafeTypedStream : INativeDisposable where T : unmanaged { /// /// Information about the itself. /// - [BurstCompatible] internal struct BufferInfo { public static readonly int SIZE = UnsafeUtility.SizeOf(); @@ -57,7 +55,6 @@ internal struct BufferInfo /// /// Unity will refer to this as a "foreachindex" which is a little bit confusing. /// - [BurstCompatible] [StructLayout(LayoutKind.Sequential, Size = 64)] internal struct LaneInfo { @@ -77,7 +74,6 @@ internal struct LaneInfo /// Contains the pointer to where the "block" begins and a pointer to another instance /// for the next "block" in the linked list. /// - [BurstCompatible] internal struct BlockInfo { public static readonly int SIZE = UnsafeUtility.SizeOf(); @@ -508,7 +504,6 @@ public NativeArray ToNativeArray(Allocator allocator) /// /// A lightweight struct to allow for writing to the collection /// - [BurstCompatible] public readonly struct Writer { internal static Writer ReinterpretFromPointer(void* ptr) @@ -582,7 +577,6 @@ public LaneWriter AsLaneWriter(int laneIndex) /// /// A lightweight writer instance that is locked to a specific lane /// - [BurstCompatible] public readonly struct LaneWriter { [NativeDisableUnsafePtrRestriction] private readonly BufferInfo* m_BufferInfo; @@ -678,7 +672,6 @@ private void CheckForNewBlock() /// /// A lightweight struct to allow for reader from the collection /// - [BurstCompatible] public readonly struct Reader { [NativeDisableUnsafePtrRestriction] private readonly BufferInfo* m_BufferInfo; @@ -778,7 +771,6 @@ public NativeArray ToNativeArray(Allocator allocator) /// 's manage their own state so that multiple readers can read from a given lane at /// the same time. /// - [BurstCompatible] public struct LaneReader { [NativeDisableUnsafePtrRestriction] private readonly BufferInfo* m_BufferInfo; diff --git a/Scripts/Runtime/Data/Collections/Util/EnumEnumerableToFixedStringExtension.cs b/Scripts/Runtime/Data/Collections/Util/EnumEnumerableToFixedStringExtension.cs index d5c04754..00718f90 100644 --- a/Scripts/Runtime/Data/Collections/Util/EnumEnumerableToFixedStringExtension.cs +++ b/Scripts/Runtime/Data/Collections/Util/EnumEnumerableToFixedStringExtension.cs @@ -32,7 +32,7 @@ public static class EnumEnumerableToFixedStringExtension [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this UnsafeList collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, UnsafeList>>(ref collectionAsRef) @@ -55,7 +55,7 @@ public static TOutputString ToFixedString(in this Unsaf [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this NativeList collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, NativeList>>(ref collectionAsRef) @@ -77,7 +77,7 @@ public static TOutputString ToFixedString(in this Nativ /// public static TOutputString ToFixedString(in this UnsafeArray collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, UnsafeArray>>(ref collectionAsRef) @@ -99,7 +99,7 @@ public static TOutputString ToFixedString(in this Unsaf /// public static TOutputString ToFixedString(in this NativeArray collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, NativeArray>>(ref collectionAsRef) @@ -121,7 +121,7 @@ public static TOutputString ToFixedString(in this Nativ /// public static TOutputString ToFixedString(in this NativeArray.ReadOnly collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As.ReadOnly, NativeArray>.ReadOnly>(ref collectionAsRef) @@ -144,7 +144,7 @@ public static TOutputString ToFixedString(in this Nativ [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this FixedList32Bytes collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, FixedList32Bytes>>(ref collectionAsRef) @@ -167,7 +167,7 @@ public static TOutputString ToFixedString(in this Fixed [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this FixedList64Bytes collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, FixedList64Bytes>>(ref collectionAsRef) @@ -190,7 +190,7 @@ public static TOutputString ToFixedString(in this Fixed [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this FixedList128Bytes collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, FixedList128Bytes>>(ref collectionAsRef) @@ -213,7 +213,7 @@ public static TOutputString ToFixedString(in this Fixed [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this FixedList512Bytes collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, FixedList512Bytes>>(ref collectionAsRef) @@ -236,7 +236,7 @@ public static TOutputString ToFixedString(in this Fixed [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(in this FixedList4096Bytes collection) where TElement : unmanaged, Enum - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { var collectionAsRef = UnsafeUtilityExtensions.AsRef(in collection); return UnsafeUtility.As, FixedList4096Bytes>>(ref collectionAsRef) diff --git a/Scripts/Runtime/Data/Collections/Util/EnumerableToFixedStringExtension.cs b/Scripts/Runtime/Data/Collections/Util/EnumerableToFixedStringExtension.cs index 54cbb8b0..5a233374 100644 --- a/Scripts/Runtime/Data/Collections/Util/EnumerableToFixedStringExtension.cs +++ b/Scripts/Runtime/Data/Collections/Util/EnumerableToFixedStringExtension.cs @@ -30,7 +30,7 @@ public static class EnumerableToFixedStringExtension public static TOutputString ToFixedString(in this UnsafeParallelHashSet collection) where TElement : unmanaged, IToFixedString, IEquatable where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); UnsafeParallelHashSet.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -53,7 +53,7 @@ public static TOutputString ToFixedString(in this NativeParallelHashSet collection) where TElement : unmanaged, IToFixedString, IEquatable where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); NativeParallelHashSet.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -76,7 +76,7 @@ public static TOutputString ToFixedString(in this UnsafeList collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); UnsafeList.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -99,7 +99,7 @@ public static TOutputString ToFixedString(in this NativeList collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); NativeArray.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -122,7 +122,7 @@ public static TOutputString ToFixedString(in this UnsafeArray collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); UnsafeArray.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -145,7 +145,7 @@ public static TOutputString ToFixedString(in this NativeArray collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); NativeArray.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -168,7 +168,7 @@ public static TOutputString ToFixedString(in this NativeArray.ReadOnly collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); NativeArray.ReadOnly.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -191,7 +191,7 @@ public static TOutputString ToFixedString(in this FixedList32Bytes collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); FixedList32Bytes.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -214,7 +214,7 @@ public static TOutputString ToFixedString(in this FixedList64Bytes collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); FixedList64Bytes.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -237,7 +237,7 @@ public static TOutputString ToFixedString(in this FixedList128Bytes collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); FixedList128Bytes.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -260,7 +260,7 @@ public static TOutputString ToFixedString(in this FixedList512Bytes collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); FixedList512Bytes.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -283,7 +283,7 @@ public static TOutputString ToFixedString(in this FixedList4096Bytes collection) where TElement : unmanaged, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { ref var collectionAsRef = ref UnsafeUtilityExtensions.AsRef(in collection); FixedList4096Bytes.Enumerator enumerator = collectionAsRef.GetEnumerator(); @@ -307,7 +307,7 @@ public static unsafe TOutputString ToFixedString where TElement : struct, IToFixedString where TElementString : struct, INativeList, IUTF8Bytes - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { TOutputString output = default; output.Append('['); diff --git a/Scripts/Runtime/Data/Collections/Util/NativeParallelHashMapExtension.cs b/Scripts/Runtime/Data/Collections/Util/NativeParallelHashMapExtension.cs index c57b725b..c9c9b1a9 100644 --- a/Scripts/Runtime/Data/Collections/Util/NativeParallelHashMapExtension.cs +++ b/Scripts/Runtime/Data/Collections/Util/NativeParallelHashMapExtension.cs @@ -18,8 +18,8 @@ public static class NativeParallelHashMapExtension /// The value type. /// True if a key-value pair was removed. public static bool Remove(this NativeParallelHashMap map, TKey key, out TValue value) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { return map.TryGetValue(key, out value) && map.Remove(key); } diff --git a/Scripts/Runtime/Data/Collections/Util/NativeParallelHashSetExtension.cs b/Scripts/Runtime/Data/Collections/Util/NativeParallelHashSetExtension.cs index 732df158..e7d5ff54 100644 --- a/Scripts/Runtime/Data/Collections/Util/NativeParallelHashSetExtension.cs +++ b/Scripts/Runtime/Data/Collections/Util/NativeParallelHashSetExtension.cs @@ -8,6 +8,7 @@ namespace Anvil.Unity.DOTS.Data /// /// A collection of extension methods for . /// + [BurstCompile] public static class NativeParallelHashSetExtension { /// @@ -66,4 +67,4 @@ public static void CopyFrom(this NativeParallelHashSet destination, IEnume } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Data/Collections/Util/UnsafeParallelHashMapExtension.cs b/Scripts/Runtime/Data/Collections/Util/UnsafeParallelHashMapExtension.cs index 69e598c7..1b9d8a08 100644 --- a/Scripts/Runtime/Data/Collections/Util/UnsafeParallelHashMapExtension.cs +++ b/Scripts/Runtime/Data/Collections/Util/UnsafeParallelHashMapExtension.cs @@ -18,8 +18,8 @@ public static class UnsafeParallelHashMapExtension /// The value type. /// True if a key-value pair was removed. public static bool Remove(this UnsafeParallelHashMap map, TKey key, out TValue value) - where TKey : struct, IEquatable - where TValue : struct + where TKey : unmanaged, IEquatable + where TValue : unmanaged { return map.TryGetValue(key, out value) && map.Remove(key); } diff --git a/Scripts/Runtime/Entities/AbstractAnvilSystemBase.cs b/Scripts/Runtime/Entities/AbstractAnvilSystemBase.cs index 16b54db3..adc2069f 100644 --- a/Scripts/Runtime/Entities/AbstractAnvilSystemBase.cs +++ b/Scripts/Runtime/Entities/AbstractAnvilSystemBase.cs @@ -86,7 +86,8 @@ private void EnsureSystemIsInUpdateGroup() m_UpdateInGroupType = updateInGroupAttribute.GroupType; //We'll get or create the system specified in the attribute. It SHOULD be a Group, but might not be so... - ComponentSystemBase componentSystemBase = World.GetOrCreateSystem(m_UpdateInGroupType); + ComponentSystemBase componentSystemBase = World.GetOrCreateSystemManaged(m_UpdateInGroupType); + if (componentSystemBase is not ComponentSystemGroup componentSystemGroup) { //We'll rightly complain about it. diff --git a/Scripts/Runtime/Entities/AccessControl.meta b/Scripts/Runtime/Entities/AccessControl.meta deleted file mode 100644 index f440e2ec..00000000 --- a/Scripts/Runtime/Entities/AccessControl.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 13cde9bd371af472b837b3582b4aa1a3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs deleted file mode 100644 index 70ff4eca..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs +++ /dev/null @@ -1,378 +0,0 @@ -using Anvil.CSharp.Core; -using System; -using System.Collections.Generic; -using Unity.Entities; -using Unity.Jobs; -using UnityEngine; - -namespace Anvil.Unity.DOTS.Entities -{ - internal interface IDynamicBufferSharedWriteController : IDisposable - { - /// - /// Registers a as a system that will shared write to - /// the . - /// - /// The that shared writes. - void RegisterSystemForSharedWrite(ComponentSystemBase system); - - /// - /// Unregisters a as a system that will shared write to - /// the . - /// - /// The that shared writes. - void UnregisterSystemForSharedWrite(ComponentSystemBase system); - - /// - /// Gets a to be used to schedule the jobs that will shared writing to the - /// . - /// - /// The that is doing the shared writing. - /// The incoming Dependency for the - /// The to schedule shared writing jobs - JobHandle GetSharedWriteDependency(SystemBase callingSystem, JobHandle callingSystemDependency); - - /// - /// Sets the shared write dependency to the passed in - /// - /// The to set to - void ForceSetSharedWriteDependency(JobHandle dependsOn); - } - - /// - /// A utility class that handles managing access for shared writing (multiple job types writing at the same time) - /// so that jobs can be scheduled easily. - /// - /// ****IMPORTANT NOTE**** - /// Using this class is very helpful for the specific task of writing to a in - /// parallel from multiple job types. This class DOES NOT prevent multiple threads from writing to the same element. - /// Typically, this means that the use case should guarantee that there is no overlap in buffer element access. - /// For example, element ranges (1-n) are dedicated to specific worker indices. - /// (Worker 0 writes to element 0, Worker 3 writes to element 3, etc...) - /// - /// In order to achieve this functionality the class tracks the World's system order to the best of its ability. - /// There are cases where this isn't perfect and your won't get the results you expect. - /// These cases are outlined below to aid in debugging if needed. - /// - /// ALL OF THESE SHOULD BE VERY RARE - /// - /// - The checks to see if it should be rebuilt by the number of systems in each - /// . If the system count between checks does not change - /// (system reorder or balanced adds/removes) the will not get automatically updated - /// and therefore is unable to correctly infer system dependencies. To work around this limitation - /// call after adding, removing or re-ordering systems. - /// - /// - If you are using s that your Systems aren't aware of. - /// Ex. Queries created with will not detect jobs that touch your - /// . Always use the function. - /// - /// - If you are scheduling jobs outside of a System that operate on this class - /// will not be aware of it and may lead to a dependency conflict. Consider using a - /// to handle this instead. - /// - /// - If you are scheduling multiple jobs in a System that operates on the where - /// one uses the Shared Write handle and the other(s) try and do an exclusive write or read, we treat that - /// System as only using the Shared Write handle. - /// - /// - If you are calling that operates on the - /// outside of your , this - /// class may not be aware of the query until the is rebuilt. - /// This means that a write or read operation may sneak in between two shared writes which would lead to a - /// dependency conflict. It is best practice to create all queries in the or - /// if you must create the query later, manually rebuild the . - /// - /// - You may get a false positive if you have a System that has two or more queries in it. One that operates on - /// your (QueryA) and one that doesn't (QueryB). If the logic has the QueryB - /// execute but QueryA doesn't, we still see the system as having executed and we'll count it as a point to move - /// the handle up when in reality it could have been ignored. - /// - /// - /// - /// This is similar to the but for specific use with a - /// where shared writing is desired. - /// - /// - /// The type this instance is associated with. - internal class DynamicBufferSharedWriteController : AbstractAnvilBase, IDynamicBufferSharedWriteController - where T : IBufferElementData - { - //************************************************************************************************************* - // INTERNAL HELPER - //************************************************************************************************************* - - /// - /// Handles our specific cached view of the - /// - private class LocalCache : AbstractCache - { - private readonly WorldCache m_WorldCache; - private readonly HashSet m_QueryComponentTypes; - private readonly List m_OrderedSystems = new List(); - private readonly List m_ExecutedOrderedSystems = new List(); - private readonly Dictionary m_ExecutedOrderedSystemsLookup = new Dictionary(); - private readonly Dictionary m_OrderedSystemsVersions = new Dictionary(); - - private int m_OrderedSystemsIndexForExecution; - private int m_LastRebuildCheckFrameCount; - - internal LocalCache( - WorldCache worldCache, - ComponentType componentType) - { - m_WorldCache = worldCache; - m_QueryComponentTypes = new HashSet - { - componentType - }; - } - - internal int GetExecutionOrderOf(ComponentSystemBase callingSystem) - { - return !m_ExecutedOrderedSystemsLookup.TryGetValue(callingSystem, out int order) - ? m_ExecutedOrderedSystems.Count - : order; - } - - internal ComponentSystemBase GetSystemAtExecutionOrder(int executionOrder) - { -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (executionOrder <= 0 || executionOrder > m_ExecutedOrderedSystems.Count) - { - throw new InvalidOperationException($"Invalid execution order of {executionOrder}.{nameof(m_ExecutedOrderedSystems)} Count is {m_ExecutedOrderedSystems.Count}"); - } -#endif - - return m_ExecutedOrderedSystems[executionOrder]; - } - - internal void RebuildIfNeeded() - { - //TODO: #27 Move to AbstractCache? - //This might be called many times a frame by many different callers. - //We only want to do this check once per frame. - int currentFrameCount = Time.frameCount; - if (m_LastRebuildCheckFrameCount == currentFrameCount) - { - return; - } - - m_LastRebuildCheckFrameCount = currentFrameCount; - - //Once per frame we want to reset our execution order since some systems may not have executed. - ResetExecutionOrder(); - - //Rebuild the world cache if it needs to be - m_WorldCache.RebuildIfNeeded(); - - //If our local cache doesn't match the latest world cache, we need to update - if (Version == m_WorldCache.Version) - { - return; - } - - //Find all the systems that have queries that match our IBufferElementData - RebuildMatchingSystems(); - - //Ensure we're not going to do this again until the World changes. - Version = m_WorldCache.Version; - } - - private void RebuildMatchingSystems() - { - //Build up our internal model of a list (in order) of systems that will operate on our IBufferElementData - m_OrderedSystemsVersions.Clear(); - m_WorldCache.RefreshSystemsWithQueriesFor(m_QueryComponentTypes, m_OrderedSystems); - //Initialize a lookup with the last version these systems ran at - foreach (ComponentSystemBase system in m_OrderedSystems) - { - m_OrderedSystemsVersions[system] = system.LastSystemVersion; - } - } - - private void ResetExecutionOrder() - { - m_OrderedSystemsIndexForExecution = 0; - m_ExecutedOrderedSystems.Clear(); - m_ExecutedOrderedSystemsLookup.Clear(); - } - - internal void UpdateExecutedSystems(ComponentSystemBase callingSystem) - { - //Once a frame we'll end up iterating through all the OrderedSystems but there's no need to iterate - //the whole list each time. Instead, we'll track the progress through the frame and only iterate up - //to the system that is currently executing and thus checking when it can shared write. - for (; m_OrderedSystemsIndexForExecution < m_OrderedSystems.Count; ++m_OrderedSystemsIndexForExecution) - { - ComponentSystemBase system = m_OrderedSystems[m_OrderedSystemsIndexForExecution]; - - //If we're the calling system, the loop is done, we should exit. - if (callingSystem == system) - { - break; - } - - //Internally, Systems will execute if they are enabled, set to AlwaysUpdate or have any queries - //that will return entities. The systems do this check via ShouldRunSystem and Enabled. - //While we could reflect and call that again, it seems inefficient to do so especially since it - //has already been done. Instead we can check if a system HAS run this frame by comparing the - //LastSystemVersion with our cached version. If the versions are the same, the system didn't run - //for any number of reasons and we can exclude it from our order. If it is enabled the next frame - //the versions won't match and we'll add it back to our executed list. - if (!DidSystemExecuteSinceLastCheck(system)) - { - continue; - } - - m_OrderedSystemsVersions[system] = system.LastSystemVersion; - m_ExecutedOrderedSystems.Add(system); - m_ExecutedOrderedSystemsLookup[system] = m_OrderedSystemsIndexForExecution; - } - } - - private bool DidSystemExecuteSinceLastCheck(ComponentSystemBase system) - { - uint cachedSystemVersion = m_OrderedSystemsVersions[system]; -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (cachedSystemVersion > system.LastSystemVersion) - { - throw new InvalidOperationException($"Investigate. Cached System Version {cachedSystemVersion} is larger than the last recorded version {system.LastSystemVersion}"); - } -#endif - return system.LastSystemVersion > cachedSystemVersion; - } - } - - - //************************************************************************************************************* - // PUBLIC CLASS - //************************************************************************************************************* - - private readonly HashSet m_SharedWriteSystems = new HashSet(); - - private readonly World m_World; - private readonly LocalCache m_LocalCache; - private readonly DynamicBufferSharedWriteDataSystem.LookupByComponentType m_LookupByComponentType; - - private JobHandle m_SharedWriteDependency; - private int m_ExecutionOrderOfLastSharedWriteDependency; - - /// - /// The of this instance is associated with. - /// - public ComponentType ComponentType { get; } - - internal DynamicBufferSharedWriteController( - ComponentType type, - World world, - DynamicBufferSharedWriteDataSystem.LookupByComponentType lookupByComponentType) - { - ComponentType = type; - m_World = world; - m_LookupByComponentType = lookupByComponentType; - WorldCacheDataSystem worldCacheDataSystem = m_World.GetOrCreateSystem(); - m_LocalCache = new LocalCache(worldCacheDataSystem.WorldCache, ComponentType); - } - - protected override void DisposeSelf() - { - // NOTE: If these asserts trigger we should think about calling Complete() on these job handles. -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (!m_SharedWriteDependency.IsCompleted) - { - throw new InvalidOperationException("The shared write access dependency is not completed"); - } -#endif - - //Remove ourselves from the chain - m_LookupByComponentType.Remove(); - - base.DisposeSelf(); - } - - - /// - public void RegisterSystemForSharedWrite(ComponentSystemBase system) - { -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (system.World != m_World) - { - throw new InvalidOperationException($"System {system} is not part of the same world as this {nameof(DynamicBufferSharedWriteController)}"); - } -#endif - m_SharedWriteSystems.Add(system); - } - - /// - public void UnregisterSystemForSharedWrite(ComponentSystemBase system) - { -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (system.World != m_World) - { - throw new InvalidOperationException($"System {system} is not part of the same world as this {nameof(DynamicBufferSharedWriteController)}"); - } -#endif - m_SharedWriteSystems.Remove(system); - } - - /// - public JobHandle GetSharedWriteDependency(SystemBase callingSystem, JobHandle callingSystemDependency) - { -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (!m_SharedWriteSystems.Contains(callingSystem)) - { - throw new InvalidOperationException($"Trying to get the shared write handle but {callingSystem} hasn't been registered. Did you call {nameof(RegisterSystemForSharedWrite)}?"); - } -#endif - - //Rebuild our local cache if we need to. Will trigger a world cache rebuild if necessary too. - m_LocalCache.RebuildIfNeeded(); - - //Ensure our local cache has the right order of systems that actually executed this frame - m_LocalCache.UpdateExecutedSystems(callingSystem); - - //Find out when our system executed in the order - int callingSystemOrder = m_LocalCache.GetExecutionOrderOf(callingSystem); - - //If we're the first system to go in a frame, we're the first start point for shared writing. - if (callingSystemOrder == 0) - { - m_SharedWriteDependency = callingSystemDependency; - m_ExecutionOrderOfLastSharedWriteDependency = callingSystemOrder; - } - //Otherwise we want to check the system(s) that executed before us to see what kind of lock they had - //on our IBufferElementData - else - { - //We want to loop backwards to see if an exclusive write or shared read was inserted - //in the case where a shared write system DOESN'T call this GetSharedWriteDependency - for (int i = callingSystemOrder - 1; i > m_ExecutionOrderOfLastSharedWriteDependency; --i) - { - //If that system was a shared writable system, we don't want to move our dependency up so that we - //can also share the write. If not, we move it up. - if (IsSystemAtExecutionOrderSharedWritable(i)) - { - continue; - } - - m_SharedWriteDependency = callingSystemDependency; - m_ExecutionOrderOfLastSharedWriteDependency = callingSystemOrder; - break; - } - } - - return m_SharedWriteDependency; - } - - private bool IsSystemAtExecutionOrderSharedWritable(int executionOrder) - { - ComponentSystemBase system = m_LocalCache.GetSystemAtExecutionOrder(executionOrder); - return m_SharedWriteSystems.Contains(system); - } - - /// - public void ForceSetSharedWriteDependency(JobHandle dependsOn) - { - m_SharedWriteDependency = dependsOn; - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs.meta b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs.meta deleted file mode 100644 index 14d98f6e..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteController.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5c11fd8cdc7d848ee99a4b1f7ec8ccb6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs deleted file mode 100644 index fc550885..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Unity.Entities; -using Anvil.CSharp.Data; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Data System (no update) for managing access control to a that you want to - /// write to in parallel from multiple different types of jobs. - /// - /// - /// Unity by default treats a parallel job (JobTypeA run in parallel) as one job that can run over multiple - /// threads at the same time. If you want to have more than one job such as JobTypeA and JobTypeB, Unity - /// will not allow it unless you specify the on - /// your . - /// - /// Doing so means that you can now write to the from multiple job types - /// but it assumes that you have taken the necessary precautions to ensure your jobs can't conflict with - /// each other. Typically this means only writing to an index that matches your - /// or - /// - /// Unity's internal read and write handles for scheduling jobs assumes that all jobs are either a shared - /// read or exclusive write. Since we want both job types to start at the same time, this - /// facilitates getting that start point while working - /// nicely in tandem with Unity's built in system that know nothing about your shared writing. - /// - /// This can be accomplished with a but it requires - /// ALL systems in the project who touch the in question to use the - /// which isn't always feasible. - /// - public partial class DynamicBufferSharedWriteDataSystem : AbstractDataSystem - { - private LookupByComponentType m_LookupByComponentType; - - internal DynamicBufferSharedWriteController GetOrCreate() - where T : IBufferElementData - { - return m_LookupByComponentType.GetOrCreate(); - } - - protected override void OnCreate() - { - base.OnCreate(); - - m_LookupByComponentType = new LookupByComponentType(World); - } - - protected override void OnDestroy() - { - m_LookupByComponentType.Dispose(); - base.OnDestroy(); - } - - - //************************************************************************************************************* - // INTERNAL HELPER - //************************************************************************************************************* - - /// - /// Lookup based on a specific - /// - internal class LookupByComponentType : AbstractLookup - { - internal LookupByComponentType(World context) : base(context) { } - - internal void Remove() - where T : IBufferElementData - { - ComponentType componentType = ComponentType.ReadWrite(); - if (!ContainsKey(componentType)) - { - return; - } - - LookupRemove(componentType); - } - - // ReSharper disable once MemberHidesStaticFromOuterClass - internal DynamicBufferSharedWriteController GetOrCreate() - where T : IBufferElementData - { - ComponentType componentType = ComponentType.ReadWrite(); - IDynamicBufferSharedWriteController controller = LookupGetOrCreate(componentType, CreationFunction); - - return (DynamicBufferSharedWriteController)controller; - } - - private IDynamicBufferSharedWriteController CreationFunction(ComponentType componentType) - where T : IBufferElementData - { - return new DynamicBufferSharedWriteController(componentType, Context, this); - } - } - } -} diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs.meta b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs.meta deleted file mode 100644 index 58efd174..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteDataSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 39c290f8517fa4d13b3ab5de80a0f2f1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs deleted file mode 100644 index 4819222d..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Anvil.CSharp.Core; -using Unity.Entities; -using Unity.Jobs; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// A handle to allow for figuring out the dependency of scheduling a job that will shared write to a - /// . - /// - /// See and - /// for more in depth background. - /// - public class DynamicBufferSharedWriteHandle : AbstractAnvilBase - { - private readonly IDynamicBufferSharedWriteController m_Controller; - private readonly SystemBase m_System; - - internal DynamicBufferSharedWriteHandle(IDynamicBufferSharedWriteController controller, SystemBase system) - { - m_Controller = controller; - m_System = system; - - m_Controller.RegisterSystemForSharedWrite(m_System); - } - - protected override void DisposeSelf() - { - m_Controller.UnregisterSystemForSharedWrite(m_System); - base.DisposeSelf(); - } - - /// - /// Gets a to be used to schedule the jobs that will shared writing to the - /// . - /// - /// The incoming Dependency for the calling system. - /// The to schedule shared writing jobs - public JobHandle GetSharedWriteDependency(JobHandle callingSystemDependency) - { - return m_Controller.GetSharedWriteDependency(m_System, callingSystemDependency); - } - - /// - /// Sets the shared write dependency to the passed in . - /// - /// NOTE: This should be quite rare. It is better to let the system automatically determine the dependency. - /// If a situation occurs where an exclusive write or shared read happens in a shared write - /// , it would be ideal to move those a different system. If that is not possible - /// then calling this function to set the proper shared write dependency can be done. - /// - /// The to set the shared write dependency too - public void ForceSetSharedWriteDependency(JobHandle dependsOn) - { - m_Controller.ForceSetSharedWriteDependency(dependsOn); - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs.meta b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs.meta deleted file mode 100644 index 429818e3..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b749ba9193aa74e098afc1d551ba67e9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs deleted file mode 100644 index 1edc3d56..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Unity.Entities; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Extension methods for for use with - /// - public static class DynamicBufferSharedWriteHandleSystemExtension - { - /// - /// Gets a for a given - /// - /// - /// The that wishes to perform a shared write - /// on a - /// - /// - /// he type of in the - /// - /// An instance of - public static DynamicBufferSharedWriteHandle GetDynamicBufferSharedWriteHandle(this SystemBase sharedWriteSystem) - where T : IBufferElementData - { - DynamicBufferSharedWriteDataSystem dataSystem = sharedWriteSystem.World.GetOrCreateSystem(); - DynamicBufferSharedWriteController controller = dataSystem.GetOrCreate(); - return new DynamicBufferSharedWriteHandle(controller, sharedWriteSystem); - } - } -} diff --git a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs.meta b/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs.meta deleted file mode 100644 index 17902c03..00000000 --- a/Scripts/Runtime/Entities/AccessControl/DynamicBufferSharedWriteHandleSystemExtension.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7f1e097f4c26c4f88b71260514abcd1d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/Cache.meta b/Scripts/Runtime/Entities/Cache.meta deleted file mode 100644 index 91c79e05..00000000 --- a/Scripts/Runtime/Entities/Cache.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f2348f43ab9984f66b9c69e8c0e04bba -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Runtime/Entities/Cache/AbstractCache.cs b/Scripts/Runtime/Entities/Cache/AbstractCache.cs deleted file mode 100644 index 99d71473..00000000 --- a/Scripts/Runtime/Entities/Cache/AbstractCache.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Anvil.CSharp.Core; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Helper class to aid with caching - /// - public abstract class AbstractCache : AbstractAnvilBase - { - protected const int INITIAL_VERSION = -1; - - /// - /// The current version of this cache - /// - public int Version - { - get; - internal set; - } = INITIAL_VERSION; - } -} diff --git a/Scripts/Runtime/Entities/Cache/AbstractCache.cs.meta b/Scripts/Runtime/Entities/Cache/AbstractCache.cs.meta deleted file mode 100644 index b12265fb..00000000 --- a/Scripts/Runtime/Entities/Cache/AbstractCache.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 82777d45f7cf4d9aa9147b29bfc12bf7 -timeCreated: 1652276801 \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/SystemCache.cs b/Scripts/Runtime/Entities/Cache/SystemCache.cs deleted file mode 100644 index 18918e4e..00000000 --- a/Scripts/Runtime/Entities/Cache/SystemCache.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.Entities; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Represents a cached state of a - /// - public class SystemCache - { - /// - /// The this cache represents - /// - public ComponentSystemBase System { get; } - - /// - /// The s used in any s - /// on the - /// - public HashSet QueryComponentTypes { get; } = new HashSet(); - - /// - /// The number of s this has. - /// - public int QueryCount { get; private set; } - - private readonly HashSet m_GroupCaches = new HashSet(); - - internal SystemCache(SystemGroupCache groupCache, ComponentSystemBase system) - { - m_GroupCaches.Add(groupCache); - System = system; - } - - internal void ClearGroups() - { - m_GroupCaches.Clear(); - } - - internal virtual void RebuildIfNeeded(SystemGroupCache parentGroupCache) - { - //Will ignore if already added - m_GroupCaches.Add(parentGroupCache); - int currentQueryCount = System.EntityQueries.Length; - -#if ENABLE_UNITY_COLLECTIONS_CHECKS - if (currentQueryCount < QueryCount) - { - throw new InvalidOperationException($"System queries decreased!"); - } -#endif - - if (currentQueryCount > QueryCount) - { - RebuildQueries(); - } - } - - private void RebuildQueries() - { - QueryComponentTypes.Clear(); - EntityQuery[] queries = System.EntityQueries; - foreach (EntityQuery query in queries) - { - ComponentType[] componentTypes = query.GetReadWriteComponentTypes(); - foreach (ComponentType componentType in componentTypes) - { - QueryComponentTypes.Add(componentType); - } - } - - QueryCount = queries.Length; - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/SystemCache.cs.meta b/Scripts/Runtime/Entities/Cache/SystemCache.cs.meta deleted file mode 100644 index 2c117025..00000000 --- a/Scripts/Runtime/Entities/Cache/SystemCache.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0a2072273b284a36a71b72f9923685b2 -timeCreated: 1652276782 \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs b/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs deleted file mode 100644 index 60b12775..00000000 --- a/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Unity.Entities; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Represents a cached state of a - /// - public class SystemGroupCache : SystemCache - { - /// - /// The number of s and/or s - /// that are part of this - /// - public int CachedGroupSystemsCount - { - get; - private set; - } - - /// - /// The this cache represents - /// - public ComponentSystemGroup SystemGroup - { - get; - } - - internal SystemGroupCache(SystemGroupCache parentGroupCache, ComponentSystemGroup group) : base(parentGroupCache, group) - { - SystemGroup = group; - } - - internal override void RebuildIfNeeded(SystemGroupCache parentGroupCache) - { - base.RebuildIfNeeded(parentGroupCache); - - //No need to check if we're different, just assign - CachedGroupSystemsCount = SystemGroup.Systems.Count; - } - } -} diff --git a/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs.meta b/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs.meta deleted file mode 100644 index 8b5677e7..00000000 --- a/Scripts/Runtime/Entities/Cache/SystemGroupCache.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 586cafdf0f7a428cba2ba8d4d50990bb -timeCreated: 1652293030 \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/WorldCache.cs b/Scripts/Runtime/Entities/Cache/WorldCache.cs deleted file mode 100644 index 2545edda..00000000 --- a/Scripts/Runtime/Entities/Cache/WorldCache.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.Entities; -using UnityEngine; -using UnityEngine.LowLevel; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Represents the cached state of a - /// - public class WorldCache : AbstractCache - { - private static readonly Type COMPONENT_SYSTEM_GROUP_TYPE = typeof(ComponentSystemGroup); - - private readonly Dictionary m_SystemCacheLookup = new Dictionary(); - private readonly List m_OrderedSystemCaches = new List(); - private readonly List m_OrderedSystemGroupCaches = new List(); - - private int m_LastRebuildCheckFrameCount; - - /// - /// The this represents. - /// - public World World { get; } - - internal WorldCache(World world) - { - World = world; - } - - /// - /// Given a set of s, populate a list with all systems - /// that have s that will write/read to any - /// in the set. - /// - /// Set of s to find matching systems for. - /// A list that will be populated with the matching systems - public void RefreshSystemsWithQueriesFor(HashSet componentTypes, List matchingSystems) - { - matchingSystems.Clear(); - - foreach (SystemCache systemCache in m_OrderedSystemCaches) - { - foreach (ComponentType componentType in componentTypes) - { - if (systemCache.QueryComponentTypes.Contains(componentType)) - { - matchingSystems.Add(systemCache.System); - break; - } - } - } - } - - /// - /// Forces a rebuild of the cache - /// - public void ForceRebuild() - { - m_LastRebuildCheckFrameCount = Time.frameCount; - Rebuild(); - } - - /// - /// Rebuilds the cache if needed. - /// - public void RebuildIfNeeded() - { - //This might be called many times a frame by many different callers. - //We only want to do this check once per frame. - int currentFrameCount = Time.frameCount; - if (m_LastRebuildCheckFrameCount == currentFrameCount) - { - return; - } - - m_LastRebuildCheckFrameCount = currentFrameCount; - - - //If we've never been built before - if (Version == INITIAL_VERSION) - { - Rebuild(); - return; - } - - //If any of our groups have a different system count from the last time we built - //Someone added a new system or removed a system - //We can't tell if a new group was added or removed though - foreach (SystemGroupCache groupSystemCache in m_OrderedSystemGroupCaches) - { - if (groupSystemCache.SystemGroup.Systems.Count == groupSystemCache.CachedGroupSystemsCount) - { - continue; - } - - Rebuild(); - return; - } - } - - private void Rebuild() - { - Version++; - m_OrderedSystemCaches.Clear(); - m_OrderedSystemGroupCaches.Clear(); - //Because a system instance can be part of multiple groups, we need to clear the groups in case - //we were removed from one of the groups. We'll get properly added to all groups in the rebuild process. - foreach (SystemCache systemCache in m_SystemCacheLookup.Values) - { - systemCache.ClearGroups(); - } - - PlayerLoopSystem rootPlayerLoopSystem = PlayerLoop.GetCurrentPlayerLoop(); - ParsePlayerLoopSystem(ref rootPlayerLoopSystem); - } - - private void ParsePlayerLoopSystem(ref PlayerLoopSystem playerLoopSystem) - { - if (playerLoopSystem.updateDelegate != null - && COMPONENT_SYSTEM_GROUP_TYPE.IsAssignableFrom(playerLoopSystem.type) - && PlayerLoopUtil.IsPlayerLoopSystemPartOfWorld(ref playerLoopSystem, World) - && PlayerLoopUtil.TryGetSystemFromPlayerLoopSystem(ref playerLoopSystem, out ComponentSystemBase group)) - { - ParseSystemGroup(null, (ComponentSystemGroup)group); - } - - //Phases won't have subsystems - if (playerLoopSystem.subSystemList == null) - { - return; - } - - //Loop through all children - for (int i = 0; i < playerLoopSystem.subSystemList.Length; ++i) - { - ParsePlayerLoopSystem(ref playerLoopSystem.subSystemList[i]); - } - } - - private SystemCache GetOrCreateSystemCache(SystemGroupCache parentGroupCache, ComponentSystemBase system) - { - //See if we've ever created this SystemCache before and create if not - if (!m_SystemCacheLookup.TryGetValue(system, out SystemCache systemCache)) - { - if (system is ComponentSystemGroup group) - { - systemCache = new SystemGroupCache(parentGroupCache, group); - } - else - { - systemCache = new SystemCache(parentGroupCache, system); - } - - m_SystemCacheLookup.Add(system, systemCache); - } - - return systemCache; - } - - private void ParseSystemGroup(SystemGroupCache parentGroupCache, ComponentSystemGroup group) - { - SystemGroupCache systemGroupCache = (SystemGroupCache)GetOrCreateSystemCache(parentGroupCache, group); - //Ensure systems are sorted properly - group.SortSystems(); - m_OrderedSystemGroupCaches.Add(systemGroupCache); - m_OrderedSystemCaches.Add(systemGroupCache); - systemGroupCache.RebuildIfNeeded(parentGroupCache); - - IReadOnlyList groupSystems = systemGroupCache.SystemGroup.Systems; - // ReSharper disable once ForCanBeConvertedToForeach - for (int i = 0; i < groupSystems.Count; ++i) - { - ComponentSystemBase groupSystem = groupSystems[i]; - if (groupSystem is ComponentSystemGroup childGroup) - { - ParseSystemGroup(systemGroupCache, childGroup); - } - else - { - ParseSystem(systemGroupCache, groupSystem); - } - } - } - - private void ParseSystem(SystemGroupCache parentGroupCache, ComponentSystemBase system) - { - SystemCache systemCache = GetOrCreateSystemCache(parentGroupCache, system); - m_OrderedSystemCaches.Add(systemCache); - systemCache.RebuildIfNeeded(parentGroupCache); - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/WorldCache.cs.meta b/Scripts/Runtime/Entities/Cache/WorldCache.cs.meta deleted file mode 100644 index 81a82c10..00000000 --- a/Scripts/Runtime/Entities/Cache/WorldCache.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9b0e7294fa5a498285497bea46cd4bda -timeCreated: 1652273936 \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs b/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs deleted file mode 100644 index dab376f1..00000000 --- a/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Unity.Entities; - -namespace Anvil.Unity.DOTS.Entities -{ - /// - /// Data System (no update) for managing a cached view of a - /// - public partial class WorldCacheDataSystem : AbstractDataSystem - { - public WorldCache WorldCache { get; private set; } - - protected override void OnCreate() - { - WorldCache = new WorldCache(World); - - base.OnCreate(); - } - - protected override void OnDestroy() - { - WorldCache.Dispose(); - - base.OnDestroy(); - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs.meta b/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs.meta deleted file mode 100644 index c93fc14e..00000000 --- a/Scripts/Runtime/Entities/Cache/WorldCacheDataSystem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 42e7f06224904728bc3624c8c7fae243 -timeCreated: 1651798847 \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/BufferFromSingleEntity.cs b/Scripts/Runtime/Entities/Data/BufferFromSingleEntity.cs index 6db4f301..256c97d0 100644 --- a/Scripts/Runtime/Entities/Data/BufferFromSingleEntity.cs +++ b/Scripts/Runtime/Entities/Data/BufferFromSingleEntity.cs @@ -9,21 +9,21 @@ namespace Anvil.Unity.DOTS.Entities /// /// The element type of the buffer /// Allows developers to define jobs with fewer parameters that clearly communicate intent. - public struct BufferFromSingleEntity where T : struct, IBufferElementData + public struct BufferFromSingleEntity where T : unmanaged, IBufferElementData { //TODO: #115 - Implement a safety check to make sure there isn't another lookup/entity combination in flight. // Until the above is implemented leave it to consuming jobs to add the attributes. [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] - private BufferFromEntity m_Lookup; + private BufferLookup m_Lookup; private readonly Entity m_Entity; /// /// Creates a new . /// - /// The lookup to read the buffer reference from. + /// The lookup to read the buffer reference from. /// The that the is on. - public BufferFromSingleEntity(BufferFromEntity lookup, Entity entity) + public BufferFromSingleEntity(BufferLookup lookup, Entity entity) { m_Lookup = lookup; m_Entity = entity; diff --git a/Scripts/Runtime/Entities/Data/CDFEReader.cs b/Scripts/Runtime/Entities/Data/CDFEReader.cs index ab0fd7f7..2b05af09 100644 --- a/Scripts/Runtime/Entities/Data/CDFEReader.cs +++ b/Scripts/Runtime/Entities/Data/CDFEReader.cs @@ -4,14 +4,13 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// Represents a read only reference to a + /// Represents a read only reference to a /// To be used in jobs that only allows for reading of this data. /// /// The type of to read - [BurstCompatible] - public readonly struct CDFEReader where T : struct, IComponentData + public readonly struct CDFEReader where T : unmanaged, IComponentData { - [ReadOnly] private readonly ComponentDataFromEntity m_CDFE; + [ReadOnly] private readonly ComponentLookup m_CDFE; /// /// Gets the that corresponds to the passed @@ -25,19 +24,19 @@ public T this[Entity entity] public CDFEReader(SystemBase system) { - m_CDFE = system.GetComponentDataFromEntity(true); + m_CDFE = system.GetComponentLookup(true); } - internal CDFEReader(ComponentDataFromEntity rawCDFE) + internal CDFEReader(ComponentLookup rawCDFE) { m_CDFE = rawCDFE; } - /// + /// public bool HasComponent(Entity entity) => m_CDFE.HasComponent(entity); - /// + /// public bool TryGetComponent(Entity entity, out T component) => m_CDFE.TryGetComponent(entity, out component); } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/CDFEWriter.cs b/Scripts/Runtime/Entities/Data/CDFEWriter.cs index d4fe4c34..366d4366 100644 --- a/Scripts/Runtime/Entities/Data/CDFEWriter.cs +++ b/Scripts/Runtime/Entities/Data/CDFEWriter.cs @@ -5,25 +5,24 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// Represents a that can be read from and written to in + /// Represents a that can be read from and written to in /// parallel. It sets the on the CDFE. /// To be used in jobs that allow for updating a specific instance in the CDFE. /// /// - /// NOTE: The has the + /// NOTE: The has the /// applied meaning that Unity will not issue /// safety warnings when using it in jobs. This is because there might be many jobs of the same type but /// representing different s and Unity's safety system gets upset if you straddle /// across the jobs. /// /// The type of to update. - [BurstCompatible] - public struct CDFEWriter where T : struct, IComponentData + public struct CDFEWriter where T : unmanaged, IComponentData { // TODO: #197 - Improve Safety. Currently unable to detect parallel writing from multiple jobs. // Required to allow JobPart patterns [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] - private ComponentDataFromEntity m_CDFE; + private ComponentLookup m_CDFE; /// /// Gets/Sets the that corresponds to the passed @@ -38,13 +37,13 @@ public T this[Entity entity] public CDFEWriter(SystemBase system) { - m_CDFE = system.GetComponentDataFromEntity(false); + m_CDFE = system.GetComponentLookup(false); } - /// + /// public bool HasComponent(Entity entity) => m_CDFE.HasComponent(entity); - /// + /// public bool TryGetComponent(Entity entity, out T component) => m_CDFE.TryGetComponent(entity, out component); /// diff --git a/Scripts/Runtime/Entities/Data/ComponentDataFromSingleEntity.cs b/Scripts/Runtime/Entities/Data/ComponentLookupFromSingleEntity.cs similarity index 72% rename from Scripts/Runtime/Entities/Data/ComponentDataFromSingleEntity.cs rename to Scripts/Runtime/Entities/Data/ComponentLookupFromSingleEntity.cs index 4ceff388..f532ad99 100644 --- a/Scripts/Runtime/Entities/Data/ComponentDataFromSingleEntity.cs +++ b/Scripts/Runtime/Entities/Data/ComponentLookupFromSingleEntity.cs @@ -7,20 +7,20 @@ namespace Anvil.Unity.DOTS.Entities /// /// The type that implements /// Allows developers to define jobs with fewer parameters that clearly communicate intent. - public readonly struct ComponentDataFromSingleEntity where T : struct, IComponentData + public readonly struct ComponentLookupFromSingleEntity where T : unmanaged, IComponentData { //TODO: #115 - Implement a safety check to make sure there isn't another lookup/entity combination in flight. // Until the above is implemented leave it to consuming jobs to add the attributes. // [NativeDisableContainerSafetyRestriction] - private readonly ComponentDataFromEntity m_Lookup; + private readonly ComponentLookup m_Lookup; private readonly Entity m_Entity; /// - /// Creates a new . + /// Creates a new . /// - /// The lookup to read the component reference from. + /// The lookup to read the component reference from. /// The that the is on. - public ComponentDataFromSingleEntity(ComponentDataFromEntity lookup, Entity entity) + public ComponentLookupFromSingleEntity(ComponentLookup lookup, Entity entity) { m_Lookup = lookup; m_Entity = entity; diff --git a/Scripts/Runtime/Entities/Data/ComponentDataFromSingleEntity.cs.meta b/Scripts/Runtime/Entities/Data/ComponentLookupFromSingleEntity.cs.meta similarity index 100% rename from Scripts/Runtime/Entities/Data/ComponentDataFromSingleEntity.cs.meta rename to Scripts/Runtime/Entities/Data/ComponentLookupFromSingleEntity.cs.meta diff --git a/Scripts/Runtime/Entities/Data/DBFEForExclusiveWrite.cs b/Scripts/Runtime/Entities/Data/DBFEForExclusiveWrite.cs index 15d4d8bc..6d52be30 100644 --- a/Scripts/Runtime/Entities/Data/DBFEForExclusiveWrite.cs +++ b/Scripts/Runtime/Entities/Data/DBFEForExclusiveWrite.cs @@ -1,3 +1,4 @@ +using Anvil.Unity.DOTS.Entities.TaskDriver; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; @@ -5,30 +6,29 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// Represents a that can be read from and written to. + /// Represents a that can be read from and written to. /// Each can be read/write in a separate thread in parallel /// but the contents of the are constrained to that thread. /// To be used in jobs that allow for updating a specific instance in the DBFE /// /// The type of to update. /// - /// NOTE: The has the + /// NOTE: The has the /// applied meaning that Unity will not issue /// safety warnings when using it in jobs. This is because there might be many jobs of the same type but /// representing different s and Unity's safety system gets upset if you straddle /// across the jobs. /// - [BurstCompatible] - public struct DBFEForExclusiveWrite where T : struct, IBufferElementData + public struct DBFEForExclusiveWrite where T : unmanaged, IBufferElementData { // TODO: #197 - Improve Safety. Currently unable to detect parallel writing from multiple jobs. // Required to allow JobPart patterns [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] [WriteOnly] - private BufferFromEntity m_DBFE; + private BufferLookup m_DBFE; public DBFEForExclusiveWrite(SystemBase system) { - m_DBFE = system.GetBufferFromEntity(false); + m_DBFE = system.GetBufferLookup(false); } /// @@ -40,10 +40,10 @@ public DynamicBuffer this[Entity entity] get => m_DBFE[entity]; } - /// - public bool HasComponent(Entity entity) => m_DBFE.HasComponent(entity); + /// + public bool HasBuffer(Entity entity) => m_DBFE.HasBuffer(entity); - /// + /// public bool TryGetBuffer(Entity entity, out DynamicBuffer component) => m_DBFE.TryGetBuffer(entity, out component); } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/DBFEForRead.cs b/Scripts/Runtime/Entities/Data/DBFEForRead.cs index 8c80fc84..2e15c60f 100644 --- a/Scripts/Runtime/Entities/Data/DBFEForRead.cs +++ b/Scripts/Runtime/Entities/Data/DBFEForRead.cs @@ -4,19 +4,18 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// Represents a that can only be read from. + /// Represents a that can only be read from. /// Each can be read in a separate thread in parallel. /// To be used in jobs that allow for reading a specific instance in the DBFE /// /// The type of to update. - [BurstCompatible] - public readonly struct DBFEForRead where T : struct, IBufferElementData + public readonly struct DBFEForRead where T : unmanaged, IBufferElementData { - [ReadOnly] private readonly BufferFromEntity m_DBFE; + [ReadOnly] private readonly BufferLookup m_DBFE; public DBFEForRead(SystemBase system) { - m_DBFE = system.GetBufferFromEntity(true); + m_DBFE = system.GetBufferLookup(true); } /// @@ -28,10 +27,10 @@ public DynamicBuffer this[Entity entity] get => m_DBFE[entity]; } - /// - public bool HasComponent(Entity entity) => m_DBFE.HasComponent(entity); + /// + public bool HasBuffer(Entity entity) => m_DBFE.HasBuffer(entity); - /// + /// public bool TryGetBuffer(Entity entity, out DynamicBuffer component) => m_DBFE.TryGetBuffer(entity, out component); } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/DataOwnerID.cs b/Scripts/Runtime/Entities/Data/DataOwnerID.cs index 7ca8c1c3..ebdec1be 100644 --- a/Scripts/Runtime/Entities/Data/DataOwnerID.cs +++ b/Scripts/Runtime/Entities/Data/DataOwnerID.cs @@ -6,7 +6,6 @@ namespace Anvil.Unity.DOTS.Entities { - [BurstCompatible] [StructLayout(LayoutKind.Sequential)] internal readonly struct DataOwnerID : IEquatable, IToFixedString @@ -22,8 +21,8 @@ namespace Anvil.Unity.DOTS.Entities { return !(lhs == rhs); } - - + + private readonly int m_Value; public bool IsValid @@ -36,7 +35,7 @@ public DataOwnerID(int value) Debug.Assert(value != UNSET_ID.m_Value); m_Value = value; } - + public bool Equals(DataOwnerID other) { return this == other; @@ -56,11 +55,10 @@ public override string ToString() { return m_Value.ToString(); } - - [BurstCompatible] + public FixedString32Bytes ToFixedString() { return $"Value: {m_Value}"; } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/DataTargetID.cs b/Scripts/Runtime/Entities/Data/DataTargetID.cs index b7c58a85..3c6df990 100644 --- a/Scripts/Runtime/Entities/Data/DataTargetID.cs +++ b/Scripts/Runtime/Entities/Data/DataTargetID.cs @@ -6,7 +6,6 @@ namespace Anvil.Unity.DOTS.Entities { - [BurstCompatible] [StructLayout(LayoutKind.Sequential)] internal readonly struct DataTargetID : IEquatable, IToFixedString @@ -22,10 +21,10 @@ namespace Anvil.Unity.DOTS.Entities { return !(lhs == rhs); } - - + + private readonly int m_Value; - + public bool IsValid { get => this != UNSET_ID; @@ -36,7 +35,7 @@ public DataTargetID(int value) Debug.Assert(value != UNSET_ID.m_Value); m_Value = value; } - + public bool Equals(DataTargetID other) { return this == other; @@ -56,11 +55,10 @@ public override string ToString() { return m_Value.ToString(); } - - [BurstCompatible] + public FixedString32Bytes ToFixedString() { return $"{m_Value}"; } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Data/EntityEnumerableToFixedStringExtension.cs b/Scripts/Runtime/Entities/Data/EntityEnumerableToFixedStringExtension.cs index e54e1312..0dc76fea 100644 --- a/Scripts/Runtime/Entities/Data/EntityEnumerableToFixedStringExtension.cs +++ b/Scripts/Runtime/Entities/Data/EntityEnumerableToFixedStringExtension.cs @@ -30,7 +30,7 @@ public static class EntityEnumerableToFixedStringExtension /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this UnsafeParallelHashSet collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, UnsafeParallelHashSet>(ref collection) .ToFixedString(); @@ -49,7 +49,7 @@ public static TOutputString ToFixedString(ref this UnsafeParallel /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this NativeParallelHashSet collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, NativeParallelHashSet>(ref collection) .ToFixedString(); @@ -67,7 +67,7 @@ public static TOutputString ToFixedString(ref this NativeParallel /// /// public static TOutputString ToFixedString(ref this UnsafeList collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, UnsafeList>(ref collection) .ToFixedString(); @@ -86,7 +86,7 @@ public static TOutputString ToFixedString(ref this UnsafeList [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this NativeList collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, NativeList>(ref collection) .ToFixedString(); @@ -105,7 +105,7 @@ public static TOutputString ToFixedString(ref this NativeList [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this UnsafeArray collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, UnsafeArray>(ref collection) .ToFixedString(); @@ -124,7 +124,7 @@ public static TOutputString ToFixedString(ref this UnsafeArray [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this NativeArray collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As, NativeArray>(ref collection) .ToFixedString(); @@ -143,7 +143,7 @@ public static TOutputString ToFixedString(ref this NativeArray [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOutputString ToFixedString(ref this NativeArray.ReadOnly collection) - where TOutputString : struct, INativeList, IUTF8Bytes + where TOutputString : unmanaged, INativeList, IUTF8Bytes { return UnsafeUtility.As.ReadOnly, NativeArray.ReadOnly>(ref collection) .ToFixedString(); diff --git a/Scripts/Runtime/Entities/Job/CopyBufferToDeferredNativeArray.cs b/Scripts/Runtime/Entities/Job/CopyBufferToDeferredNativeArray.cs index b5aff347..3c767cc4 100644 --- a/Scripts/Runtime/Entities/Job/CopyBufferToDeferredNativeArray.cs +++ b/Scripts/Runtime/Entities/Job/CopyBufferToDeferredNativeArray.cs @@ -15,7 +15,7 @@ public struct CopyBufferToDeferredNativeArray : IJob where T : unmanaged, IBu /// /// The type handle for the to copy from. /// - [ReadOnly] public BufferFromSingleEntity InputBufferFromEntity; + [ReadOnly] public BufferFromSingleEntity InputBufferLookup; /// /// The : IJob where T : unmanaged, IBu /// public void Execute() { - NativeArray inputBuffer = InputBufferFromEntity.GetBuffer().AsNativeArray(); + NativeArray inputBuffer = InputBufferLookup.GetBuffer().AsNativeArray(); NativeArray outputBuffer = OutputBuffer.DeferredCreate(inputBuffer.Length, NativeArrayOptions.UninitializedMemory); outputBuffer.CopyFrom(inputBuffer); } diff --git a/Scripts/Runtime/Entities/Job/CopyBufferToNativeArray.cs b/Scripts/Runtime/Entities/Job/CopyBufferToNativeArray.cs index 92b1cdb3..8c565032 100644 --- a/Scripts/Runtime/Entities/Job/CopyBufferToNativeArray.cs +++ b/Scripts/Runtime/Entities/Job/CopyBufferToNativeArray.cs @@ -13,12 +13,12 @@ namespace Anvil.Unity.DOTS.Entities /// and must have the same length. /// [BurstCompile] - public struct CopyBufferToNativeArray : IJob where T : struct, IBufferElementData + public struct CopyBufferToNativeArray : IJob where T : unmanaged, IBufferElementData { /// /// The type handle for the to copy from. /// - [ReadOnly] public BufferFromSingleEntity InputBufferFromEntity; + [ReadOnly] public BufferFromSingleEntity InputBufferLookup; /// /// The .Copy()` but it's not // necessary for the intended use case and adds complexity. Add support if the need arises. - NativeArray inputBuffer = InputBufferFromEntity.GetBuffer().AsNativeArray(); + NativeArray inputBuffer = InputBufferLookup.GetBuffer().AsNativeArray(); Debug.Assert(inputBuffer.Length == OutputBuffer.Length, "Output buffer must be the same size as the singleton buffer"); OutputBuffer.CopyFrom(inputBuffer); } diff --git a/Scripts/Runtime/Entities/Job/CopyNativeArrayToBuffer.cs b/Scripts/Runtime/Entities/Job/CopyNativeArrayToBuffer.cs index 7cc67889..f6b54a0a 100644 --- a/Scripts/Runtime/Entities/Job/CopyNativeArrayToBuffer.cs +++ b/Scripts/Runtime/Entities/Job/CopyNativeArrayToBuffer.cs @@ -13,7 +13,7 @@ namespace Anvil.Unity.DOTS.Entities /// and must have the same length. /// [BurstCompile] - public struct CopyNativeArrayToBuffer : IJob where T : struct, IBufferElementData + public struct CopyNativeArrayToBuffer : IJob where T : unmanaged, IBufferElementData { /// /// The to copy from. @@ -23,12 +23,12 @@ public struct CopyNativeArrayToBuffer : IJob where T : struct, IBufferElement /// /// The type handle for the to copy to. /// - [WriteOnly] public BufferFromSingleEntity OutputBufferFromEntity; + [WriteOnly] public BufferFromSingleEntity OutputBufferLookup; /// public void Execute() { - NativeArray outputBuffer = OutputBufferFromEntity.GetBuffer().AsNativeArray(); + NativeArray outputBuffer = OutputBufferLookup.GetBuffer().AsNativeArray(); // Could be modified to support mismatched lengths using `NativeArray.Copy()` but it's not // necessary for the intended use case and adds complexity. Add support if the need arises. @@ -36,4 +36,4 @@ public void Execute() NativeArray.Copy(InputBuffer, outputBuffer); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Job/FloodSetComponentJob.cs b/Scripts/Runtime/Entities/Job/FloodSetComponentJob.cs index ffa63f36..f106771e 100644 --- a/Scripts/Runtime/Entities/Job/FloodSetComponentJob.cs +++ b/Scripts/Runtime/Entities/Job/FloodSetComponentJob.cs @@ -1,5 +1,6 @@ -using Anvil.Unity.DOTS.Data; using Unity.Burst; +using Unity.Burst.Intrinsics; +using Unity.Collections; using Unity.Entities; using UnityEngine; @@ -11,7 +12,7 @@ namespace Anvil.Unity.DOTS.Entities /// /// The type. [BurstCompile] - public struct FloodSetComponentJob : IJobChunk where T : struct, IComponentData + public struct FloodSetComponentJob : IJobChunk where T : unmanaged, IComponentData { private ComponentTypeHandle m_TypeHandle; private readonly T m_Value; @@ -29,9 +30,14 @@ public FloodSetComponentJob(ComponentTypeHandle typeHandle, T value) m_Value = value; } - public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) + public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) { - UnsafeCollectionUtil.FloodSetBuffer(chunk.GetComponentDataPtrRW(ref m_TypeHandle), 0, chunk.Count, m_Value); + NativeArray array = chunk.GetNativeArray(ref m_TypeHandle); + ChunkEntityEnumerator enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count); + while (enumerator.NextEntityIndex(out int index)) + { + array[index] = m_Value; + } } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Job/MemsetBufferJob.cs b/Scripts/Runtime/Entities/Job/MemsetBufferJob.cs index 83225ec7..4fb6bbda 100644 --- a/Scripts/Runtime/Entities/Job/MemsetBufferJob.cs +++ b/Scripts/Runtime/Entities/Job/MemsetBufferJob.cs @@ -15,7 +15,7 @@ namespace Anvil.Unity.DOTS.Entities /// The compliment to . //TODO: #133 - Profile vs NativeArrayExtension.FloodSet. This probably isn't faster than FloodSetting in a job. [BurstCompile] - public struct MemsetBufferJob : IJobParallelForBatch where T : struct, IBufferElementData + public struct MemsetBufferJob : IJobParallelForBatch where T : unmanaged, IBufferElementData { // The minimum number of elements to process in a single batch. // Attempts to keep batch sizes large enough to prevent multiple cores from copying the same diff --git a/Scripts/Runtime/Entities/Lifecycle/AbstractEntityLifecycleStatusSystem.cs b/Scripts/Runtime/Entities/Lifecycle/AbstractEntityLifecycleStatusSystem.cs index be5722ae..f92c9314 100644 --- a/Scripts/Runtime/Entities/Lifecycle/AbstractEntityLifecycleStatusSystem.cs +++ b/Scripts/Runtime/Entities/Lifecycle/AbstractEntityLifecycleStatusSystem.cs @@ -20,7 +20,6 @@ namespace Anvil.Unity.DOTS.Entities /// Entities that are in a "CleanUp" state can be treated as "Departures" before they are actually destroyed by /// Unity. This is the default behaviour. /// - [AlwaysUpdateSystem] public abstract partial class AbstractEntityLifecycleStatusSystem : AbstractAnvilSystemBase { private readonly List m_EntityLifecycleStatus; @@ -220,7 +219,7 @@ public JobHandle AcquireCreatedAndDestroyedEntities( if (shouldIncludeCleanupEntities) { - NativeArray cleanupEntities = m_CleanupEntityQuery.ToEntityArrayAsync(Allocator.TempJob, out JobHandle cleanupDependsOn); + NativeList cleanupEntities = m_CleanupEntityQuery.ToEntityListAsync(Allocator.TempJob, out JobHandle cleanupDependsOn); IncludeCleanupEntitiesJob includeCleanupEntitiesJob = new IncludeCleanupEntitiesJob( m_WorldCleanupEntities, @@ -255,13 +254,13 @@ private struct IncludeCleanupEntitiesJob : IJob private NativeParallelHashSet m_WorldCleanupEntities; private NativeList m_WorldDestroyedEntities; private NativeReference m_CleanupFrame; - [ReadOnly] private readonly NativeArray m_PendingCleanupEntities; + [ReadOnly] private readonly NativeList m_PendingCleanupEntities; private readonly int m_CurrentFrame; public IncludeCleanupEntitiesJob( NativeParallelHashSet worldCleanupEntities, NativeList worldDestroyedEntities, - NativeArray pendingCleanupEntities, + NativeList pendingCleanupEntities, NativeReference cleanupFrame, int currentFrame) { @@ -284,8 +283,8 @@ public void Execute() } } - //If we're on a new frame, we want to clear the cleanup entities. - //We could have multiple Lifecycle systems and we want the cleanup entities to be valid for the + //If we're on a new frame, we want to clear the cleanup entities. + //We could have multiple Lifecycle systems and we want the cleanup entities to be valid for the //entirety of the frame if (m_CurrentFrame != m_CleanupFrame.Value) { @@ -300,12 +299,14 @@ public void Execute() return; } + //Ensure we have enough space + m_WorldDestroyedEntities.SetCapacity(m_WorldDestroyedEntities.Length + m_PendingCleanupEntities.Length); //We'll add all the pending clean up entities to the destroyed list - m_WorldDestroyedEntities.AddRange(m_PendingCleanupEntities); + m_WorldDestroyedEntities.AddRangeNoResize(m_PendingCleanupEntities); //Now we'll go through all the entities that are going to be cleaned up later in the frame. m_WorldCleanupEntities.UnionWith(m_PendingCleanupEntities); } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Lifecycle/EntityLifecycleStatus.cs b/Scripts/Runtime/Entities/Lifecycle/EntityLifecycleStatus.cs index 03a36aa4..77354a4a 100644 --- a/Scripts/Runtime/Entities/Lifecycle/EntityLifecycleStatus.cs +++ b/Scripts/Runtime/Entities/Lifecycle/EntityLifecycleStatus.cs @@ -1,6 +1,7 @@ using Anvil.CSharp.Core; using Anvil.Unity.DOTS.Jobs; using Unity.Burst; +using Unity.Burst.Intrinsics; using Unity.Collections; using Unity.Entities; using Unity.Jobs; @@ -53,7 +54,13 @@ protected override void DisposeSelf() public void CreateQuery() { - m_Query = m_OwningSystem.GetEntityQuery(m_QueryComponentTypes); + EntityQueryDesc entityQueryDesc = new EntityQueryDesc + { + All = m_QueryComponentTypes, + Options = EntityQueryOptions.IncludeDisabledEntities | EntityQueryOptions.IgnoreComponentEnabledState + }; + + m_Query = m_OwningSystem.GetEntityQuery(entityQueryDesc); m_Query.SetOrderVersionFilter(); } @@ -227,7 +234,7 @@ public void Execute() [BurstCompile] - private struct UpdateArrivedJob : IJobEntityBatch + private struct UpdateArrivedJob : IJobChunk { [ReadOnly] private readonly EntityTypeHandle m_EntityTypeHandle; private NativeParallelHashSet m_Lookup; @@ -243,9 +250,11 @@ public UpdateArrivedJob( m_ArrivedEntities = arrivedEntities; } - public void Execute(ArchetypeChunk batchInChunk, int batchIndex) + public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) { - NativeArray entities = batchInChunk.GetNativeArray(m_EntityTypeHandle); + //We're deliberately not using the chunk filter here, because we want to know about all entities that + //have entered the world, regardless if they are disabled or not. + NativeArray entities = chunk.GetNativeArray(m_EntityTypeHandle); for (int i = 0; i < entities.Length; ++i) { diff --git a/Scripts/Runtime/Entities/Lifecycle/EntitySpawnSystem.cs b/Scripts/Runtime/Entities/Lifecycle/EntitySpawnSystem.cs index cfc19f27..e38dfa10 100644 --- a/Scripts/Runtime/Entities/Lifecycle/EntitySpawnSystem.cs +++ b/Scripts/Runtime/Entities/Lifecycle/EntitySpawnSystem.cs @@ -64,10 +64,10 @@ private int GetNextInstanceID() //instance id issued combo. //This way we don't run out of IDs when acquiring every frame but we also don't need to force the call site //to manage and store an ID. - + //TODO: https://github.com/decline-cookies/anvil-csharp-core/issues/147 // Change to a Pool instead. - + //If we have an ID free to use in the queue, just get it if (m_InstanceIDQueue.Count > 0) { @@ -84,7 +84,7 @@ protected override void OnCreate() Type type = GetType(); Type commandBufferSystemType = type.GetCustomAttribute().CommandBufferSystemType; - m_CommandBufferSystem = (EntityCommandBufferSystem)World.GetOrCreateSystem(commandBufferSystemType); + m_CommandBufferSystem = (EntityCommandBufferSystem)World.GetOrCreateSystemManaged(commandBufferSystemType); CreateArchetypeLookup(); } @@ -106,11 +106,6 @@ private void CreateArchetypeLookup() continue; } - if (definitionType.GetCustomAttribute() == null) - { - throw new InvalidOperationException($"Definition Type of {definitionType.GetReadableName()} should have the {nameof(BurstCompatibleAttribute)} set but it does not."); - } - if (definitionType.GetCustomAttribute() == null) { throw new InvalidOperationException($"Definition Type of {definitionType.GetReadableName()} should be readonly but it is not."); @@ -157,7 +152,7 @@ public void UnregisterEntityPrototypeForDefinition(bool //************************************************************************************************************* // SPAWN API - IN JOB //************************************************************************************************************* - + /// /// Acquires an for use in a job and returns the dependency to wait on. /// Must call with the dependency for the jobs that use this instance. @@ -183,7 +178,7 @@ public void ReleaseAsync(JobHandle releaseAccessDependency) m_CommandBufferSystem.AddJobHandleForProducer(releaseAccessDependency); } - + private EntitySpawner AcquireDeferred() { return AcquireSpawner(true, m_EntityPrototypes.Acquire(AccessType.SharedRead)); @@ -270,7 +265,7 @@ public void SpawnDeferred(NativeArray spawnDefinitions } ReleaseDeferred(entitySpawner); } - + /// /// Spawns an immediately with the given /// @@ -349,7 +344,7 @@ public NativeArray SpawnImmediate(NativeArray //************************************************************************************************************* // UPDATE //************************************************************************************************************* - + protected override void OnUpdate() { m_PendingReleaseSpawners.Clear(); @@ -417,4 +412,4 @@ public static EntitySpawner GetEntitySpawnerByID(EntitySpawner.SpawnerID spawner return entitySpawner; } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Lifecycle/JobInteraction/EntitySpawner.cs b/Scripts/Runtime/Entities/Lifecycle/JobInteraction/EntitySpawner.cs index c0f497dd..80f34564 100644 --- a/Scripts/Runtime/Entities/Lifecycle/JobInteraction/EntitySpawner.cs +++ b/Scripts/Runtime/Entities/Lifecycle/JobInteraction/EntitySpawner.cs @@ -12,7 +12,6 @@ namespace Anvil.Unity.DOTS.Entities /// Helper struct to allow for spawning and making associated structural and initialization /// changes while in parallel bursted jobs. /// - [BurstCompatible] public readonly struct EntitySpawner : IEquatable { public static bool operator ==(EntitySpawner lhs, EntitySpawner rhs) @@ -24,28 +23,28 @@ namespace Anvil.Unity.DOTS.Entities { return !(lhs == rhs); } - + private const int UNSET_THREAD_INDEX = -1; - + /// /// The to identify this instance globally in the application /// public readonly SpawnerID ID; - + /// /// The Thread Index this instance is operating on. /// [NativeSetThreadIndex] public readonly int ThreadIndex; - - + + [NativeDisableContainerSafetyRestriction] private readonly EntityCommandBuffer m_ECB; //TODO: #86 - Once we upgrade to Entities 1.0 we won't have to hide the ECB or ECB.ParallelWriter inside here - // and we can expose it or make two separate Spawner structs. One for parallel and one for single. + // and we can expose it or make two separate Spawner structs. One for parallel and one for single. [NativeDisableContainerSafetyRestriction] private readonly EntityCommandBuffer.ParallelWriter m_ECBWriter; [ReadOnly] private readonly NativeParallelHashMap m_ArchetypeLookup; [ReadOnly] private readonly NativeParallelHashMap m_PrototypeLookup; - - + + /// /// Returns whether the underlying is created or not. /// @@ -54,7 +53,7 @@ public bool IsECBCreated { get => m_ECB.IsCreated; } - + internal EntitySpawner( SpawnerID id, EntityCommandBuffer ecb, @@ -68,7 +67,7 @@ internal EntitySpawner( m_PrototypeLookup = prototypeLookup; ThreadIndex = UNSET_THREAD_INDEX; } - + /// /// Returns whether the underlying has been played back yet or not. /// @@ -127,14 +126,14 @@ public Entity SpawnDeferredEntityWithPrototype(TDefinition definiti //TODO: #86 - Remove once we upgrade to Entities 1.0 /// - /// A special managed function that is called by a function pointer to allow for use in Burst. + /// A special managed function that is called by a function pointer to allow for use in Burst. /// /// The to identify the spawner /// The thread index to use /// The to set the component on /// The /// The type of - public static void ManagedLookupAndSetSharedComponent(SpawnerID spawnerID, int threadIndex, Entity e, T component) where T : struct, ISharedComponentData + public static void ManagedLookupAndSetSharedComponent(SpawnerID spawnerID, int threadIndex, Entity e, T component) where T : unmanaged, ISharedComponentData { EntitySpawner entitySpawner = EntitySpawnSystem.GetEntitySpawnerByID(spawnerID); EntityCommandBuffer.ParallelWriter ecbParallelWriter = entitySpawner.m_ECBWriter; @@ -147,13 +146,13 @@ public static void ManagedLookupAndSetSharedComponent(SpawnerID spawnerID, in //************************************************************************************************************* /// - public void SetComponent(Entity e, T component) where T : struct, IComponentData + public void SetComponent(Entity e, T component) where T : unmanaged, IComponentData { m_ECBWriter.SetComponent(ID.InstanceID, e, component); } /// - public DynamicBuffer SetBuffer(Entity e) where T : struct, IBufferElementData + public DynamicBuffer SetBuffer(Entity e) where T : unmanaged, IBufferElementData { return m_ECBWriter.SetBuffer(ID.InstanceID, e); } @@ -165,19 +164,19 @@ public void AppendToBuffer(Entity e, T element) where T : struct, IBufferElem } /// - public void AddComponent(Entity e) where T : struct, IComponentData + public void AddComponent(Entity e) where T : unmanaged, IComponentData { m_ECBWriter.AddComponent(ID.InstanceID, e); } /// - public void AddComponent(Entity e, T component) where T : struct, IComponentData + public void AddComponent(Entity e, T component) where T : unmanaged, IComponentData { m_ECBWriter.AddComponent(ID.InstanceID, e, component); } /// - public void AddComponent(Entity e, ComponentTypes componentTypes) + public void AddComponent(Entity e, ComponentTypeSet componentTypes) { m_ECBWriter.AddComponent(ID.InstanceID, e, componentTypes); } @@ -253,11 +252,11 @@ internal Entity GetPrototypeEntityForDefinition(int hash) Debug_EnsurePrototypeIsRegistered(hash); return m_PrototypeLookup[hash]; } - + //************************************************************************************************************* // IEQUATABLE //************************************************************************************************************* - + public bool Equals(EntitySpawner other) { return this == other; @@ -294,7 +293,7 @@ private void Debug_EnsurePrototypeIsRegistered(int hash) throw new InvalidOperationException($"Tried to get the Prototype Entity but it wasn't in the lookup! Did you call {nameof(EntitySpawnSystem.UnregisterEntityPrototypeForDefinition)}?"); } } - + //************************************************************************************************************* // ID //************************************************************************************************************* @@ -313,17 +312,17 @@ private void Debug_EnsurePrototypeIsRegistered(int hash) { return !(lhs == rhs); } - + /// /// The ID of the that owns this /// public readonly uint OwningSystemID; - + /// /// The ID of the /// public readonly int InstanceID; - + public SpawnerID(uint owningSystemID, int instanceID) { OwningSystemID = owningSystemID; @@ -351,4 +350,4 @@ public override string ToString() } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationExtension.cs b/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationExtension.cs index b25859a6..9fe65888 100644 --- a/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationExtension.cs +++ b/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationExtension.cs @@ -21,14 +21,14 @@ public static class EntityWorldMigrationExtension /// This will then handle notifying all s to have the chance to respond with /// custom migration work. /// NOTE: Use this instead of in order for migration callbacks - /// to occur in non IComponentData + /// to occur in non IComponentData /// /// The source 's Entity Manager /// The to move Entities to. /// The to select the Entities to migrate. public static void MoveEntitiesAndMigratableDataTo(this EntityManager srcEntityManager, World destinationWorld, EntityQuery entitiesToMigrateQuery) { - EntityWorldMigrationSystem entityWorldMigrationSystem = srcEntityManager.World.GetOrCreateSystem(); + EntityWorldMigrationSystem entityWorldMigrationSystem = srcEntityManager.World.GetOrCreateSystemManaged(); entityWorldMigrationSystem.MoveEntitiesAndMigratableDataTo(destinationWorld, entitiesToMigrateQuery); } @@ -46,7 +46,6 @@ public static void MoveEntitiesAndMigratableDataTo(this EntityManager srcEntityM /// true if this entity was moved to the new world and remaps to a new entity. /// false if this entity did not move and stayed in this world. /// - [BurstCompatible] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetRemappedEntity( this Entity currentEntity, @@ -68,7 +67,6 @@ public static bool TryGetRemappedEntity( /// /// Occurs if this type was not registered via /// - [BurstCompatible] public static unsafe void PatchEntityReferences(this ref T instance, ref NativeArray remapArray) where T : struct { @@ -102,4 +100,4 @@ public static unsafe void PatchEntityReferences(this ref T instance, ref Nati } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationSystem.cs b/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationSystem.cs index 58a05917..c66ed063 100644 --- a/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationSystem.cs +++ b/Scripts/Runtime/Entities/Lifecycle/Migration/EntityWorldMigrationSystem.cs @@ -20,7 +20,7 @@ namespace Anvil.Unity.DOTS.Entities /// NOTE: Use on this System instead of directly interfacing with /// /// - public class EntityWorldMigrationSystem : AbstractDataSystem + public partial class EntityWorldMigrationSystem : AbstractDataSystem { private readonly HashSet m_MigrationObservers; @@ -105,6 +105,7 @@ private JobHandle NotifyObserversOfMigrateTo(World destinationWorld, ref NativeA private static NativeList s_EntityOffsetList = new NativeList(32, Allocator.Persistent); private static NativeList s_BlobAssetRefOffsetList = new NativeList(32, Allocator.Persistent); private static NativeList s_WeakAssetRefOffsetList = new NativeList(32, Allocator.Persistent); + private static readonly HashSet s_TypeCache = new HashSet(); private static bool s_AppDomainUnloadRegistered; @@ -121,6 +122,7 @@ private static void Init() AppDomain.CurrentDomain.DomainUnload += CurrentDomain_OnDomainUnload; s_AppDomainUnloadRegistered = true; + s_TypeCache.Clear(); SharedTypeOffsetInfo.REF.Data = s_TypeOffsetsLookup; UpdateSharedStatics(); } @@ -178,7 +180,7 @@ public static void RegisterForEntityPatching(Type type) { throw new InvalidOperationException($"Type {type.GetReadableName()} must be a value type in order to register for Entity Patching."); } - + ScanForCollections(string.Empty, type); long typeHash = BurstRuntime.GetHashCode64(type); @@ -199,11 +201,12 @@ public static void RegisterForEntityPatching(Type type) out bool hasWeakAssetRefs, ref s_EntityOffsetList, ref s_BlobAssetRefOffsetList, - ref s_WeakAssetRefOffsetList); + ref s_WeakAssetRefOffsetList, + s_TypeCache); //Unity gives us back Blob Asset Refs and Weak Asset Refs as well but for now we're ignoring them. - //When the time comes to use those and do remapping with them, we'll need to add that info here along + //When the time comes to use those and do remapping with them, we'll need to add that info here along //with the utils to actually do the remapping s_TypeOffsetsLookup.Add( typeHash, @@ -215,7 +218,7 @@ public static void RegisterForEntityPatching(Type type) //our shared statics UpdateSharedStatics(); } - + //TODO: #233 - This likely won't be a safety function when fully implemented as we'll need to store the type offsets for patching [Conditional("ANVIL_DEBUG_SAFETY")] private static void ScanForCollections(string parentPathString, Type type) @@ -292,4 +295,4 @@ internal sealed class SharedWeakAssetRefInfo public static readonly SharedStatic REF = SharedStatic.GetOrCreate(); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/ManagedReference/ManagedReferenceExtension.cs b/Scripts/Runtime/Entities/ManagedReference/ManagedReferenceExtension.cs index 91239bbd..bcba4cc0 100644 --- a/Scripts/Runtime/Entities/ManagedReference/ManagedReferenceExtension.cs +++ b/Scripts/Runtime/Entities/ManagedReference/ManagedReferenceExtension.cs @@ -82,14 +82,14 @@ private static void DEBUG_AssertInstanceMatchesRef(EntityManager entityManage /// Requires that a singleton instance reference exists for a /// to update. /// This is the equivalent of - /// . + /// . /// /// The system to add the requirement too. /// The type of the managed instance. public static void RequireManagedSingletonForUpdate(this ComponentSystemBase system) where T : class, IComponentReferencable { - system.RequireSingletonForUpdate>(); + system.RequireForUpdate>(); } /// @@ -102,7 +102,10 @@ public static void RequireManagedSingletonForUpdate(this ComponentSystemBase /// The managed instance. public static T GetManagedSingleton(this ComponentSystemBase system) where T : class, IComponentReferencable { + //TODO: #296 - This function will be obsolete post 1.0 +#pragma warning disable CS0618 // Type or member is obsolete return system.GetSingleton>().Resolve(); +#pragma warning restore CS0618 // Type or member is obsolete } /// @@ -114,7 +117,10 @@ public static T GetManagedSingleton(this ComponentSystemBase system) where T /// True if a singleton of the managed type exists. public static bool HasManagedSingleton(this ComponentSystemBase system) where T : class, IComponentReferencable { + //TODO: #296 - This function will be obsolete post 1.0 +#pragma warning disable CS0618 // Type or member is obsolete return system.HasSingleton>(); +#pragma warning restore CS0618 // Type or member is obsolete } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IDriverEntityPersistentData.cs b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IDriverEntityPersistentData.cs index c573c8de..521276d3 100644 --- a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IDriverEntityPersistentData.cs +++ b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IDriverEntityPersistentData.cs @@ -10,7 +10,7 @@ namespace Anvil.Unity.DOTS.Entities /// /// The type of public interface IDriverEntityPersistentData : IEntityPersistentData - where T : struct, IEntityPersistentDataInstance + where T : unmanaged, IEntityPersistentDataInstance { } } diff --git a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IEntityPersistentData.cs b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IEntityPersistentData.cs index ba5fcfdf..03d01c0f 100644 --- a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IEntityPersistentData.cs +++ b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IEntityPersistentData.cs @@ -15,5 +15,5 @@ public interface IEntityPersistentData : IAbstractPersistentData, IReadOnlyEntityPersistentData, ISharedWriteAccessControlledValue>, IExclusiveWriteAccessControlledValue> - where T : struct, IEntityPersistentDataInstance { } + where T : unmanaged, IEntityPersistentDataInstance { } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IReadOnlyEntityPersistentData.cs b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IReadOnlyEntityPersistentData.cs index 4d97a28c..ad82bd44 100644 --- a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IReadOnlyEntityPersistentData.cs +++ b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IReadOnlyEntityPersistentData.cs @@ -12,5 +12,5 @@ namespace Anvil.Unity.DOTS.Entities /// The type of public interface IReadOnlyEntityPersistentData : IAbstractPersistentData, IReadAccessControlledValue> - where T : struct, IEntityPersistentDataInstance { } + where T : unmanaged, IEntityPersistentDataInstance { } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/PersistentData/Data/Interface/ISystemEntityPersistentData.cs b/Scripts/Runtime/Entities/PersistentData/Data/Interface/ISystemEntityPersistentData.cs index 1a095a6c..66998b19 100644 --- a/Scripts/Runtime/Entities/PersistentData/Data/Interface/ISystemEntityPersistentData.cs +++ b/Scripts/Runtime/Entities/PersistentData/Data/Interface/ISystemEntityPersistentData.cs @@ -9,7 +9,7 @@ namespace Anvil.Unity.DOTS.Entities /// /// The type of public interface ISystemEntityPersistentData : IEntityPersistentData - where T : struct, IEntityPersistentDataInstance + where T : unmanaged, IEntityPersistentDataInstance { } diff --git a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IWorldEntityPersistentData.cs b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IWorldEntityPersistentData.cs index 0a77251f..291d12a5 100644 --- a/Scripts/Runtime/Entities/PersistentData/Data/Interface/IWorldEntityPersistentData.cs +++ b/Scripts/Runtime/Entities/PersistentData/Data/Interface/IWorldEntityPersistentData.cs @@ -8,7 +8,7 @@ namespace Anvil.Unity.DOTS.Entities /// /// The type of public interface IWorldEntityPersistentData : IEntityPersistentData - where T : struct, IEntityPersistentDataInstance + where T : unmanaged, IEntityPersistentDataInstance { } diff --git a/Scripts/Runtime/Entities/PersistentData/PersistentDataSystem.cs b/Scripts/Runtime/Entities/PersistentData/PersistentDataSystem.cs index 8b753419..6c3e47db 100644 --- a/Scripts/Runtime/Entities/PersistentData/PersistentDataSystem.cs +++ b/Scripts/Runtime/Entities/PersistentData/PersistentDataSystem.cs @@ -32,7 +32,7 @@ public PersistentDataSystem() protected override void OnCreate() { base.OnCreate(); - m_EntityWorldMigrationSystem = World.GetOrCreateSystem(); + m_EntityWorldMigrationSystem = World.GetOrCreateSystemManaged(); m_EntityWorldMigrationSystem.RegisterMigrationObserver(this); } @@ -115,7 +115,7 @@ private ThreadPersistentData CreateThreadPersistentDataInstance(IDataOwner JobHandle IEntityWorldMigrationObserver.MigrateTo(JobHandle dependsOn, World destinationWorld, ref NativeArray remapArray) { - PersistentDataSystem destinationPersistentDataSystem = destinationWorld.GetOrCreateSystem(); + PersistentDataSystem destinationPersistentDataSystem = destinationWorld.GetOrCreateSystemManaged(); Debug_EnsureOtherWorldPersistentDataSystemExists(destinationWorld, destinationPersistentDataSystem); NativeArray migrationDependencies = new NativeArray(m_EntityPersistentData.Count, Allocator.Temp); diff --git a/Scripts/Runtime/Entities/TaskDriver/AbstractTaskDriver.cs b/Scripts/Runtime/Entities/TaskDriver/AbstractTaskDriver.cs index d4d8a6c1..9fe30b61 100644 --- a/Scripts/Runtime/Entities/TaskDriver/AbstractTaskDriver.cs +++ b/Scripts/Runtime/Entities/TaskDriver/AbstractTaskDriver.cs @@ -25,6 +25,8 @@ public abstract class AbstractTaskDriver : AbstractAnvilBase, ITaskSetOwner { private static readonly Type TASK_DRIVER_SYSTEM_TYPE = typeof(TaskDriverSystem<>); private static readonly Type COMPONENT_SYSTEM_GROUP_TYPE = typeof(ComponentSystemGroup); + private static readonly Type WORLD_TYPE = typeof(World); + private static readonly MethodInfo ADD_SYSTEM_MANAGED_METHOD_INFO = WORLD_TYPE.GetMethod("AddSystemManaged", BindingFlags.Instance | BindingFlags.Public); private readonly PersistentDataSystem m_PersistentDataSystem; private readonly List m_SubTaskDrivers; @@ -133,8 +135,8 @@ protected AbstractTaskDriver(World world, AbstractTaskDriver parent = null, stri Parent?.m_SubTaskDrivers.Add(this); WorldUniqueID = GenerateWorldUniqueID(uniqueContextIdentifier); - TaskDriverManagementSystem taskDriverManagementSystem = World.GetOrCreateSystem(); - m_PersistentDataSystem = World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = World.GetOrCreateSystemManaged(); + m_PersistentDataSystem = World.GetOrCreateSystemManaged(); m_SubTaskDrivers = new List(); TaskSet = new TaskSet(this); @@ -148,12 +150,13 @@ protected AbstractTaskDriver(World world, AbstractTaskDriver parent = null, stri //If we've already created a TaskDriver of this type, then it's corresponding system will also have been created. - TaskDriverSystem = (AbstractTaskDriverSystem)World.GetExistingSystem(customSystemType); + TaskDriverSystem = (AbstractTaskDriverSystem)World.GetExistingSystemManaged(customSystemType); //If not, then we will want to explicitly create it and ensure it is part of the lifecycle. if (TaskDriverSystem == null) { TaskDriverSystem = (AbstractTaskDriverSystem)Activator.CreateInstance(customSystemType, World); - World.AddSystem(TaskDriverSystem); + MethodInfo customAddSystemManagedMethodInfo = ADD_SYSTEM_MANAGED_METHOD_INFO.MakeGenericMethod(customSystemType); + customAddSystemManagedMethodInfo.Invoke(World, new object[] { TaskDriverSystem }); ComponentSystemGroup systemGroup = GetSystemGroup(); systemGroup.AddSystemToUpdateList(TaskDriverSystem); } @@ -192,7 +195,7 @@ private ComponentSystemGroup GetSystemGroup() throw new InvalidOperationException($"Tried to get the {COMPONENT_SYSTEM_GROUP_TYPE.GetReadableName()} for {this} but {systemGroupType.GetReadableName()} is not a valid group type!"); } - return (ComponentSystemGroup)World.GetOrCreateSystem(systemGroupType); + return (ComponentSystemGroup)World.GetOrCreateSystemManaged(systemGroupType); } private Type GetSystemGroupType() @@ -381,4 +384,4 @@ private void Debug_EnsureHardened() } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskDriverManagementSystem.cs b/Scripts/Runtime/Entities/TaskDriver/TaskDriverManagementSystem.cs index b9fe528e..bbcc8cad 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskDriverManagementSystem.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskDriverManagementSystem.cs @@ -63,7 +63,7 @@ private DataOwnerID GenerateWorldUniqueID() protected override void OnCreate() { base.OnCreate(); - EntityWorldMigrationSystem entityWorldMigrationSystem = World.GetOrCreateSystem(); + EntityWorldMigrationSystem entityWorldMigrationSystem = World.GetOrCreateSystemManaged(); entityWorldMigrationSystem.RegisterMigrationObserver(this); } @@ -314,7 +314,7 @@ protected sealed override void OnUpdate() JobHandle IEntityWorldMigrationObserver.MigrateTo(JobHandle dependsOn, World destinationWorld, ref NativeArray remapArray) { - TaskDriverManagementSystem destinationTaskDriverManagementSystem = destinationWorld.GetOrCreateSystem(); + TaskDriverManagementSystem destinationTaskDriverManagementSystem = destinationWorld.GetOrCreateSystemManaged(); Debug_EnsureOtherWorldTaskDriverManagementSystemExists(destinationWorld, destinationTaskDriverManagementSystem); return m_TaskDriverMigrationData.MigrateTo( diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractJobConfig.cs index 61bc5019..d34accf2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractJobConfig.cs @@ -65,7 +65,7 @@ protected AbstractJobConfig(ITaskSetOwner taskSetOwner) { IsEnabled = true; TaskSetOwner = taskSetOwner; - m_PersistentDataSystem = TaskSetOwner.World.GetOrCreateSystem(); + m_PersistentDataSystem = TaskSetOwner.World.GetOrCreateSystemManaged(); m_AccessWrappers = new Dictionary(); m_SchedulingAccessWrappers = new List(); @@ -259,26 +259,26 @@ public IJobConfig RequireEntityPersistentDataForExclusiveWrite(IEntityPer /// public IJobConfig RequireEntityNativeArrayFromQueryForRead(EntityQuery entityQuery) { - return RequireEntityNativeArrayFromQueryForRead(new EntityQueryNativeArray(entityQuery)); + return RequireEntityNativeArrayFromQueryForRead(new EntityQueryNativeList(entityQuery)); } /// public IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQuery entityQuery) - where T : struct, IComponentData + where T : unmanaged, IComponentData { - return RequireIComponentDataNativeArrayFromQueryForRead(new EntityQueryComponentNativeArray(entityQuery)); + return RequireIComponentDataNativeArrayFromQueryForRead(new EntityQueryComponentNativeList(entityQuery)); } - protected IJobConfig RequireEntityNativeArrayFromQueryForRead(EntityQueryNativeArray entityQueryNativeArray) + protected IJobConfig RequireEntityNativeArrayFromQueryForRead(EntityQueryNativeList entityQueryNativeList) { - AddAccessWrapper(new EntityQueryAccessWrapper(entityQueryNativeArray, Usage.Default)); + AddAccessWrapper(new EntityQueryAccessWrapper(entityQueryNativeList, Usage.Default)); return this; } - protected IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQueryComponentNativeArray entityQueryNativeArray) - where T : struct, IComponentData + protected IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQueryComponentNativeList entityQueryNativeList) + where T : unmanaged, IComponentData { - AddAccessWrapper(new EntityQueryComponentAccessWrapper(entityQueryNativeArray, Usage.Default)); + AddAccessWrapper(new EntityQueryComponentAccessWrapper(entityQueryNativeList, Usage.Default)); return this; } @@ -308,26 +308,26 @@ public IJobConfig RequireEntitySpawner(EntitySpawnSystem entitySpawnSystem) //************************************************************************************************************* - // CONFIGURATION - REQUIRED DATA - ComponentDataFromEntity (CDFE) + // CONFIGURATION - REQUIRED DATA - ComponentLookup (CDFE) //************************************************************************************************************* //TODO: #86 - Revisit this section after Entities 1.0 upgrade for name changes to CDFE /// - public IJobConfig RequireCDFEForRead() where T : struct, IComponentData + public IJobConfig RequireCDFEForRead() where T : unmanaged, IComponentData { AddAccessWrapper(new CDFEAccessWrapper(AccessType.SharedRead, Usage.Default, TaskSetOwner.TaskDriverSystem)); return this; } /// - public IJobConfig RequireCDFEForSystemSharedWrite() where T : struct, IComponentData + public IJobConfig RequireCDFEForSystemSharedWrite() where T : unmanaged, IComponentData { AddAccessWrapper(new CDFEAccessWrapper(AccessType.SharedWrite, Usage.Default, TaskSetOwner.TaskDriverSystem)); return this; } /// - public IJobConfig RequireCDFEForExclusiveWrite() where T : struct, IComponentData + public IJobConfig RequireCDFEForExclusiveWrite() where T : unmanaged, IComponentData { AddAccessWrapper(new CDFEAccessWrapper(AccessType.ExclusiveWrite, Usage.Default, TaskSetOwner.TaskDriverSystem)); return this; @@ -339,7 +339,7 @@ public IJobConfig RequireCDFEForExclusiveWrite() where T : struct, IComponent //************************************************************************************************************* /// - public IJobConfig RequireDBFEForRead() where T : struct, IBufferElementData + public IJobConfig RequireDBFEForRead() where T : unmanaged, IBufferElementData { AddAccessWrapper(new DynamicBufferAccessWrapper(AccessType.SharedRead, Usage.Default, TaskSetOwner.TaskDriverSystem)); @@ -347,14 +347,14 @@ public IJobConfig RequireDBFEForRead() where T : struct, IBufferElementData } /// - public IJobConfig RequireDBFEForSystemSharedWrite() where T : struct, IBufferElementData + public IJobConfig RequireDBFEForSystemSharedWrite() where T : unmanaged, IBufferElementData { AddAccessWrapper(new DynamicBufferAccessWrapper(AccessType.SharedWrite, Usage.Default, TaskSetOwner.TaskDriverSystem)); return this; } /// - public IJobConfig RequireDBFEForExclusiveWrite() where T : struct, IBufferElementData + public IJobConfig RequireDBFEForExclusiveWrite() where T : unmanaged, IBufferElementData { AddAccessWrapper(new DynamicBufferAccessWrapper(AccessType.ExclusiveWrite, Usage.Default, TaskSetOwner.TaskDriverSystem)); return this; @@ -575,46 +575,46 @@ PersistentDataAccessWrapper> persistentDataAccessWra instance = persistentDataAccessWrapper.PersistentData; } - internal NativeArray GetEntityNativeArrayFromQuery() + internal NativeList GetEntityNativeListFromQuery() { EntityQueryAccessWrapper entityQueryAccessWrapper = GetAccessWrapper(Usage.Default); - return entityQueryAccessWrapper.NativeArray; + return entityQueryAccessWrapper.NativeList; } - internal NativeArray GetIComponentDataNativeArrayFromQuery() - where T : struct, IComponentData + internal NativeList GetIComponentDataNativeListFromQuery() + where T : unmanaged, IComponentData { EntityQueryComponentAccessWrapper entityQueryAccessWrapper = GetAccessWrapper>(Usage.Default); - return entityQueryAccessWrapper.NativeArray; + return entityQueryAccessWrapper.NativeList; } internal void Fulfill(out CDFEReader instance) - where T : struct, IComponentData + where T : unmanaged, IComponentData { CDFEAccessWrapper cdfeAccessWrapper = GetAccessWrapper>(Usage.Default); instance = cdfeAccessWrapper.CreateCDFEReader(); } internal void Fulfill(out CDFEWriter instance) - where T : struct, IComponentData + where T : unmanaged, IComponentData { CDFEAccessWrapper cdfeAccessWrapper = GetAccessWrapper>(Usage.Default); instance = cdfeAccessWrapper.CreateCDFEUpdater(); } internal void Fulfill(out DBFEForRead instance) - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { DynamicBufferAccessWrapper dynamicBufferAccessWrapper = GetAccessWrapper>(Usage.Default); instance = dynamicBufferAccessWrapper.CreateDynamicBufferReader(); } internal void Fulfill(out DBFEForExclusiveWrite instance) - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { DynamicBufferAccessWrapper dynamicBufferAccessWrapper = GetAccessWrapper>(Usage.Default); instance = dynamicBufferAccessWrapper.CreateDynamicBufferExclusiveWriter(); diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractResolvableJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractResolvableJobConfig.cs index 94e5e691..525b98fc 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractResolvableJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/AbstractResolvableJobConfig.cs @@ -37,7 +37,7 @@ protected override void DisposeSelf() public unsafe IResolvableJobConfigRequirements RequireResolveTarget() where TResolveTargetType : unmanaged, IEntityKeyedTask { - TaskDriverManagementSystem taskDriverManagementSystem = TaskSetOwner.World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = TaskSetOwner.World.GetOrCreateSystemManaged(); EntityProxyDataSource dataSource = taskDriverManagementSystem.GetOrCreateEntityProxyDataSource(); m_ResolveTargetDefinitions.Add(ResolveTargetDefinition.Create(dataSource.PendingWriterPointer)); diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryComponentJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryComponentJobConfig.cs index 0de48c49..9784610f 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryComponentJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryComponentJobConfig.cs @@ -2,12 +2,12 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - internal class EntityQueryComponentJobConfig : AbstractJobConfig where T : struct, IComponentData + internal class EntityQueryComponentJobConfig : AbstractJobConfig where T : unmanaged, IComponentData { - public EntityQueryComponentJobConfig(ITaskSetOwner taskSetOwner, EntityQueryComponentNativeArray entityQueryComponentNativeArray) + public EntityQueryComponentJobConfig(ITaskSetOwner taskSetOwner, EntityQueryComponentNativeList entityQueryComponentNativeList) : base(taskSetOwner) { - RequireIComponentDataNativeArrayFromQueryForRead(entityQueryComponentNativeArray); + RequireIComponentDataNativeArrayFromQueryForRead(entityQueryComponentNativeList); } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryJobConfig.cs index d1c90756..30cd8929 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/EntityQueryJobConfig.cs @@ -2,10 +2,10 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { internal class EntityQueryJobConfig : AbstractJobConfig { - public EntityQueryJobConfig(ITaskSetOwner taskSetOwner, EntityQueryNativeArray entityQueryNativeArray) + public EntityQueryJobConfig(ITaskSetOwner taskSetOwner, EntityQueryNativeList entityQueryNativeList) : base(taskSetOwner) { - RequireEntityNativeArrayFromQueryForRead(entityQueryNativeArray); + RequireEntityNativeArrayFromQueryForRead(entityQueryNativeList); } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/Interface/IJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/Interface/IJobConfig.cs index 6efb14c8..a24e1ed9 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/Interface/IJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/Interface/IJobConfig.cs @@ -174,7 +174,7 @@ public IJobConfig RequireEntityPersistentDataForExclusiveWrite(IEntityPer /// /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQuery entityQuery) - where T : struct, IComponentData; + where T : unmanaged, IComponentData; //************************************************************************************************************* @@ -202,33 +202,33 @@ public IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQuer //************************************************************************************************************* - // CONFIGURATION - REQUIRED DATA - ComponentDataFromEntity (CDFE) + // CONFIGURATION - REQUIRED DATA - ComponentLookup (CDFE) //************************************************************************************************************* /// - /// Specifies a to be read from in a shared-read context. + /// Specifies a to be read from in a shared-read context. /// /// The type of in the CDFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireCDFEForRead() - where T : struct, IComponentData; + where T : unmanaged, IComponentData; /// - /// Specifies a to be written to in a system scoped shared-write context. + /// Specifies a to be written to in a system scoped shared-write context. /// This means that write access is shared between all Task Driver instances of the same type in the same . /// /// The type of in the CDFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireCDFEForSystemSharedWrite() - where T : struct, IComponentData; + where T : unmanaged, IComponentData; /// - /// Specifies a to be written to in an exclusive write context. + /// Specifies a to be written to in an exclusive write context. /// /// The type of in the CDFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireCDFEForExclusiveWrite() - where T : struct, IComponentData; + where T : unmanaged, IComponentData; //************************************************************************************************************* @@ -236,29 +236,29 @@ public IJobConfig RequireCDFEForExclusiveWrite() //************************************************************************************************************* /// - /// Specifies a to be read from in a shared-read context. + /// Specifies a to be read from in a shared-read context. /// /// The type of in the DBFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireDBFEForRead() - where T : struct, IBufferElementData; + where T : unmanaged, IBufferElementData; /// - /// Specifies a to be written to in a system scoped shared-write context. + /// Specifies a to be written to in a system scoped shared-write context. /// This means that write access is shared between all Task Driver instances of the same type in the same . /// /// The type of in the DBFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireDBFEForSystemSharedWrite() - where T : struct, IBufferElementData; + where T : unmanaged, IBufferElementData; /// - /// Specifies a to be written to in an exclusive-write context. + /// Specifies a to be written to in an exclusive-write context. /// /// The type of in the DBFE. /// A reference to itself to continue chaining configuration methods. public IJobConfig RequireDBFEForExclusiveWrite() - where T : struct, IBufferElementData; + where T : unmanaged, IBufferElementData; //************************************************************************************************************* diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/NoOpJobConfig.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/NoOpJobConfig.cs index d6dfb8fc..5b64d53f 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/NoOpJobConfig.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfig/NoOpJobConfig.cs @@ -92,7 +92,7 @@ public IJobConfig RequireEntityNativeArrayFromQueryForRead(EntityQuery entityQue } public IJobConfig RequireIComponentDataNativeArrayFromQueryForRead(EntityQuery entityQuery) - where T : struct, IComponentData + where T : unmanaged, IComponentData { return this; } @@ -111,38 +111,38 @@ public IJobConfig RequireEntitySpawner(EntitySpawnSystem entitySpawnSystem) public IJobConfig RequireCDFEForRead() - where T : struct, IComponentData + where T : unmanaged, IComponentData { return this; } public IJobConfig RequireCDFEForSystemSharedWrite() - where T : struct, IComponentData + where T : unmanaged, IComponentData { return this; } public IJobConfig RequireCDFEForExclusiveWrite() - where T : struct, IComponentData + where T : unmanaged, IComponentData { return this; } public IJobConfig RequireDBFEForRead() - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { return this; } public IJobConfig RequireDBFEForSystemSharedWrite() - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { return this; } public IJobConfig RequireDBFEForExclusiveWrite() - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { return this; } diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfigFactory.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfigFactory.cs index c389b0de..52d057ef 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfigFactory.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobConfigFactory.cs @@ -78,15 +78,15 @@ public static EntityQueryJobConfig CreateEntityQueryJobConfig( JobConfigScheduleDelegates.ScheduleEntityQueryJobDelegate scheduleJobFunction, BatchStrategy batchStrategy) { - EntityQueryNativeArray entityQueryNativeArray = new EntityQueryNativeArray(entityQuery); + EntityQueryNativeList entityQueryNativeList = new EntityQueryNativeList(entityQuery); - EntityQueryJobConfig jobConfig = new EntityQueryJobConfig(taskSetOwner, entityQueryNativeArray); + EntityQueryJobConfig jobConfig = new EntityQueryJobConfig(taskSetOwner, entityQueryNativeList); EntityQueryJobData jobData = new EntityQueryJobData(jobConfig); EntityQueryScheduleInfo scheduleInfo = new EntityQueryScheduleInfo( jobData, - entityQueryNativeArray, + entityQueryNativeList, batchStrategy, scheduleJobFunction); @@ -98,19 +98,19 @@ public static EntityQueryComponentJobConfig CreateEntityQueryComponentJobConf EntityQuery entityQuery, JobConfigScheduleDelegates.ScheduleEntityQueryComponentJobDelegate scheduleJobFunction, BatchStrategy batchStrategy) - where T : struct, IComponentData + where T : unmanaged, IComponentData { - EntityQueryComponentNativeArray entityQueryComponentNativeArray = new EntityQueryComponentNativeArray(entityQuery); + EntityQueryComponentNativeList entityQueryComponentNativeList = new EntityQueryComponentNativeList(entityQuery); EntityQueryComponentJobConfig jobConfig = new EntityQueryComponentJobConfig( taskSetOwner, - entityQueryComponentNativeArray); + entityQueryComponentNativeList); EntityQueryComponentJobData jobData = new EntityQueryComponentJobData(jobConfig); EntityQueryComponentScheduleInfo scheduleInfo = new EntityQueryComponentScheduleInfo( jobData, - entityQueryComponentNativeArray, + entityQueryComponentNativeList, batchStrategy, scheduleJobFunction); diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/AbstractJobData.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/AbstractJobData.cs index f74b7cfd..77d95b12 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/AbstractJobData.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/AbstractJobData.cs @@ -145,9 +145,9 @@ public void Fulfill(out EntityPersistentDataWriter instance) /// Gets a to read from in a job from an /// /// The - public NativeArray GetEntityNativeArrayFromQuery() + public NativeList GetEntityNativeListFromQuery() { - return m_JobConfig.GetEntityNativeArrayFromQuery(); + return m_JobConfig.GetEntityNativeListFromQuery(); } /// @@ -155,10 +155,10 @@ public NativeArray GetEntityNativeArrayFromQuery() /// /// The type of in the array. /// The - public NativeArray GetIComponentDataNativeArrayFromQuery() - where T : struct, IComponentData + public NativeList GetIComponentDataNativeListFromQuery() + where T : unmanaged, IComponentData { - return m_JobConfig.GetIComponentDataNativeArrayFromQuery(); + return m_JobConfig.GetIComponentDataNativeListFromQuery(); } //************************************************************************************************************* @@ -170,7 +170,7 @@ public NativeArray GetIComponentDataNativeArrayFromQuery() /// Fulfills an instance of the provided type for the job. /// public void Fulfill(out CDFEReader instance) - where T : struct, IComponentData + where T : unmanaged, IComponentData { m_JobConfig.Fulfill(out instance); } @@ -179,7 +179,7 @@ public void Fulfill(out CDFEReader instance) /// Fulfills an instance of the provided type for the job. /// public void Fulfill(out CDFEWriter instance) - where T : struct, IComponentData + where T : unmanaged, IComponentData { m_JobConfig.Fulfill(out instance); } @@ -188,7 +188,7 @@ public void Fulfill(out CDFEWriter instance) /// Fulfills an instance of the provided type for the job. /// public void Fulfill(out DBFEForRead instance) - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { m_JobConfig.Fulfill(out instance); } @@ -197,7 +197,7 @@ public void Fulfill(out DBFEForRead instance) /// Fulfills an instance of the provided type for the job. /// public void Fulfill(out DBFEForExclusiveWrite instance) - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { m_JobConfig.Fulfill(out instance); } diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/CancelJobData.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/CancelJobData.cs index f17af6d8..01af0fd0 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/CancelJobData.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/CancelJobData.cs @@ -20,13 +20,16 @@ internal CancelJobData(CancelJobConfig jobConfig) : base(jobConfig) // DATA STREAMS //************************************************************************************************************* - internal DataStreamCancellationUpdater GetDataStreamCancellationUpdater() + /// + /// Fulfills an instance of the provided type for the job. + /// + /// The + public void Fulfill(out DataStreamCancellationUpdater cancellationUpdater) { EntityProxyDataStream activeCancelDataStream = m_CancelJobConfig.GetActiveCancelDataStream(); ResolveTargetTypeLookup resolveTargetTypeLookup = m_CancelJobConfig.GetResolveTargetTypeLookup(); UnsafeParallelHashMap cancelProgressLookup = m_CancelJobConfig.GetCancelProgressLookup(); - DataStreamCancellationUpdater cancellationUpdater = activeCancelDataStream.CreateDataStreamCancellationUpdater(resolveTargetTypeLookup, cancelProgressLookup); - return cancellationUpdater; + cancellationUpdater = activeCancelDataStream.CreateDataStreamCancellationUpdater(resolveTargetTypeLookup, cancelProgressLookup); } } -} \ No newline at end of file +} diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/EntityQueryComponentJobData.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/EntityQueryComponentJobData.cs index 2221f8bb..bf23f191 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/EntityQueryComponentJobData.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/EntityQueryComponentJobData.cs @@ -8,7 +8,7 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// /// The type of public class EntityQueryComponentJobData : AbstractJobData - where T : struct, IComponentData + where T : unmanaged, IComponentData { private readonly EntityQueryComponentJobConfig m_JobConfig; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/UpdateJobData.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/UpdateJobData.cs index 907ef7e4..c99cd651 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/UpdateJobData.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobData/UpdateJobData.cs @@ -18,12 +18,15 @@ internal UpdateJobData(UpdateJobConfig jobConfig) : base(jobConfig) // DATA STREAMS //************************************************************************************************************* - internal DataStreamUpdater GetDataStreamUpdater() + /// + /// Fulfills an instance of the provided type for the job. + /// + /// The + public void Fulfill(out DataStreamUpdater updater) { EntityProxyDataStream dataStream = m_UpdateJobConfig.GetPendingDataStream(AbstractJobConfig.Usage.Update); ResolveTargetTypeLookup resolveTargetTypeLookup = m_UpdateJobConfig.GetResolveTargetTypeLookup(); - DataStreamUpdater updater = dataStream.CreateDataStreamUpdater(resolveTargetTypeLookup); - return updater; + updater = dataStream.CreateDataStreamUpdater(resolveTargetTypeLookup); } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskCancelJobForDefer.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskCancelJobForDefer.cs index ed1827f0..5b890446 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskCancelJobForDefer.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskCancelJobForDefer.cs @@ -10,9 +10,8 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// This is specific to a context where the data is being cancelled. /// /// The type of data - [JobProducerType(typeof(TaskCancelJobForDeferExtension.WrapperJobStruct<,>))] - public interface ITaskCancelJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + [JobProducerType(typeof(TaskCancelJobForDeferExtension.WrapperJobProducer<>))] + public interface ITaskCancelJobForDefer { /// /// Called once per thread to allow for initialization of state in the job @@ -28,6 +27,6 @@ public interface ITaskCancelJobForDefer /// /// The to cancel. /// A helper struct to continue or resolve - void Execute(TInstance cancelInstance, ref DataStreamCancellationUpdater cancellationUpdater); + void Execute(int index); } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskJobForDefer.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskJobForDefer.cs index 040d7ad2..f72a6243 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskJobForDefer.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskJobForDefer.cs @@ -10,9 +10,8 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// This is specific to a context where the data is being read. /// /// The type of data - [JobProducerType(typeof(TaskJobForDeferExtension.WrapperJobStruct<,>))] - public interface ITaskJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + [JobProducerType(typeof(TaskJobForDeferExtension.WrapperJobProducer<>))] + public interface ITaskJobForDefer { /// /// Called once per thread to allow for initialization of state in the job @@ -25,6 +24,6 @@ public interface ITaskJobForDefer /// occur. /// /// The to read. - void Execute(TInstance instance); + void Execute(int index); } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskUpdateJobForDefer.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskUpdateJobForDefer.cs index 8f429c9f..bfbae02b 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskUpdateJobForDefer.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/ITaskUpdateJobForDefer.cs @@ -10,9 +10,8 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// This is specific to a context where the data is being updated. /// /// The type of data - [JobProducerType(typeof(TaskUpdateJobForDeferExtension.WrapperJobStruct<,>))] - public interface ITaskUpdateJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + [JobProducerType(typeof(TaskUpdateJobForDeferExtension.WrapperJobProducer<>))] + public interface ITaskUpdateJobForDefer { /// /// Called once per thread to allow for initialization of state in the job @@ -28,6 +27,6 @@ public interface ITaskUpdateJobForDefer /// /// The to update. /// A helper struct to continue or resolve - void Execute(TInstance instance, ref DataStreamUpdater updater); + void Execute(int index); } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskCancelJobForDeferExtension.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskCancelJobForDeferExtension.cs index d8b86f13..eb98086d 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskCancelJobForDeferExtension.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskCancelJobForDeferExtension.cs @@ -1,6 +1,9 @@ +using Anvil.Unity.DOTS.Jobs; +using JetBrains.Annotations; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Unity.Burst; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Jobs.LowLevel.Unsafe; @@ -17,7 +20,7 @@ public static JobHandle Schedule( this TJob jobData, CancelScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskCancelJobForDefer + where TJob : unmanaged, ITaskCancelJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -32,7 +35,7 @@ public static JobHandle ScheduleParallel( this TJob jobData, CancelScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskCancelJobForDefer + where TJob : unmanaged, ITaskCancelJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -49,15 +52,13 @@ private static unsafe JobHandle InternalSchedule( JobHandle dependsOn, ScheduleMode scheduleMode, int batchSize) - where TJob : struct, ITaskCancelJobForDefer + where TJob : unmanaged, ITaskCancelJobForDefer where TInstance : unmanaged, IEntityKeyedTask { - IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA; - ValidateReflectionData(reflectionData); + WrapperJobProducer wrapperData = new WrapperJobProducer(ref jobData); - WrapperJobStruct wrapperData = new WrapperJobStruct( - ref jobData, - scheduleInfo); + IntPtr reflectionData = GetReflectionData(); + ValidateReflectionData(reflectionData); JobsUtility.JobScheduleParameters scheduleParameters = new JobsUtility.JobScheduleParameters( UnsafeUtility.AddressOf(ref wrapperData), @@ -83,6 +84,22 @@ private static unsafe JobHandle InternalSchedule( // STATIC HELPERS //************************************************************************************************************* + //Called by Unity's JobsILPostProcessor to initialize the reflection data for the job. + [UsedImplicitly] + public static void EarlyJobInit() + where TJob : unmanaged, ITaskCancelJobForDefer + { + WrapperJobProducer.Initialize(); + } + + private static IntPtr GetReflectionData() + where TJob : unmanaged, ITaskCancelJobForDefer + { + WrapperJobProducer.Initialize(); + IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA.Data; + return reflectionData; + } + [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] private static void ValidateReflectionData(IntPtr reflectionData) { @@ -93,61 +110,36 @@ private static void ValidateReflectionData(IntPtr reflectionData) } //************************************************************************************************************* - // WRAPPER STRUCT + // PRODUCER //************************************************************************************************************* - internal struct WrapperJobStruct - where TJob : struct, ITaskCancelJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + internal struct WrapperJobProducer + where TJob : struct, ITaskCancelJobForDefer { - private const int UNSET_NATIVE_THREAD_INDEX = -1; - - internal TJob JobData; - internal DataStreamCancellationUpdater CancellationUpdater; - [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + // ReSharper disable once StaticMemberInGenericType + internal static readonly SharedStatic JOB_REFLECTION_DATA = SharedStatic.GetOrCreate>(); - public WrapperJobStruct(ref TJob jobData, CancelScheduleInfo scheduleInfo) + [BurstDiscard] + internal static void Initialize() { - JobData = jobData; - CancellationUpdater = scheduleInfo.CancellationUpdater; - NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + if (JOB_REFLECTION_DATA.Data == IntPtr.Zero) + { + JOB_REFLECTION_DATA.Data = JobsUtility.CreateJobReflectionData( + typeof(WrapperJobProducer), + typeof(TJob), + (ExecuteJobFunction)Execute); + } } - } - - //************************************************************************************************************* - // PRODUCER - //************************************************************************************************************* - private struct WrapperJobProducer - where TJob : struct, ITaskCancelJobForDefer - where TInstance : unmanaged, IEntityKeyedTask - { - // ReSharper disable once StaticMemberInGenericType - internal static readonly IntPtr JOB_REFLECTION_DATA = JobsUtility.CreateJobReflectionData( - typeof(WrapperJobStruct), - typeof(TJob), - (ExecuteJobFunction)Execute); - - - private delegate void ExecuteJobFunction( - ref WrapperJobStruct jobData, - IntPtr additionalPtr, - IntPtr bufferRangePatchData, - ref JobRanges ranges, - int jobIndex); - [SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Required by Burst.")] public static unsafe void Execute( - ref WrapperJobStruct wrapperData, + ref WrapperJobProducer wrapperData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { - ref TJob jobData = ref wrapperData.JobData; - ref DataStreamCancellationUpdater cancellationUpdater = ref wrapperData.CancellationUpdater; - - cancellationUpdater.InitForThread(wrapperData.NativeThreadIndex); + ref TJob jobData = ref wrapperData.m_JobData; jobData.InitForThread(wrapperData.NativeThreadIndex); //TODO: Low Priority - #85 - Add some job safety checks @@ -160,10 +152,28 @@ public static unsafe void Execute( for (int i = beginIndex; i < endIndex; ++i) { - jobData.Execute(cancellationUpdater[i], ref cancellationUpdater); + jobData.Execute(i); } } } + + private delegate void ExecuteJobFunction( + ref WrapperJobProducer jobData, + IntPtr additionalPtr, + IntPtr bufferRangePatchData, + ref JobRanges ranges, + int jobIndex); + + private const int UNSET_NATIVE_THREAD_INDEX = -1; + + private TJob m_JobData; + [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + + public WrapperJobProducer(ref TJob jobData) + { + m_JobData = jobData; + NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + } } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskJobForDeferExtension.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskJobForDeferExtension.cs index db9eaf2e..0e1d53e9 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskJobForDeferExtension.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskJobForDeferExtension.cs @@ -1,6 +1,8 @@ +using JetBrains.Annotations; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Unity.Burst; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Jobs.LowLevel.Unsafe; @@ -17,7 +19,7 @@ public static JobHandle Schedule( this TJob jobData, DataStreamScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskJobForDefer + where TJob : unmanaged, ITaskJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -32,7 +34,7 @@ public static JobHandle ScheduleParallel( this TJob jobData, DataStreamScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskJobForDefer + where TJob : unmanaged, ITaskJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -49,15 +51,13 @@ public static unsafe JobHandle InternalSchedule( JobHandle dependsOn, ScheduleMode scheduleMode, int batchSize) - where TJob : struct, ITaskJobForDefer + where TJob : unmanaged, ITaskJobForDefer where TInstance : unmanaged, IEntityKeyedTask { - IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA; - ValidateReflectionData(reflectionData); + WrapperJobProducer wrapperData = new WrapperJobProducer(ref jobData); - WrapperJobStruct wrapperData = new WrapperJobStruct( - ref jobData, - scheduleInfo); + IntPtr reflectionData = GetReflectionData(); + ValidateReflectionData(reflectionData); JobsUtility.JobScheduleParameters scheduleParameters = new JobsUtility.JobScheduleParameters( UnsafeUtility.AddressOf(ref wrapperData), @@ -84,6 +84,22 @@ public static unsafe JobHandle InternalSchedule( // STATIC HELPERS //************************************************************************************************************* + //Called by Unity's JobsILPostProcessor to initialize the reflection data for the job. + [UsedImplicitly] + public static void EarlyJobInit() + where TJob : unmanaged, ITaskJobForDefer + { + WrapperJobProducer.Initialize(); + } + + private static IntPtr GetReflectionData() + where TJob : unmanaged, ITaskJobForDefer + { + WrapperJobProducer.Initialize(); + IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA.Data; + return reflectionData; + } + [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] private static void ValidateReflectionData(IntPtr reflectionData) { @@ -94,59 +110,36 @@ private static void ValidateReflectionData(IntPtr reflectionData) } //************************************************************************************************************* - // WRAPPER STRUCT + // PRODUCER //************************************************************************************************************* - internal struct WrapperJobStruct - where TJob : struct, ITaskJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + internal struct WrapperJobProducer + where TJob : unmanaged, ITaskJobForDefer { - private const int UNSET_NATIVE_THREAD_INDEX = -1; - - internal TJob JobData; - internal DataStreamActiveReader Reader; - [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + // ReSharper disable once StaticMemberInGenericType + internal static readonly SharedStatic JOB_REFLECTION_DATA = SharedStatic.GetOrCreate>(); - public WrapperJobStruct(ref TJob jobData, DataStreamScheduleInfo scheduleInfo) + [BurstDiscard] + internal static void Initialize() { - JobData = jobData; - Reader = scheduleInfo.Reader; - NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + if (JOB_REFLECTION_DATA.Data == IntPtr.Zero) + { + JOB_REFLECTION_DATA.Data = JobsUtility.CreateJobReflectionData( + typeof(WrapperJobProducer), + typeof(TJob), + (ExecuteJobFunction)Execute); + } } - } - - //************************************************************************************************************* - // PRODUCER - //************************************************************************************************************* - private struct WrapperJobProducer - where TJob : struct, ITaskJobForDefer - where TInstance : unmanaged, IEntityKeyedTask - { - // ReSharper disable once StaticMemberInGenericType - internal static readonly IntPtr JOB_REFLECTION_DATA = JobsUtility.CreateJobReflectionData( - typeof(WrapperJobStruct), - typeof(TJob), - (ExecuteJobFunction)Execute); - - - private delegate void ExecuteJobFunction( - ref WrapperJobStruct jobData, - IntPtr additionalPtr, - IntPtr bufferRangePatchData, - ref JobRanges ranges, - int jobIndex); - [SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Required by Burst.")] - public static unsafe void Execute( - ref WrapperJobStruct wrapperData, + internal static unsafe void Execute( + ref WrapperJobProducer wrapperData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { - ref TJob jobData = ref wrapperData.JobData; - ref DataStreamActiveReader reader = ref wrapperData.Reader; + ref TJob jobData = ref wrapperData.m_JobData; jobData.InitForThread(wrapperData.NativeThreadIndex); @@ -158,10 +151,28 @@ public static unsafe void Execute( for (int i = beginIndex; i < endIndex; ++i) { - jobData.Execute(reader[i]); + jobData.Execute(i); } } } + + private delegate void ExecuteJobFunction( + ref WrapperJobProducer jobData, + IntPtr additionalPtr, + IntPtr bufferRangePatchData, + ref JobRanges ranges, + int jobIndex); + + private const int UNSET_NATIVE_THREAD_INDEX = -1; + + private TJob m_JobData; + [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + + public WrapperJobProducer(ref TJob jobData) + { + m_JobData = jobData; + NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + } } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskUpdateJobForDeferExtension.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskUpdateJobForDeferExtension.cs index d16740ab..83974784 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskUpdateJobForDeferExtension.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/JobType/TaskUpdateJobForDeferExtension.cs @@ -1,6 +1,8 @@ +using JetBrains.Annotations; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Unity.Burst; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Jobs.LowLevel.Unsafe; @@ -16,7 +18,7 @@ public static JobHandle Schedule( this TJob jobData, UpdateScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskUpdateJobForDefer + where TJob : unmanaged, ITaskUpdateJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -31,7 +33,7 @@ public static JobHandle ScheduleParallel( this TJob jobData, UpdateScheduleInfo scheduleInfo, JobHandle dependsOn = default) - where TJob : struct, ITaskUpdateJobForDefer + where TJob : unmanaged, ITaskUpdateJobForDefer where TInstance : unmanaged, IEntityKeyedTask { return InternalSchedule( @@ -43,20 +45,19 @@ public static JobHandle ScheduleParallel( } private static unsafe JobHandle InternalSchedule( - TJob jobData, + this TJob jobData, UpdateScheduleInfo scheduleInfo, JobHandle dependsOn, ScheduleMode scheduleMode, int batchSize) - where TJob : struct, ITaskUpdateJobForDefer + where TJob : unmanaged, ITaskUpdateJobForDefer where TInstance : unmanaged, IEntityKeyedTask { - IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA; + WrapperJobProducer wrapperData = new WrapperJobProducer(ref jobData); + + IntPtr reflectionData = GetReflectionData(); ValidateReflectionData(reflectionData); - WrapperJobStruct wrapperData = new WrapperJobStruct( - ref jobData, - scheduleInfo); JobsUtility.JobScheduleParameters scheduleParameters = new JobsUtility.JobScheduleParameters( UnsafeUtility.AddressOf(ref wrapperData), @@ -82,6 +83,22 @@ private static unsafe JobHandle InternalSchedule( // STATIC HELPERS //************************************************************************************************************* + //Called by Unity's JobsILPostProcessor to initialize the reflection data for the job. + [UsedImplicitly] + public static void EarlyJobInit() + where TJob : unmanaged, ITaskUpdateJobForDefer + { + WrapperJobProducer.Initialize(); + } + + private static IntPtr GetReflectionData() + where TJob : unmanaged, ITaskUpdateJobForDefer + { + WrapperJobProducer.Initialize(); + IntPtr reflectionData = WrapperJobProducer.JOB_REFLECTION_DATA.Data; + return reflectionData; + } + [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] private static void ValidateReflectionData(IntPtr reflectionData) { @@ -92,61 +109,36 @@ private static void ValidateReflectionData(IntPtr reflectionData) } //************************************************************************************************************* - // WRAPPER STRUCT + // PRODUCER //************************************************************************************************************* - internal struct WrapperJobStruct - where TJob : struct, ITaskUpdateJobForDefer - where TInstance : unmanaged, IEntityKeyedTask + internal struct WrapperJobProducer + where TJob : unmanaged, ITaskUpdateJobForDefer { - private const int UNSET_NATIVE_THREAD_INDEX = -1; - - internal TJob JobData; - internal DataStreamUpdater Updater; - [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + // ReSharper disable once StaticMemberInGenericType + internal static readonly SharedStatic JOB_REFLECTION_DATA = SharedStatic.GetOrCreate>(); - public WrapperJobStruct(ref TJob jobData, UpdateScheduleInfo scheduleInfo) + [BurstDiscard] + internal static void Initialize() { - JobData = jobData; - Updater = scheduleInfo.Updater; - NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + if (JOB_REFLECTION_DATA.Data == IntPtr.Zero) + { + JOB_REFLECTION_DATA.Data = JobsUtility.CreateJobReflectionData( + typeof(WrapperJobProducer), + typeof(TJob), + (ExecuteJobFunction)Execute); + } } - } - - //************************************************************************************************************* - // PRODUCER - //************************************************************************************************************* - private struct WrapperJobProducer - where TJob : struct, ITaskUpdateJobForDefer - where TInstance : unmanaged, IEntityKeyedTask - { - // ReSharper disable once StaticMemberInGenericType - internal static readonly IntPtr JOB_REFLECTION_DATA = JobsUtility.CreateJobReflectionData( - typeof(WrapperJobStruct), - typeof(TJob), - (ExecuteJobFunction)Execute); - - - private delegate void ExecuteJobFunction( - ref WrapperJobStruct jobData, - IntPtr additionalPtr, - IntPtr bufferRangePatchData, - ref JobRanges ranges, - int jobIndex); - [SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Required by Burst.")] public static unsafe void Execute( - ref WrapperJobStruct wrapperData, + ref WrapperJobProducer wrapperData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { - ref TJob jobData = ref wrapperData.JobData; - ref DataStreamUpdater updater = ref wrapperData.Updater; - - updater.InitForThread(wrapperData.NativeThreadIndex); + ref TJob jobData = ref wrapperData.m_JobData; jobData.InitForThread(wrapperData.NativeThreadIndex); while (JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out int beginIndex, out int endIndex)) @@ -157,10 +149,28 @@ public static unsafe void Execute( for (int i = beginIndex; i < endIndex; ++i) { - jobData.Execute(updater[i], ref updater); + jobData.Execute(i); } } } + + private delegate void ExecuteJobFunction( + ref WrapperJobProducer jobData, + IntPtr additionalPtr, + IntPtr bufferRangePatchData, + ref JobRanges ranges, + int jobIndex); + + private const int UNSET_NATIVE_THREAD_INDEX = -1; + + private TJob m_JobData; + [NativeSetThreadIndex] internal readonly int NativeThreadIndex; + + public WrapperJobProducer(ref TJob jobData) + { + m_JobData = jobData; + NativeThreadIndex = UNSET_NATIVE_THREAD_INDEX; + } } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeArray.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeList.cs similarity index 79% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeArray.cs rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeList.cs index 3e7d73db..c0a45e45 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeArray.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeList.cs @@ -10,14 +10,14 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// Consumers can then get the length of the array to be able to do things like scheduling and everyone can share /// the same NativeArray instead of resolving the struct EntityQuery multiple times. /// - internal abstract class AbstractEntityQueryNativeArray - where T : struct + internal abstract class AbstractEntityQueryNativeList + where T : unmanaged { public abstract int Length { get; } - public NativeArray Results { get; protected set; } + public NativeList Results { get; protected set; } internal EntityQuery EntityQuery { get; } - protected AbstractEntityQueryNativeArray(EntityQuery entityQuery) + protected AbstractEntityQueryNativeList(EntityQuery entityQuery) { EntityQuery = entityQuery; } @@ -25,4 +25,4 @@ protected AbstractEntityQueryNativeArray(EntityQuery entityQuery) public abstract JobHandle Acquire(); public abstract void Release(JobHandle releaseAccessDependency); } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeArray.cs.meta b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeList.cs.meta similarity index 100% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeArray.cs.meta rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/AbstractEntityQueryNativeList.cs.meta diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeArray.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeList.cs similarity index 58% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeArray.cs rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeList.cs index af22f411..31e92a8c 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeArray.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeList.cs @@ -4,19 +4,19 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - internal class EntityQueryComponentNativeArray : AbstractEntityQueryNativeArray - where T : struct, IComponentData + internal class EntityQueryComponentNativeList : AbstractEntityQueryNativeList + where T : unmanaged, IComponentData { public sealed override int Length { get => Results.Length; } - public EntityQueryComponentNativeArray(EntityQuery entityQuery) : base(entityQuery) { } + public EntityQueryComponentNativeList(EntityQuery entityQuery) : base(entityQuery) { } public sealed override JobHandle Acquire() { - Results = EntityQuery.ToComponentDataArrayAsync(Allocator.TempJob, out JobHandle dependsOn); + Results = EntityQuery.ToComponentDataListAsync(Allocator.TempJob, out JobHandle dependsOn); return dependsOn; } @@ -25,4 +25,4 @@ public sealed override void Release(JobHandle releaseAccessDependency) Results.Dispose(releaseAccessDependency); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeArray.cs.meta b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeList.cs.meta similarity index 100% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeArray.cs.meta rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryComponentNativeList.cs.meta diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeArray.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeList.cs similarity index 64% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeArray.cs rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeList.cs index c6620519..14c6882b 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeArray.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeList.cs @@ -4,18 +4,18 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - internal class EntityQueryNativeArray : AbstractEntityQueryNativeArray + internal class EntityQueryNativeList : AbstractEntityQueryNativeList { public sealed override int Length { get => Results.Length; } - public EntityQueryNativeArray(EntityQuery entityQuery) : base(entityQuery) { } + public EntityQueryNativeList(EntityQuery entityQuery) : base(entityQuery) { } public sealed override JobHandle Acquire() { - Results = EntityQuery.ToEntityArrayAsync(Allocator.TempJob, out JobHandle dependsOn); + Results = EntityQuery.ToEntityListAsync(Allocator.TempJob, out JobHandle dependsOn); return dependsOn; } @@ -24,4 +24,4 @@ public sealed override void Release(JobHandle releaseAccessDependency) Results.Dispose(releaseAccessDependency); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeArray.cs.meta b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeList.cs.meta similarity index 100% rename from Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeArray.cs.meta rename to Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Query/EntityQueryNativeList.cs.meta diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/JobConfigScheduleDelegates.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/JobConfigScheduleDelegates.cs index 5f843eea..45357100 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/JobConfigScheduleDelegates.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/JobConfigScheduleDelegates.cs @@ -38,7 +38,7 @@ public delegate JobHandle ScheduleEntityQueryComponentJobDelegate( JobHandle jobHandle, EntityQueryComponentJobData jobData, EntityQueryComponentScheduleInfo scheduleInfo) - where T : struct, IComponentData; + where T : unmanaged, IComponentData; /// /// For scheduling a job triggered by instances in a from a diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/CancelScheduleInfo.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/CancelScheduleInfo.cs index 664dfe99..ec3d84f5 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/CancelScheduleInfo.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/CancelScheduleInfo.cs @@ -22,11 +22,6 @@ public class CancelScheduleInfo : AbstractScheduleInfo /// public DeferredNativeArrayScheduleInfo DeferredNativeArrayScheduleInfo { get; } - internal DataStreamCancellationUpdater CancellationUpdater - { - get => m_JobData.GetDataStreamCancellationUpdater(); - } - internal CancelScheduleInfo( CancelJobData jobData, EntityProxyDataStream dataStream, diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryComponentScheduleInfo.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryComponentScheduleInfo.cs index 7f5b6a47..fd644fbc 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryComponentScheduleInfo.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryComponentScheduleInfo.cs @@ -9,10 +9,10 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// The type of data //TODO: #82 - See if this can be consolidated. public class EntityQueryComponentScheduleInfo : AbstractScheduleInfo - where T : struct, IComponentData + where T : unmanaged, IComponentData { private readonly EntityQueryComponentJobData m_JobData; - private readonly EntityQueryComponentNativeArray m_EntityQueryComponentNativeArray; + private readonly EntityQueryComponentNativeList m_EntityQueryComponentNativeList; private readonly JobConfigScheduleDelegates.ScheduleEntityQueryComponentJobDelegate m_ScheduleJobFunction; /// @@ -20,18 +20,18 @@ public class EntityQueryComponentScheduleInfo : AbstractScheduleInfo /// public int Length { - get => m_EntityQueryComponentNativeArray.Length; + get => m_EntityQueryComponentNativeList.Length; } internal EntityQueryComponentScheduleInfo( EntityQueryComponentJobData jobData, - EntityQueryComponentNativeArray entityQueryComponentNativeArray, + EntityQueryComponentNativeList entityQueryComponentNativeList, BatchStrategy batchStrategy, JobConfigScheduleDelegates.ScheduleEntityQueryComponentJobDelegate scheduleJobFunction) : base(scheduleJobFunction.Method, batchStrategy, ChunkUtil.MaxElementsPerChunk()) { m_JobData = jobData; - m_EntityQueryComponentNativeArray = entityQueryComponentNativeArray; + m_EntityQueryComponentNativeList = entityQueryComponentNativeList; m_ScheduleJobFunction = scheduleJobFunction; } @@ -43,7 +43,7 @@ internal sealed override JobHandle CallScheduleFunction(JobHandle dependsOn) internal override bool ShouldSchedule() { //If the query won't match anything, no need to schedule. SystemState.ShouldRunSystem does this - return !m_EntityQueryComponentNativeArray.EntityQuery.IsEmptyIgnoreFilter; + return !m_EntityQueryComponentNativeList.EntityQuery.IsEmptyIgnoreFilter; } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryScheduleInfo.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryScheduleInfo.cs index f15e27e9..2bc3d7cc 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryScheduleInfo.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/EntityQueryScheduleInfo.cs @@ -9,7 +9,7 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver public class EntityQueryScheduleInfo : AbstractScheduleInfo { private readonly EntityQueryJobData m_JobData; - private readonly EntityQueryNativeArray m_EntityQueryNativeArray; + private readonly EntityQueryNativeList m_EntityQueryNativeList; private readonly JobConfigScheduleDelegates.ScheduleEntityQueryJobDelegate m_ScheduleJobFunction; /// @@ -17,18 +17,18 @@ public class EntityQueryScheduleInfo : AbstractScheduleInfo /// public int Length { - get => m_EntityQueryNativeArray.Length; + get => m_EntityQueryNativeList.Length; } internal EntityQueryScheduleInfo( EntityQueryJobData jobData, - EntityQueryNativeArray entityQueryNativeArray, + EntityQueryNativeList entityQueryNativeList, BatchStrategy batchStrategy, JobConfigScheduleDelegates.ScheduleEntityQueryJobDelegate scheduleJobFunction) : base(scheduleJobFunction.Method, batchStrategy, ChunkUtil.MaxElementsPerChunk()) { m_JobData = jobData; - m_EntityQueryNativeArray = entityQueryNativeArray; + m_EntityQueryNativeList = entityQueryNativeList; m_ScheduleJobFunction = scheduleJobFunction; } @@ -40,7 +40,7 @@ internal sealed override JobHandle CallScheduleFunction(JobHandle dependsOn) internal override bool ShouldSchedule() { //If the query won't match anything, no need to schedule. SystemState.ShouldRunSystem does this - return !m_EntityQueryNativeArray.EntityQuery.IsEmptyIgnoreFilter; + return !m_EntityQueryNativeList.EntityQuery.IsEmptyIgnoreFilter; } } } \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/UpdateScheduleInfo.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/UpdateScheduleInfo.cs index fca25085..311d250d 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/UpdateScheduleInfo.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Scheduling/ScheduleInfo/UpdateScheduleInfo.cs @@ -21,10 +21,6 @@ public class UpdateScheduleInfo : AbstractScheduleInfo /// public DeferredNativeArrayScheduleInfo DeferredNativeArrayScheduleInfo { get; } - internal DataStreamUpdater Updater - { - get => m_JobData.GetDataStreamUpdater(); - } internal UpdateScheduleInfo( UpdateJobData jobData, @@ -54,4 +50,4 @@ internal override bool ShouldSchedule() return m_DataStream.IsActiveDataInvalidated(m_LastDataStreamVersion); } } -} \ No newline at end of file +} diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/CDFEAccessWrapper.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/CDFEAccessWrapper.cs index 5c61185a..c4edbc46 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/CDFEAccessWrapper.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/CDFEAccessWrapper.cs @@ -5,7 +5,7 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { internal class CDFEAccessWrapper : AbstractAccessWrapper - where T : struct, IComponentData + where T : unmanaged, IComponentData { private readonly SystemBase m_System; private readonly AccessController m_AccessController; @@ -13,7 +13,7 @@ internal class CDFEAccessWrapper : AbstractAccessWrapper public CDFEAccessWrapper(AccessType accessType, AbstractJobConfig.Usage usage, SystemBase system) : base(accessType, usage) { m_System = system; - m_AccessController = m_System.World.GetOrCreateSystem().GetOrCreateCDFEAccessController(); + m_AccessController = m_System.World.GetOrCreateSystemManaged().GetOrCreateCDFEAccessController(); } protected override void DisposeSelf() diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/DynamicBufferAccessWrapper.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/DynamicBufferAccessWrapper.cs index 4e5819c5..7722c2b3 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/DynamicBufferAccessWrapper.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/DynamicBufferAccessWrapper.cs @@ -5,7 +5,7 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { internal class DynamicBufferAccessWrapper : AbstractAccessWrapper - where T : struct, IBufferElementData + where T : unmanaged, IBufferElementData { private readonly SystemBase m_System; private readonly AccessController m_AccessController; @@ -13,7 +13,7 @@ internal class DynamicBufferAccessWrapper : AbstractAccessWrapper public DynamicBufferAccessWrapper(AccessType accessType, AbstractJobConfig.Usage usage, SystemBase system) : base(accessType, usage) { m_System = system; - m_AccessController = m_System.World.GetOrCreateSystem().GetOrCreateDBFEAccessController(); + m_AccessController = m_System.World.GetOrCreateSystemManaged().GetOrCreateDBFEAccessController(); } protected override void DisposeSelf() diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryAccessWrapper.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryAccessWrapper.cs index d5180969..fe25a4c3 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryAccessWrapper.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryAccessWrapper.cs @@ -7,27 +7,27 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { internal class EntityQueryAccessWrapper : AbstractAccessWrapper { - private readonly EntityQueryNativeArray m_EntityQueryNativeArray; + private readonly EntityQueryNativeList m_EntityQueryNativeList; - public NativeArray NativeArray + public NativeList NativeList { - get => m_EntityQueryNativeArray.Results; + get => m_EntityQueryNativeList.Results; } - public EntityQueryAccessWrapper(EntityQueryNativeArray entityQueryNativeArray, AbstractJobConfig.Usage usage) : base(AccessType.SharedRead, usage) + public EntityQueryAccessWrapper(EntityQueryNativeList entityQueryNativeList, AbstractJobConfig.Usage usage) : base(AccessType.SharedRead, usage) { - m_EntityQueryNativeArray = entityQueryNativeArray; + m_EntityQueryNativeList = entityQueryNativeList; } public sealed override JobHandle AcquireAsync() { - return m_EntityQueryNativeArray.Acquire(); + return m_EntityQueryNativeList.Acquire(); } public sealed override void ReleaseAsync(JobHandle dependsOn) { - m_EntityQueryNativeArray.Release(dependsOn); + m_EntityQueryNativeList.Release(dependsOn); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryComponentAccessWrapper.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryComponentAccessWrapper.cs index 2a0b6d4d..e63ce9a2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryComponentAccessWrapper.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/Job/Wrapper/EntityQueryComponentAccessWrapper.cs @@ -6,28 +6,28 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { internal class EntityQueryComponentAccessWrapper : AbstractAccessWrapper - where T : struct, IComponentData + where T : unmanaged, IComponentData { - private readonly EntityQueryComponentNativeArray m_EntityQueryNativeArray; + private readonly EntityQueryComponentNativeList m_EntityQueryNativeList; - public NativeArray NativeArray + public NativeList NativeList { - get => m_EntityQueryNativeArray.Results; + get => m_EntityQueryNativeList.Results; } - public EntityQueryComponentAccessWrapper(EntityQueryComponentNativeArray entityQueryNativeArray, AbstractJobConfig.Usage usage) : base(AccessType.SharedRead, usage) + public EntityQueryComponentAccessWrapper(EntityQueryComponentNativeList entityQueryNativeList, AbstractJobConfig.Usage usage) : base(AccessType.SharedRead, usage) { - m_EntityQueryNativeArray = entityQueryNativeArray; + m_EntityQueryNativeList = entityQueryNativeList; } public sealed override JobHandle AcquireAsync() { - return m_EntityQueryNativeArray.Acquire(); + return m_EntityQueryNativeList.Acquire(); } public sealed override void ReleaseAsync(JobHandle dependsOn) { - m_EntityQueryNativeArray.Release(dependsOn); + m_EntityQueryNativeList.Release(dependsOn); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelProgressDataStream.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelProgressDataStream.cs index b5b848a9..10cf0151 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelProgressDataStream.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelProgressDataStream.cs @@ -20,7 +20,7 @@ public override IDataSource DataSource public CancelProgressDataStream(ITaskSetOwner taskSetOwner) : base(taskSetOwner) { - TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystemManaged(); m_DataSource = taskDriverManagementSystem.GetCancelProgressDataSource(); ActiveLookupData = m_DataSource.CreateActiveLookupData(TaskSetOwner, UNIQUE_CONTEXT_IDENTIFIER); diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelRequestsDataStream.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelRequestsDataStream.cs index e62bebec..66c83a53 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelRequestsDataStream.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/Cancellation/CancelRequestsDataStream.cs @@ -31,7 +31,7 @@ public uint ActiveDataVersion public CancelRequestsDataStream(ITaskSetOwner taskSetOwner) : base(taskSetOwner) { - TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystemManaged(); m_DataSource = taskDriverManagementSystem.GetCancelRequestsDataSource(); ActiveLookupData = m_DataSource.CreateActiveLookupData(TaskSetOwner, UNIQUE_CONTEXT_IDENTIFIER); diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsActiveConsolidator.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsActiveConsolidator.cs index e704d061..86299371 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsActiveConsolidator.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsActiveConsolidator.cs @@ -4,7 +4,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal struct CancelRequestsActiveConsolidator { private readonly bool m_HasCancellableData; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsDataSourceConsolidator.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsDataSourceConsolidator.cs index bd79130c..87d9890d 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsDataSourceConsolidator.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/CancelRequestsDataSourceConsolidator.cs @@ -7,7 +7,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal struct CancelRequestsDataSourceConsolidator : IDisposable { private const int UNSET_THREAD_INDEX = -1; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyActiveConsolidator.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyActiveConsolidator.cs index 3ddc014d..a21a15fa 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyActiveConsolidator.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyActiveConsolidator.cs @@ -6,7 +6,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal unsafe struct EntityProxyActiveConsolidator where TInstance : unmanaged, IEntityKeyedTask { diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyDataSourceConsolidator.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyDataSourceConsolidator.cs index 4c3d3c46..48e20fb5 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyDataSourceConsolidator.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/DataSource/Consolidator/EntityProxyDataSourceConsolidator.cs @@ -10,7 +10,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver //TODO: https://github.com/decline-cookies/anvil-unity-dots/pull/105#discussion_r1043567688 //TODO: https://github.com/decline-cookies/anvil-unity-dots/pull/105#discussion_r1043573642 - [BurstCompatible] internal struct EntityProxyDataSourceConsolidator : IDisposable where TInstance : unmanaged, IEntityKeyedTask { diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/EntityProxyDataStream.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/EntityProxyDataStream.cs index 2dd3ba21..7499f656 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/EntityProxyDataStream.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/DataStream/EntityProxyDataStream.cs @@ -63,7 +63,7 @@ public uint ActiveCancelDataVersion public EntityProxyDataStream(ITaskSetOwner taskSetOwner, CancelRequestBehaviour cancelRequestBehaviour, string uniqueContextIdentifier) : base(taskSetOwner) { - TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystemManaged(); m_DataSource = taskDriverManagementSystem.GetOrCreateEntityProxyDataSource(); m_ActiveArrayData = m_DataSource.CreateActiveArrayData(taskSetOwner, cancelRequestBehaviour, uniqueContextIdentifier); @@ -99,7 +99,7 @@ public EntityProxyDataStream(AbstractTaskDriver taskDriver, EntityProxyDataStrea //TODO: #137 - Gross!!! This is a special case only for CancelComplete protected EntityProxyDataStream(ITaskSetOwner taskSetOwner, string uniqueContextIdentifier) : base(taskSetOwner) { - TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystem(); + TaskDriverManagementSystem taskDriverManagementSystem = taskSetOwner.World.GetOrCreateSystemManaged(); m_DataSource = taskDriverManagementSystem.GetCancelCompleteDataSource() as EntityProxyDataSource; m_ActiveArrayData = m_DataSource.CreateActiveArrayData(taskSetOwner, CancelRequestBehaviour.Ignore, uniqueContextIdentifier); ScheduleInfo = m_ActiveArrayData.ScheduleInfo; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskID.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskID.cs index 1580d13e..b11e8f9b 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskID.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskID.cs @@ -9,7 +9,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { //TODO: #136 - Maybe have this implement IEntityKeyedTask. https://github.com/decline-cookies/anvil-unity-dots/pull/157#discussion_r1093730973 - [BurstCompatible] [StructLayout(LayoutKind.Sequential, Size = 16)] internal readonly struct EntityKeyedTaskID : IEquatable { @@ -65,7 +64,6 @@ public override string ToString() return $"{Entity.ToString()} - DataOwnerID: {DataOwnerID}, DataTargetID: {DataTargetID}"; } - [BurstCompatible] public FixedString64Bytes ToFixedString() { FixedString64Bytes fs = new FixedString64Bytes(); @@ -77,11 +75,11 @@ public FixedString64Bytes ToFixedString() fs.Append(DataTargetID.ToFixedString()); return fs; } - + //************************************************************************************************************* // SAFETY //************************************************************************************************************* - + [Conditional("ANVIL_DEBUG_SAFETY")] public static void Debug_EnsureOffsetsAreCorrect() { @@ -90,7 +88,7 @@ public static void Debug_EnsureOffsetsAreCorrect() { throw new InvalidOperationException($"{nameof(DataOwnerID)} has changed location in the struct. The hardcoded burst compatible offset of {nameof(TASK_SET_OWNER_ID_OFFSET)} = {TASK_SET_OWNER_ID_OFFSET} needs to be changed to {actualOffset}!"); } - + actualOffset = UnsafeUtility.GetFieldOffset(typeof(EntityKeyedTaskID).GetField(nameof(DataTargetID))); if (actualOffset != DATA_TARGET_ID_OFFSET) { @@ -98,4 +96,4 @@ public static void Debug_EnsureOffsetsAreCorrect() } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskWrapper.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskWrapper.cs index 39ab1a24..dc75eef2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskWrapper.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/EntityKeyedTask/EntityKeyedTaskWrapper.cs @@ -7,7 +7,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] [StructLayout(LayoutKind.Sequential)] internal readonly struct EntityKeyedTaskWrapper : IEquatable> where TInstance : unmanaged, IEntityKeyedTask @@ -66,7 +65,6 @@ public override string ToString() return $"{InstanceID.ToString()})"; } - [BurstCompatible] public FixedString64Bytes ToFixedString() { return InstanceID.ToFixedString(); @@ -87,7 +85,7 @@ private static void Debug_EnsurePayloadsAreTheSame( throw new InvalidOperationException($"Equality check for {typeof(EntityKeyedTaskWrapper)} where the ID's are the same but the Payloads are different. This should never happen!"); } } - + [Conditional("ANVIL_DEBUG_SAFETY")] public static void Debug_EnsureOffsetsAreCorrect() { @@ -98,4 +96,4 @@ public static void Debug_EnsureOffsetsAreCorrect() } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/CancelRequestsWriter.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/CancelRequestsWriter.cs index c541078e..9f891ef2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/CancelRequestsWriter.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/CancelRequestsWriter.cs @@ -10,7 +10,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// /// Job-Safe struct to allow for requesting the cancellation by /// - [BurstCompatible] public struct CancelRequestsWriter { private const int UNSET_LANE_INDEX = -1; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamActiveReader.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamActiveReader.cs index a06c1fb6..06219777 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamActiveReader.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamActiveReader.cs @@ -1,6 +1,8 @@ +using Anvil.Unity.DOTS.Data; using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Unity.Collections; namespace Anvil.Unity.DOTS.Entities.TaskDriver @@ -10,7 +12,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// To be used in jobs that only allows for reading of this data. /// /// They type of to read - [BurstCompatible] public readonly struct DataStreamActiveReader : IEnumerable where TInstance : unmanaged, IEntityKeyedTask { @@ -21,6 +22,16 @@ internal DataStreamActiveReader(NativeArray> a m_Active = active; } + /// + /// Gets the at the specified index. + /// + /// The index into the backing array + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TInstance ElementAtReadOnly(int index) + { + return ref m_Active.ElementAtReadOnly(index).Payload; + } + /// /// Gets the at the specified index. /// diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamCancellationUpdater.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamCancellationUpdater.cs index be98402e..08e41e62 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamCancellationUpdater.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamCancellationUpdater.cs @@ -11,7 +11,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// Job-Safe struct to allow for cancelling an instance of data /// /// The to cancel - [BurstCompatible] public struct DataStreamCancellationUpdater where TInstance : unmanaged, IEntityKeyedTask { private const int UNSET_LANE_INDEX = -1; @@ -105,7 +104,7 @@ internal void Resolve(ref TResolveTargetType resolvedInstanc ref resolvedInstance); } - internal TInstance this[int index] + public TInstance this[int index] { get { diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamPendingWriter.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamPendingWriter.cs index c69fb9a9..1563f780 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamPendingWriter.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamPendingWriter.cs @@ -11,7 +11,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// To be used in jobs that only allows for writing of this data. /// /// They type of to write - [BurstCompatible] public struct DataStreamPendingWriter where TInstance : unmanaged, IEntityKeyedTask { private const int UNSET_LANE_INDEX = -1; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamUpdater.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamUpdater.cs index 05e1bb86..43c19e99 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamUpdater.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/DataStreamUpdater.cs @@ -10,7 +10,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// Job-Safe struct to allow for updating an instance of data /// /// The to update. - [BurstCompatible] public struct DataStreamUpdater where TInstance : unmanaged, IEntityKeyedTask { private const int UNSET_LANE_INDEX = -1; @@ -99,7 +98,7 @@ internal void Resolve(ref TResolveTargetType resolvedInstanc ref resolvedInstance); } - internal TInstance this[int index] + public TInstance this[int index] { get { diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataReader.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataReader.cs index e4920630..852a891d 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataReader.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataReader.cs @@ -11,9 +11,8 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// To be used in jobs that only allows for reading of this data. /// /// They type of to read - [BurstCompatible] public readonly struct EntityPersistentDataReader - where TData : struct, IEntityPersistentDataInstance + where TData : unmanaged, IEntityPersistentDataInstance { [ReadOnly] private readonly UnsafeParallelHashMap m_Lookup; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataWriter.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataWriter.cs index 1d5df174..3c8d29a2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataWriter.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/EntityPersistentDataWriter.cs @@ -10,9 +10,8 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// To be used in jobs that only allows for writing of this data. /// /// They type of to write - [BurstCompatible] public struct EntityPersistentDataWriter - where TData : struct, IEntityPersistentDataInstance + where TData : unmanaged, IEntityPersistentDataInstance { [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] private UnsafeParallelHashMap m_Lookup; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/ThreadPersistentDataAccessor.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/ThreadPersistentDataAccessor.cs index f5df5dc9..2d1dc0c2 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/ThreadPersistentDataAccessor.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/JobDataInteraction/ThreadPersistentDataAccessor.cs @@ -11,8 +11,7 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver /// Represents a read/write reference to an /// /// The type of to read/write - [BurstCompatible] - public unsafe struct ThreadPersistentDataAccessor + public unsafe struct ThreadPersistentDataAccessor where TData : unmanaged, IThreadPersistentDataInstance { private const int UNSET_LANE_INDEX = -1; @@ -40,7 +39,7 @@ internal ThreadPersistentDataAccessor(ref UnsafeArray threadDataArray) : Debug_InitializeAccessorState(); } - + /// /// Call once to initialize the state of this accessor for the thread it is running on. /// @@ -50,7 +49,7 @@ public void InitForThread(int nativeThreadIndex) Debug_EnsureInitThreadOnlyCalledOnce(); m_LaneIndex = ParallelAccessUtil.CollectionIndexForThread(nativeThreadIndex); } - + /// /// Call once to initialize the state of this writer for main thread usage. /// diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetID.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetID.cs index f7c25869..1237b76c 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetID.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetID.cs @@ -4,7 +4,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal readonly struct ResolveTargetID : IEquatable { public static bool operator ==(ResolveTargetID lhs, ResolveTargetID rhs) @@ -46,11 +45,10 @@ public override string ToString() return $"TypeID: {TypeID} - DataOwnerID: {DataOwnerID}"; } - [BurstCompatible] public FixedString64Bytes ToFixedString() { return new FixedString64Bytes(ToString()); ; } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetTypeLookup.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetTypeLookup.cs index e8a0ff67..2e9ed3a8 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetTypeLookup.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetTypeLookup.cs @@ -6,7 +6,6 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal struct ResolveTargetTypeLookup : IDisposable { private UnsafeParallelHashMap m_ResolveTargetWriteDataByID; diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetUtil.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetUtil.cs index 221979fc..fd3e08d4 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetUtil.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskData/Resolving/ResolveTargetUtil.cs @@ -8,13 +8,11 @@ namespace Anvil.Unity.DOTS.Entities.TaskDriver { - [BurstCompatible] internal static class ResolveTargetUtil { // ReSharper disable once ClassNeverInstantiated.Local private class ResolveTargetSharedStaticContext { } - [BurstCompatible] // ReSharper disable once ClassNeverInstantiated.Local private class ResolveTargetID where TResolveTargetType : unmanaged, IEntityKeyedTask @@ -59,7 +57,6 @@ public static uint RegisterResolveTarget() return id; } - [BurstCompatible] public static uint GetResolveTargetID() where TResolveTargetType : unmanaged, IEntityKeyedTask { diff --git a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskSet.cs b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskSet.cs index ba0bbe3b..a6db2377 100644 --- a/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskSet.cs +++ b/Scripts/Runtime/Entities/TaskDriver/TaskSet/TaskSet.cs @@ -41,7 +41,7 @@ public TaskSet(ITaskSetOwner taskSetOwner) { TaskSetOwner = taskSetOwner; - m_PersistentDataSystem = TaskSetOwner.World.GetOrCreateSystem(); + m_PersistentDataSystem = TaskSetOwner.World.GetOrCreateSystemManaged(); //This is temporary until we refactor DataStreams and AbstractData as part of #241 m_DataStreamLookupByID = new Dictionary(); @@ -239,7 +239,7 @@ public IJobConfig ConfigureJobTriggeredBy( EntityQuery entityQuery, JobConfigScheduleDelegates.ScheduleEntityQueryComponentJobDelegate scheduleJobFunction, BatchStrategy batchStrategy) - where T : struct, IComponentData + where T : unmanaged, IComponentData { Debug_EnsureNoDuplicateJobSchedulingDelegates(scheduleJobFunction); diff --git a/Scripts/Runtime/Entities/Transform/TransformUtil.cs b/Scripts/Runtime/Entities/Transform/TransformUtil.cs index 04eef43b..0810a9e4 100644 --- a/Scripts/Runtime/Entities/Transform/TransformUtil.cs +++ b/Scripts/Runtime/Entities/Transform/TransformUtil.cs @@ -25,6 +25,7 @@ private static BurstableLogger Logger get => new BurstableLogger(string.Empty); } + //TODO: #302 - Potentially remove this. May not be necessary anymore. /// /// Adds any missing transform components to an to express basic translation, rotation, and /// scale. If a standard component isn't present it is added with an identity value. @@ -35,19 +36,9 @@ public static void AddMissingStandardComponents(Entity entity, EntityManager ent { Debug.Assert(entityManager.Exists(entity)); - if (!entityManager.HasComponent(entity)) + if (!entityManager.HasComponent(entity)) { - entityManager.AddComponentData(entity, new Translation() { Value = float3.zero }); - } - - if (!entityManager.HasComponent(entity) && !entityManager.HasComponent(entity)) - { - entityManager.AddComponentData(entity, new Scale() { Value = 1 }); - } - - if (!entityManager.HasComponent(entity) && !entityManager.HasComponent(entity)) - { - entityManager.AddComponentData(entity, new Rotation() { Value = quaternion.identity }); + entityManager.AddComponentData(entity, LocalTransform.Identity); } } @@ -400,4 +391,4 @@ private static void EmitErrorIfNonUniformScale(float3 scale) } } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Util/BufferFromEntityExtension.cs b/Scripts/Runtime/Entities/Util/BufferFromEntityExtension.cs index 19c3a6a2..24babd69 100644 --- a/Scripts/Runtime/Entities/Util/BufferFromEntityExtension.cs +++ b/Scripts/Runtime/Entities/Util/BufferFromEntityExtension.cs @@ -3,21 +3,21 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// A collection of extension methods for working with + /// A collection of extension methods for working with /// - public static class BufferFromEntityExtension + public static class BufferLookupExtension { /// /// Builds a container to provide in job access to a on an entity. /// - /// The instance to get the from + /// The instance to get the from /// The to get the from. /// The element type of the . /// A container that provides in job access to the requested . - public static BufferFromSingleEntity ForSingleEntity(this BufferFromEntity lookup, Entity entity) - where T : struct, IBufferElementData + public static BufferFromSingleEntity ForSingleEntity(this BufferLookup lookup, Entity entity) + where T : unmanaged, IBufferElementData { return new BufferFromSingleEntity(lookup, entity); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Util/ComponentDataFromEntityExtension.cs b/Scripts/Runtime/Entities/Util/ComponentLookupExtension.cs similarity index 58% rename from Scripts/Runtime/Entities/Util/ComponentDataFromEntityExtension.cs rename to Scripts/Runtime/Entities/Util/ComponentLookupExtension.cs index bb07ff93..f5f6ac30 100644 --- a/Scripts/Runtime/Entities/Util/ComponentDataFromEntityExtension.cs +++ b/Scripts/Runtime/Entities/Util/ComponentLookupExtension.cs @@ -3,21 +3,21 @@ namespace Anvil.Unity.DOTS.Entities { /// - /// A collection of extension methods for working with + /// A collection of extension methods for working with /// - public static class ComponentDataFromEntityExtension + public static class ComponentLookupExtension { /// /// Builds a container to provide in job access to a on an entity. /// - /// The instance to get the from + /// The instance to get the from /// The to get the from. /// The element type of the . /// A container that provides in job access to the requested . - public static ComponentDataFromSingleEntity ForSingleEntity(this ComponentDataFromEntity lookup, Entity entity) - where T : struct, IComponentData + public static ComponentLookupFromSingleEntity ForSingleEntity(this ComponentLookup lookup, Entity entity) + where T : unmanaged, IComponentData { - return new ComponentDataFromSingleEntity(lookup, entity); + return new ComponentLookupFromSingleEntity(lookup, entity); } } -} +} \ No newline at end of file diff --git a/Scripts/Runtime/Entities/Util/ComponentDataFromEntityExtension.cs.meta b/Scripts/Runtime/Entities/Util/ComponentLookupExtension.cs.meta similarity index 100% rename from Scripts/Runtime/Entities/Util/ComponentDataFromEntityExtension.cs.meta rename to Scripts/Runtime/Entities/Util/ComponentLookupExtension.cs.meta diff --git a/Scripts/Runtime/Entities/Util/ComponentSystemBaseExtension.cs b/Scripts/Runtime/Entities/Util/ComponentSystemBaseExtension.cs index 288780b6..c9e559bf 100644 --- a/Scripts/Runtime/Entities/Util/ComponentSystemBaseExtension.cs +++ b/Scripts/Runtime/Entities/Util/ComponentSystemBaseExtension.cs @@ -1,9 +1,7 @@ using Anvil.Unity.DOTS.Data; -using System.Collections.Generic; using Unity.Collections; using Unity.Entities; using Unity.Jobs; -using UnityEngine; namespace Anvil.Unity.DOTS.Entities { @@ -18,9 +16,12 @@ public static class ComponentSystemBaseExtension /// true if the data will not be written to. /// The element type of the . /// A container that provides in job access to the requested . - public static BufferFromSingleEntity GetBufferFromSingletonEntity(this ComponentSystemBase system, bool isReadOnly = false) where T : struct, IBufferElementData + public static BufferFromSingleEntity GetBufferFromSingletonEntity(this ComponentSystemBase system, bool isReadOnly = false) where T : unmanaged, IBufferElementData { - return system.GetBufferFromEntity(isReadOnly).ForSingleEntity(system.GetSingletonEntity()); + //TODO: #296 - This function will be obsolete post 1.0 +#pragma warning disable CS0618 // Type or member is obsolete + return system.GetBufferLookup(isReadOnly).ForSingleEntity(system.GetSingletonEntity()); +#pragma warning restore CS0618 // Type or member is obsolete } /// @@ -31,12 +32,12 @@ public static BufferFromSingleEntity GetBufferFromSingletonEntity(this Com /// The element type of the . /// A container that provides in job access to the requested . /// - /// If fetching many single entity containers at once, getting a instance and - /// calling is more efficient. + /// If fetching many single entity containers at once, getting a instance and + /// calling is more efficient. /// - public static BufferFromSingleEntity GetBufferFromSingleEntity(this ComponentSystemBase system, Entity entity, bool isReadOnly = false) where T : struct, IBufferElementData + public static BufferFromSingleEntity GetBufferFromSingleEntity(this ComponentSystemBase system, Entity entity, bool isReadOnly = false) where T : unmanaged, IBufferElementData { - return system.GetBufferFromEntity(isReadOnly).ForSingleEntity(entity); + return system.GetBufferLookup(isReadOnly).ForSingleEntity(entity); } /// @@ -45,9 +46,12 @@ public static BufferFromSingleEntity GetBufferFromSingleEntity(this Compon /// true if the data will not be written to. /// The type that implements . /// A container that provides in job access to the requested . - public static ComponentDataFromSingleEntity GetComponentDataFromSingletonEntity(this ComponentSystemBase system, bool isReadOnly) where T : struct, IComponentData + public static ComponentLookupFromSingleEntity GetComponentDataFromSingletonEntity(this ComponentSystemBase system, bool isReadOnly) where T : unmanaged, IComponentData { - return system.GetComponentDataFromEntity(isReadOnly).ForSingleEntity(system.GetSingletonEntity()); + //TODO: #296 - This function will be obsolete post 1.0 +#pragma warning disable CS0618 // Type or member is obsolete + return system.GetComponentLookup(isReadOnly).ForSingleEntity(system.GetSingletonEntity()); +#pragma warning restore CS0618 // Type or member is obsolete } /// @@ -58,12 +62,12 @@ public static ComponentDataFromSingleEntity GetComponentDataFromSingletonEnti /// The element type of the . /// A container that provides in job access to the requested . /// - /// If fetching many single entity containers at once, getting a instance and - /// calling is more efficient. + /// If fetching many single entity containers at once, getting a instance and + /// calling is more efficient. /// - public static ComponentDataFromSingleEntity GetComponentDataFromSingleEntity(this ComponentSystemBase system, Entity entity, bool isReadOnly) where T : struct, IComponentData + public static ComponentLookupFromSingleEntity GetComponentDataFromSingleEntity(this ComponentSystemBase system, Entity entity, bool isReadOnly) where T : unmanaged, IComponentData { - return system.GetComponentDataFromEntity(isReadOnly).ForSingleEntity(entity); + return system.GetComponentLookup(isReadOnly).ForSingleEntity(entity); } /// @@ -78,11 +82,11 @@ public static ComponentDataFromSingleEntity GetComponentDataFromSingleEntity< /// /// Actual copy is performed by . This is just a convenience method. /// - public static JobHandle CopyBufferToNativeArray(this ComponentSystemBase system, in JobHandle dependsOn, Entity fromEntity, in NativeArray outputBuffer) where T : struct, IBufferElementData + public static JobHandle CopyBufferToNativeArray(this ComponentSystemBase system, in JobHandle dependsOn, Entity fromEntity, in NativeArray outputBuffer) where T : unmanaged, IBufferElementData { CopyBufferToNativeArray job = new CopyBufferToNativeArray() { - InputBufferFromEntity = system.GetBufferFromEntity(true).ForSingleEntity(fromEntity), + InputBufferLookup = system.GetBufferLookup(true).ForSingleEntity(fromEntity), OutputBuffer = outputBuffer }; @@ -106,7 +110,7 @@ public static JobHandle CopyBufferToDeferredNativeArray(this ComponentSystemB { CopyBufferToDeferredNativeArray job = new CopyBufferToDeferredNativeArray() { - InputBufferFromEntity = system.GetBufferFromEntity(true).ForSingleEntity(fromEntity), + InputBufferLookup = system.GetBufferLookup(true).ForSingleEntity(fromEntity), OutputBuffer = outputBuffer }; @@ -126,12 +130,12 @@ public static JobHandle CopyBufferToDeferredNativeArray(this ComponentSystemB /// /// Actual copy is performed by . This is just a convenience method. /// - public static JobHandle CopyNativeArrayToBuffer(this ComponentSystemBase system, in JobHandle dependsOn, in NativeArray inputBuffer, Entity toEntity) where T : struct, IBufferElementData + public static JobHandle CopyNativeArrayToBuffer(this ComponentSystemBase system, in JobHandle dependsOn, in NativeArray inputBuffer, Entity toEntity) where T : unmanaged, IBufferElementData { CopyNativeArrayToBuffer job = new CopyNativeArrayToBuffer() { InputBuffer = inputBuffer, - OutputBufferFromEntity = system.GetBufferFromEntity(false).ForSingleEntity(toEntity) + OutputBufferLookup = system.GetBufferLookup(false).ForSingleEntity(toEntity) }; return job.Schedule(dependsOn); @@ -143,20 +147,24 @@ public static JobHandle CopyNativeArrayToBuffer(this ComponentSystemBase syst /// The system to find the parent of. /// The parent of the system /// True if a parent was found for the given system. - public static bool TryFindParentGroup(this ComponentSystem system, out ComponentSystemGroup group) + public static bool TryFindParentGroup(this ComponentSystemBase system, out ComponentSystemGroup group) { var worldSystems = system.World.Systems; foreach (ComponentSystemBase worldSystem in worldSystems) { - if (worldSystem is ComponentSystemGroup worldGroup) + if (worldSystem is not ComponentSystemGroup worldGroup) { - Debug.Assert(worldGroup.Systems is List); - if ((worldGroup.Systems as List).Contains(system)) - { - group = worldGroup; - return true; - } + continue; } + + NativeList worldGroupSystems = worldGroup.GetAllSystems(Allocator.Temp); + if (!worldGroupSystems.Contains(system.SystemHandle)) + { + continue; + } + + group = worldGroup; + return true; } group = null; diff --git a/Scripts/Runtime/Entities/Util/DynamicBufferExtension.cs b/Scripts/Runtime/Entities/Util/DynamicBufferExtension.cs index 93b88316..a766b7e4 100644 --- a/Scripts/Runtime/Entities/Util/DynamicBufferExtension.cs +++ b/Scripts/Runtime/Entities/Util/DynamicBufferExtension.cs @@ -16,7 +16,7 @@ public static class DynamicBufferExtension /// The zero-based index. /// The data type stored in the buffer. Must be a value type. /// A readonly reference to the element. - public static unsafe ref readonly T ElementAtReadOnly(this DynamicBuffer buffer, int index) where T : struct + public static unsafe ref readonly T ElementAtReadOnly(this DynamicBuffer buffer, int index) where T : unmanaged { Debug.Assert(index >= 0 && index < buffer.Length); return ref UnsafeUtility.ArrayElementAsRef(buffer.GetUnsafeReadOnlyPtr(), index); diff --git a/Scripts/Runtime/Entities/Util/EntityManagerExtension.cs b/Scripts/Runtime/Entities/Util/EntityManagerExtension.cs index e3f28f01..667c9ea1 100644 --- a/Scripts/Runtime/Entities/Util/EntityManagerExtension.cs +++ b/Scripts/Runtime/Entities/Util/EntityManagerExtension.cs @@ -34,7 +34,7 @@ public static bool IsValid(this EntityManager entityManager, Entity entity) /// The data that was fetched. This data is only valid if the method returns true. /// The data type to fetch. /// True if the data was present on the entity. - public static bool TryGetComponentData(this EntityManager entityManager, Entity entity, out T data) where T : struct, IComponentData + public static bool TryGetComponentData(this EntityManager entityManager, Entity entity, out T data) where T : unmanaged, IComponentData { if (entityManager.HasComponent(entity)) { diff --git a/Scripts/Runtime/Entities/Util/WorldExtension.cs b/Scripts/Runtime/Entities/Util/WorldExtension.cs index 0d9bcb7d..b1767b75 100644 --- a/Scripts/Runtime/Entities/Util/WorldExtension.cs +++ b/Scripts/Runtime/Entities/Util/WorldExtension.cs @@ -40,11 +40,11 @@ public static void GetOrCreateSystemsSequentiallyAndLogExceptions(this World wor { if (typeof(ComponentSystemBase).IsAssignableFrom(systemType)) { - world.GetOrCreateSystem(systemType); + world.GetOrCreateSystemManaged(systemType); } else if (typeof(ISystem).IsAssignableFrom(systemType)) { - world.GetOrCreateUnmanagedSystem(systemType); + world.GetOrCreateSystem(systemType); } else { diff --git a/Scripts/Runtime/Entities/Util/WorldUtil.cs b/Scripts/Runtime/Entities/Util/WorldUtil.cs index c050ebb1..c0af9b90 100644 --- a/Scripts/Runtime/Entities/Util/WorldUtil.cs +++ b/Scripts/Runtime/Entities/Util/WorldUtil.cs @@ -15,7 +15,7 @@ namespace Anvil.Unity.DOTS.Entities /// /// Kept outside so their names read better in the editor. [DisableAutoCreation] - internal class EndInitializationCommandBufferSystemGroup_Anvil : ComponentSystemGroup { } + internal partial class EndInitializationCommandBufferSystemGroup_Anvil : ComponentSystemGroup { } /// /// A system group to house a s . @@ -23,7 +23,7 @@ internal class EndInitializationCommandBufferSystemGroup_Anvil : ComponentSystem /// /// Kept outside so their names read better in the editor. [DisableAutoCreation] - internal class EndSimulationCommandBufferSystemGroup_Anvil : ComponentSystemGroup { } + internal partial class EndSimulationCommandBufferSystemGroup_Anvil : ComponentSystemGroup { } /// /// A phase inserted immediately after . @@ -160,10 +160,10 @@ public static ComponentSystemGroup[] SetupTopLevelGroupsInCurrentPlayerLoop( (Type playerLoopSystemType, Type systemGroupType) = topLevelGroupTypes[i]; Debug.Assert(systemGroupType.IsSubclassOf(typeof(ComponentSystemGroup))); - ComponentSystemGroup group = world.GetExistingSystem(systemGroupType) as ComponentSystemGroup; + ComponentSystemGroup group = world.GetExistingSystemManaged(systemGroupType) as ComponentSystemGroup; if (group == null) { - group = world.CreateSystem(systemGroupType) as ComponentSystemGroup; + group = world.CreateSystemManaged(systemGroupType) as ComponentSystemGroup; ScriptBehaviourUpdateOrder.AppendSystemToPlayerLoop(group, ref playerLoop, playerLoopSystemType); } else @@ -286,9 +286,9 @@ public static void MoveSystemFromToGroup(World worl { Debug.Assert(typeof(SrcGroup) != typeof(DestGroup), "Source and destination groups should not be the same."); - ComponentSystemBase system = world.GetExistingSystem(); - ComponentSystemGroup srcGroup = world.GetExistingSystem(); - ComponentSystemGroup destGroup = world.GetExistingSystem(); + ComponentSystemBase system = world.GetExistingSystemManaged(); + ComponentSystemGroup srcGroup = world.GetExistingSystemManaged(); + ComponentSystemGroup destGroup = world.GetExistingSystemManaged(); // Skip if there are missing elements if (system == null || srcGroup == null || destGroup == null) @@ -296,7 +296,7 @@ public static void MoveSystemFromToGroup(World worl throw new ArgumentNullException($"{nameof(MoveSystemFromToGroup)}: One or more of the provided system and groups do not exist. {nameof(System)}:{system}, {nameof(SrcGroup)}:{srcGroup}, {nameof(DestGroup)}:{destGroup}"); } - Debug.Assert(srcGroup.Systems.Contains(system), $"{system} is not part of the source group: {srcGroup}"); + Debug.Assert(srcGroup.GetAllSystems().AsArray().Contains(system.SystemHandle), $"{system} is not part of the source group: {srcGroup}"); srcGroup.RemoveSystemFromUpdateList(system); destGroup.AddSystemToUpdateList(system); diff --git a/Scripts/Runtime/Job/Util/ParallelAccessUtil.cs b/Scripts/Runtime/Job/Util/ParallelAccessUtil.cs index 25fab9f6..23934e91 100644 --- a/Scripts/Runtime/Job/Util/ParallelAccessUtil.cs +++ b/Scripts/Runtime/Job/Util/ParallelAccessUtil.cs @@ -16,6 +16,7 @@ namespace Anvil.Unity.DOTS.Jobs { + //TODO: #299 - Might be able to get rid of this class altogether. /// /// Utility methods for working accessing values in parallel. /// @@ -50,11 +51,7 @@ private JobWorkerMaximumCountKeyContext() { } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Init() { - JOB_WORKER_MAXIMUM_COUNT.Data = JobsUtility.JobWorkerMaximumCount; - //Why plus 2? Because sometimes Unity will put your jobs on the main thread and also an additional - //profiler thread outside the job worker threads. - CollectionSizeForMaxThreads = JOB_WORKER_MAXIMUM_COUNT.Data + 2; - + JOB_WORKER_MAXIMUM_COUNT.Data = JobsUtility.ThreadIndexCount; Debug.Assert(JOB_WORKER_MAXIMUM_COUNT.Data > 0); } @@ -70,40 +67,17 @@ private static void Init() /// etc /// It's the number of separate "buckets" that can be written to in parallel. /// - public static int CollectionSizeForMaxThreads { get; private set; } + public static int CollectionSizeForMaxThreads + { + get => JOB_WORKER_MAXIMUM_COUNT.Data; + } /// /// Returns the correct index for the collection based on the passed in. /// /// - /// This function assumes that the collection being used was sized appropriately via - /// . Larger sized collections will still work - /// but the intended usage is to create a small tightly packed collection sized for the specific hardware the - /// program is running on. Smaller sized collections will error sporadically as the scheduler assigns jobs to - /// out of range thread indexes. - /// - /// This function also assumes that you are never running your job on the main thread via - /// . In that case the thread index will be 0 and this function will - /// return -1 which will cause an error. - /// - /// When scheduling your job, Unity will place your job on one of the available worker threads in which case - /// the native thread index you receive will be from 1 to . - /// There are two special cases. - /// 1. The scheduler may place your job on the main thread. In this case the native thread index will be - /// some value above . - /// 2. The scheduler may place your job on a profiler thread in the editor. In this case the native thread - /// index will also be some value above - /// It is unknown why this is. - /// - /// Our goal is to have a tightly packed collection so in the example of an 8 core machine with - /// equal to 15, we would have the following mapping. - /// - /// thread 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, main, profiler - /// index 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - /// - /// We have a tightly packed collection with index 0 through 16 for a total of 17 buckets. - /// (15 job workers, one main, one profiler) - /// Thread indexes map directly without having to remember the special rules. + /// Temporary, this used to do a lot more work but due to Entities 1.0, we can simply return the nativeThreadIndex. + /// See: #299 for more details. /// /// /// The native thread index to figure out the collection index from. Must be greater than 0. @@ -113,7 +87,7 @@ public static int CollectionIndexForThread(int nativeThreadIndex) { DetectMultipleXThreads(nativeThreadIndex); Debug_EnsureNativeThreadIndexIsValid(nativeThreadIndex); - return math.min(nativeThreadIndex - 1, JOB_WORKER_MAXIMUM_COUNT.Data); + return nativeThreadIndex; } /// @@ -126,7 +100,7 @@ public static int CollectionIndexForThread(int nativeThreadIndex) /// The collection index to use public static int CollectionIndexForMainThread() { - int mainThreadIndex = JOB_WORKER_MAXIMUM_COUNT.Data; + int mainThreadIndex = JobsUtility.ThreadIndex; DetectMultipleXThreads(mainThreadIndex); return mainThreadIndex; } @@ -138,7 +112,7 @@ public static int CollectionIndexForMainThread() [Conditional("ANVIL_DEBUG_SAFETY")] private static void Debug_EnsureNativeThreadIndexIsValid(int nativeThreadIndex) { - if (nativeThreadIndex is <= 0 or > JobsUtility.MaxJobThreadCount) + if (nativeThreadIndex < 0 || nativeThreadIndex > JOB_WORKER_MAXIMUM_COUNT.Data) { throw new InvalidOperationException($"Native Thread Index is {nativeThreadIndex}! Did you call {nameof(CollectionIndexForThread)} instead of {nameof(CollectionIndexForMainThread)}?"); } @@ -150,7 +124,7 @@ private static void Debug_EnsureNativeThreadIndexIsValid(int nativeThreadIndex) private static void DetectMultipleXThreads(int nativeThreadIndex) { #if ANVIL_DEBUG_SAFETY_EXPENSIVE - ThreadHelper.DetectMultipleXThreads(nativeThreadIndex, CollectionSizeForMaxThreads); + ThreadHelper.DetectMultipleXThreads(nativeThreadIndex, JOB_WORKER_MAXIMUM_COUNT.Data); #endif } } diff --git a/Scripts/Runtime/Logging/BurstableLogger.cs b/Scripts/Runtime/Logging/BurstableLogger.cs index 9477e2a9..ef9090d3 100644 --- a/Scripts/Runtime/Logging/BurstableLogger.cs +++ b/Scripts/Runtime/Logging/BurstableLogger.cs @@ -30,8 +30,7 @@ namespace Anvil.Unity.DOTS.Logging /// except for the Editor console (). /// This is a Burst limitation. /// - [BurstCompatible] - public readonly struct BurstableLogger where TPrefixStringType : struct, INativeList, IUTF8Bytes + public readonly struct BurstableLogger where TPrefixStringType : unmanaged, INativeList, IUTF8Bytes { private const int UNSET_THREAD_INDEX = -1; @@ -53,7 +52,6 @@ namespace Anvil.Unity.DOTS.Logging /// /// Thrown if there is an unknown error encountered when configuring the prefix string. /// - [NotBurstCompatible] public BurstableLogger(Logger logger, string appendToMessagePrefix) { m_ThreadIndex = UNSET_THREAD_INDEX; diff --git a/Scripts/Runtime/Logging/BurstableLoggerExtension.cs b/Scripts/Runtime/Logging/BurstableLoggerExtension.cs index 3a690de4..78d6d01f 100644 --- a/Scripts/Runtime/Logging/BurstableLoggerExtension.cs +++ b/Scripts/Runtime/Logging/BurstableLoggerExtension.cs @@ -35,7 +35,7 @@ public static BurstableLogger AsBurstable(this in Logger log /// /// A instance. public static BurstableLogger AsBurstable(this in Logger logger, string appendToMessagePrefix = null) - where TPrefixStringType : struct, INativeList, IUTF8Bytes + where TPrefixStringType : unmanaged, INativeList, IUTF8Bytes { return new BurstableLogger(logger, appendToMessagePrefix); } diff --git a/Scripts/Runtime/anvil-unity-dots-runtime.asmdef b/Scripts/Runtime/anvil-unity-dots-runtime.asmdef index b525c277..5214a2e6 100644 --- a/Scripts/Runtime/anvil-unity-dots-runtime.asmdef +++ b/Scripts/Runtime/anvil-unity-dots-runtime.asmdef @@ -7,7 +7,6 @@ "Unity.Burst", "Unity.Collections", "Unity.Entities", - "Unity.Jobs", "Unity.Mathematics", "Unity.Transforms", "Unity.Profiling.Core"