public object GetComponentBoxed(Entity entity, ComponentType type) { m_Manager.EntityComponentStore->AssertEntityHasComponent(entity, type); var typeInfo = TypeManager.GetTypeInfo(type.TypeIndex); if (typeInfo.Category == TypeManager.TypeCategory.ComponentData) { var obj = Activator.CreateInstance(TypeManager.GetType(type.TypeIndex)); if (!typeInfo.IsZeroSized) { ulong handle; var ptr = (byte *)UnsafeUtility.PinGCObjectAndGetAddress(obj, out handle); ptr += TypeManager.ObjectOffset; var src = m_Manager.EntityComponentStore->GetComponentDataWithTypeRO(entity, type.TypeIndex); UnsafeUtility.MemCpy(ptr, src, TypeManager.GetTypeInfo(type.TypeIndex).SizeInChunk); UnsafeUtility.ReleaseGCObject(handle); } return(obj); } else if (typeInfo.Category == TypeManager.TypeCategory.ISharedComponentData) { return(m_Manager.GetSharedComponentData(entity, type.TypeIndex)); } else { throw new System.NotImplementedException(); } }
public object GetSharedComponentDataBoxed(int index, int typeIndex) { if (index == 0) { return(Activator.CreateInstance(TypeManager.GetType(typeIndex))); } return(m_SharedComponentData[index]); }
internal unsafe void SetComponentDataRaw(Entity entity, int typeIndex, void *data, int size) { this.Entities.AssertEntityHasComponent(entity, typeIndex); this.ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex); if (TypeManager.GetTypeInfo(typeIndex).SizeInChunk != size) { throw new ArgumentException($"SetComponentDataRaw<{TypeManager.GetType(typeIndex)}> can not be called with a zero sized component and must have same size as sizeof(T)."); } UnsafeUtility.MemCpy((void *)this.Entities.GetComponentDataWithTypeRW(entity, typeIndex, this.Entities.GlobalSystemVersion), data, (long)size); }
internal unsafe void *GetComponentDataRawRW(Entity entity, int typeIndex) { this.Entities.AssertEntityHasComponent(entity, typeIndex); this.ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex); if (TypeManager.GetTypeInfo(typeIndex).IsZeroSized) { throw new ArgumentException($"GetComponentDataRaw<{TypeManager.GetType(typeIndex)}> can not be called with a zero sized component."); } return((void *)ref this.Entities.GetComponentDataWithTypeRW(entity, typeIndex, this.Entities.GlobalSystemVersion)); }
/// <summary> /// /// </summary> /// <param name="chunkComponentType"></param> /// <param name="expectedTypeSize"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException"></exception> public NativeArray <T> GetDynamicComponentDataArrayReinterpret <T>(ArchetypeChunkComponentTypeDynamic chunkComponentType, int expectedTypeSize) where T : struct { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (chunkComponentType.m_IsZeroSized) { throw new ArgumentException($"ArchetypeChunk.GetDynamicComponentDataArrayReinterpret<{typeof(T)}> cannot be called on zero-sized IComponentData"); } AtomicSafetyHandle.CheckReadAndThrow(chunkComponentType.m_Safety); #endif var archetype = m_Chunk->Archetype; int typeIndexInArchetype = chunkComponentType.m_TypeLookupCache; ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref typeIndexInArchetype); chunkComponentType.m_TypeLookupCache = (short)typeIndexInArchetype; if (typeIndexInArchetype == -1) { var emptyResult = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(null, 0, 0); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref emptyResult, chunkComponentType.m_Safety); #endif return(emptyResult); } var typeSize = archetype->SizeOfs[typeIndexInArchetype]; var length = m_Chunk->Count; var byteLen = length * typeSize; var outTypeSize = UnsafeUtility.SizeOf <T>(); var outLength = byteLen / outTypeSize; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (typeSize != expectedTypeSize) { throw new InvalidOperationException($"Dynamic chunk component type {TypeManager.GetType(chunkComponentType.m_TypeIndex)} (size = {typeSize}) size does not equal {expectedTypeSize}. Component size must match with expectedTypeSize."); } if (outTypeSize * outLength != byteLen) { throw new InvalidOperationException($"Dynamic chunk component type {TypeManager.GetType(chunkComponentType.m_TypeIndex)} (array length {length}) and {typeof(T)} cannot be aliased due to size constraints. The size of the types and lengths involved must line up."); } #endif var buffer = m_Chunk->Buffer; var startOffset = archetype->Offsets[typeIndexInArchetype]; var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buffer + startOffset, outLength, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, chunkComponentType.m_Safety); #endif if (!chunkComponentType.IsReadOnly) { m_Chunk->SetChangeVersion(typeIndexInArchetype, chunkComponentType.GlobalSystemVersion); } return(result); }
public object GetSharedComponentDataBoxed(int index, int typeIndex) { #if !NET_DOTS if (index == 0) return Activator.CreateInstance(TypeManager.GetType(typeIndex)); #else if (index == 0) throw new InvalidOperationException("Implement TypeManager.GetType(typeIndex).DefaultValue"); #endif return m_SharedComponentData[index]; }
internal void SetComponentBoxed(Entity entity, ComponentType componentType, object boxedObject) { var type = TypeManager.GetType(componentType.TypeIndex); ulong gcHandle; byte *boxedPtr = (byte *)UnsafeUtility.PinGCObjectAndGetAddress(boxedObject, out gcHandle); //@TODO: harcoded object class sizeof hack SetComponentDataRaw(entity, componentType.TypeIndex, boxedPtr + 16, UnsafeUtility.SizeOf(type)); UnsafeUtility.ReleaseGCObject(gcHandle); }
IComponentProperty GetOrCreatePropertyForType(int typeIndex, bool isReadOnly) { var cache = isReadOnly ? m_ReadOnlyPropertyCache : m_ReadWritePropertyCache; if (cache.TryGetValue(typeIndex, out var property)) { return(property); } m_ComponentPropertyConstructor.TypeIndex = typeIndex; m_ComponentPropertyConstructor.IsReadOnly = isReadOnly; PropertyBagStore.GetPropertyBag(TypeManager.GetType(typeIndex)).Accept(m_ComponentPropertyConstructor); cache.Add(typeIndex, m_ComponentPropertyConstructor.Property); return(m_ComponentPropertyConstructor.Property); }
public List <Type> GetAssignableComponentTypes(Type interfaceType) { int typeCount = TypeManager.GetTypeCount(); List <Type> list = new List <Type>(); for (int i = 0; i < typeCount; i++) { Type c = TypeManager.GetType(i); if (interfaceType.IsAssignableFrom(c)) { list.Add(c); } } return(list); }
public static int GetTypeIndexFromType(Archetype *archetype, Type componentType) { var types = archetype->Types; var typeCount = archetype->TypesCount; for (var i = 0; i != typeCount; i++) { if (componentType.IsAssignableFrom(TypeManager.GetType(types[i].TypeIndex))) { return(types[i].TypeIndex); } } return(-1); }
public SharedComponentDataManager() { var actualCount = TypeManager.GetTypeCount() - SharedComponentTypeStart; dataArray = new Element[actualCount]; for (int i = 0; i < dataArray.Length; i++) { var type = TypeManager.GetType(i + SharedComponentTypeStart); if (!ISharedComponentDataType.IsAssignableFrom(type) || !type.IsValueType) { continue; } dataArray[i] = Element.Create(128, type); } }
internal string FormatToString(FixedString64 systemTypeName) { int type = m_ProblematicTypeIndex; AtomicSafetyHandle h = m_ProblematicHandle; if (!IsWrite) { int i = m_ReaderIndex; return($"The system {systemTypeName} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method."); } else { return($"The system {systemTypeName} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method."); } }
public object GetSharedComponentDataBoxed(int index, int typeIndex) { #if !UNITY_CSHARP_TINY if (index == 0) { return(Activator.CreateInstance(TypeManager.GetType(typeIndex))); } #else if (index == 0) { throw new InvalidOperationException("Implement TypeManager.GetType(typeIndex).DefaultValue"); } throw new NotImplementedException("SharedComponents not supported (yet) in Tiny"); #endif return(m_SharedComponentData[index]); }
/// <summary> /// Packed array of this ComponentGroup's ReadOnly and writable ComponentTypes. /// ReadOnly ComponentTypes come before writable types in this array. /// </summary> /// <returns>Array of ComponentTypes</returns> internal ComponentType[] GetReadAndWriteTypes() { var types = new ComponentType[m_GroupData->ReaderTypesCount + m_GroupData->WriterTypesCount]; var typeArrayIndex = 0; for (var i = 0; i < m_GroupData->ReaderTypesCount; ++i) { types[typeArrayIndex++] = ComponentType.ReadOnly(TypeManager.GetType(m_GroupData->ReaderTypes[i])); } for (var i = 0; i < m_GroupData->WriterTypesCount; ++i) { types[typeArrayIndex++] = TypeManager.GetType(m_GroupData->WriterTypes[i]); } return(types); }
public List <Type> GetAssignableComponentTypes(Type interfaceType, List <Type> listOut) { // #todo Cache this. It only can change when TypeManager.GetTypeCount() changes var componentTypeCount = TypeManager.GetTypeCount(); for (var i = 0; i < componentTypeCount; i++) { var type = TypeManager.GetType(i); if (interfaceType.IsAssignableFrom(type)) { listOut.Add(type); } } return(listOut); }
internal void SetComponentDataRaw(Entity entity, int typeIndex, void *data, int size) { Entities->AssertEntityHasComponent(entity, typeIndex); ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (TypeManager.GetTypeInfo(typeIndex).SizeInChunk != size) { throw new System.ArgumentException($"SetComponentDataRaw<{TypeManager.GetType(typeIndex)}> can not be called with a zero sized component and must have same size as sizeof(T)."); } #endif var ptr = Entities->GetComponentDataWithTypeRW(entity, typeIndex, Entities->GlobalSystemVersion); UnsafeUtility.MemCpy(ptr, data, size); }
public void Execute(int index) { var typeHash = TypeHashes[index]; var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(typeHash.StableTypeHash); var type = TypeManager.GetType(typeIndex); ComponentType componentType; if ((typeHash.Flags & ComponentTypeFlags.ChunkComponent) == ComponentTypeFlags.ChunkComponent) { componentType = ComponentType.ChunkComponent(type); } else { componentType = new ComponentType(type); } PackedTypes[index] = componentType; }
internal void *GetComponentDataRawRW(Entity entity, int typeIndex) { Entities->AssertEntityHasComponent(entity, typeIndex); ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (TypeManager.GetTypeInfo(typeIndex).IsZeroSized) { throw new System.ArgumentException($"GetComponentDataRaw<{TypeManager.GetType(typeIndex)}> can not be called with a zero sized component."); } #endif var ptr = Entities->GetComponentDataWithTypeRW(entity, typeIndex, Entities->GlobalSystemVersion); return(ptr); }
internal int GetIndexInComponentGroup(int componentType) { var componentIndex = 0; while (componentIndex < m_GroupData->RequiredComponentsCount && m_GroupData->RequiredComponents[componentIndex].TypeIndex != componentType) { ++componentIndex; } #if ENABLE_UNITY_COLLECTIONS_CHECKS if (componentIndex >= m_GroupData->RequiredComponentsCount) { throw new InvalidOperationException($"Trying to get iterator for {TypeManager.GetType(componentType)} but the required component type was not declared in the EntityGroup."); } #endif return(componentIndex); }
internal object GetComponentBoxed(Entity entity, ComponentType componentType) { var ptr = GetComponentDataRaw(entity, componentType.TypeIndex); var type = TypeManager.GetType(componentType.TypeIndex); var boxed = Activator.CreateInstance(type); ulong gcHandle; byte *boxedPtr = (byte *)UnsafeUtility.PinGCObjectAndGetAddress(boxed, out gcHandle); //@TODO: harcoded object class sizeof hack UnsafeUtility.MemCpy(boxedPtr + 16, ptr, UnsafeUtility.SizeOf(type)); UnsafeUtility.ReleaseGCObject(gcHandle); return(boxed); }
private void ReAlloc(int requiredComponentTypeIndexNotModified) { var oldLength = dataArray.Length; if (requiredComponentTypeIndexNotModified < oldLength + SharedComponentTypeStart) { return; } var currentActualLength = TypeManager.GetTypeCount() - SharedComponentTypeStart; for (int i = currentActualLength - 1; i >= oldLength; --i) { var type = TypeManager.GetType(i + SharedComponentTypeStart); if (!type.IsValueType || !ISharedComponentDataType.IsAssignableFrom(type)) { continue; } var tmp = new Element[i + 1]; Buffer.BlockCopy(dataArray, 0, tmp, 0, dataArray.Length); dataArray = tmp; dataArray[i] = Element.Create(128, type); break; } for (int i = dataArray.Length - 2; i >= oldLength; --i) { var type = TypeManager.GetType(i + SharedComponentTypeStart); if (!ISharedComponentDataType.IsAssignableFrom(type) || !type.IsValueType || (type.IsGenericType && type.IsGenericTypeDefinition)) { continue; } #if REF_EQUATABLE var EqualsMethodInfo = type.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, null, CallingConventions.Any, EqualsTypeArray, null); if (EqualsMethodInfo == null || EqualsMethodInfo.DeclaringType != type) { throw new Exception(type.FullName); } var GetHashCodeMethodInfo = type.GetMethod("GetHashCode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, null, CallingConventions.Any, Array.Empty <Type>(), null); if (GetHashCodeMethodInfo == null || GetHashCodeMethodInfo.DeclaringType != type) { throw new Exception(type.FullName); } #endif dataArray[i] = Element.Create(128, type); } }
private bool ArchetypeSystemStateCleanupNeeded(Archetype *archetype) { for (var t = 1; t < archetype->TypesCount; ++t) { var typeIndex = archetype->Types[t].TypeIndex; var systemStateType = typeof(ISystemStateComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex)); var systemStateSharedType = typeof(ISystemStateSharedComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex)); if (systemStateType || systemStateSharedType) { return(true); } } return(false); }
/// <summary> /// Index of a ComponentType in this EntityQuery's RequiredComponents list. /// For example, you have a EntityQuery that requires these ComponentTypes: Position, Velocity, and Color. /// /// These are their type indices (according to the TypeManager): /// Position.TypeIndex == 3 /// Velocity.TypeIndex == 5 /// Color.TypeIndex == 17 /// /// RequiredComponents: [Position -> Velocity -> Color] (a linked list) /// Given Velocity's TypeIndex (5), the return value would be 1, since Velocity is in slot 1 of RequiredComponents. /// </summary> /// <param name="componentType">Index of a ComponentType in the TypeManager</param> /// <returns>An index into RequiredComponents.</returns> internal int GetIndexInEntityQuery(int componentType) { // Go through all the required component types in this EntityQuery until you find the matching component type index. var componentIndex = 0; while (componentIndex < m_QueryData->RequiredComponentsCount && m_QueryData->RequiredComponents[componentIndex].TypeIndex != componentType) { ++componentIndex; } #if ENABLE_UNITY_COLLECTIONS_CHECKS if (componentIndex >= m_QueryData->RequiredComponentsCount || m_QueryData->RequiredComponents[componentIndex].AccessModeType == ComponentType.AccessMode.Exclude) { throw new InvalidOperationException($"Trying to get iterator for {TypeManager.GetType(componentType)} but the required component type was not declared in the EntityGroup."); } #endif return(componentIndex); }
public void Validate() { // Determine the number of ComponentTypes contained in the filters var itemCount = None.Length + All.Length + Any.Length; // Project all the ComponentType Ids of None, All, Any queryDesc filters into the same array to identify duplicated later on // Also, check that queryDesc doesn't contain any ExcludeComponent... var allComponentTypeIds = new NativeArray <int>(itemCount, Allocator.Temp); var curComponentTypeIndex = 0; ValidateComponentTypes(None, ref allComponentTypeIds, ref curComponentTypeIndex); ValidateComponentTypes(All, ref allComponentTypeIds, ref curComponentTypeIndex); ValidateComponentTypes(Any, ref allComponentTypeIds, ref curComponentTypeIndex); // Check for duplicate, only if necessary if (itemCount > 1) { // Sort the Ids to have identical value adjacent allComponentTypeIds.Sort(); // Check for identical values var refId = allComponentTypeIds[0]; for (int i = 1; i < allComponentTypeIds.Length; i++) { var curId = allComponentTypeIds[i]; if (curId == refId) { #if NET_DOTS throw new EntityQueryDescValidationException( $"EntityQuery contains a filter with duplicate component type index {curId}. Queries can only contain a single component of a given type in a filter."); #else var compType = TypeManager.GetType(curId); throw new EntityQueryDescValidationException( $"EntityQuery contains a filter with duplicate component type name {compType.Name}. Queries can only contain a single component of a given type in a filter."); #endif } refId = curId; } } }
public object GetSharedComponentDataBoxed(int index) { try { if (index == 0) { return(Activator.CreateInstance(TypeManager.GetType(m_SharedComponentType[index]))); } } catch { Debug.Log(index.ToString()); for (int i = 0; i < m_SharedComponentType.Length; i++) { Debug.Log(i + ":xxx:" + m_SharedComponentType[i]); } throw; } return(m_SharedComponentData[index]); }
static SharedComponentDataManager() { TypeManager.Initialize(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); ISharedComponentDataType = typeof(ISharedComponentData); for (int i = 0; i < assemblies.Length; ++i) { var types = assemblies[i].GetTypes(); for (int j = 0; j < types.Length; ++j) { if (!types[j].IsValueType || !ISharedComponentDataType.IsAssignableFrom(types[j]) || (types[j].IsGenericType && types[j].IsGenericTypeDefinition)) { continue; } TypeManager.GetTypeIndex(types[j]); } } for (int i = 1, length = TypeManager.GetTypeCount(); i < length; ++i) { var type = TypeManager.GetType(i); if (!type.IsValueType || !ISharedComponentDataType.IsAssignableFrom(type) || (type.IsGenericType && type.IsGenericTypeDefinition)) { continue; } #if REF_EQUATABLE var EqualsMethodInfo = type.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, null, CallingConventions.Any, EqualsTypeArray, null); if (EqualsMethodInfo == null || EqualsMethodInfo.DeclaringType != type) { throw new Exception(type.FullName); } var GetHashCodeMethodInfo = type.GetMethod("GetHashCode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, null, CallingConventions.Any, Array.Empty <Type>(), null); if (GetHashCodeMethodInfo == null || GetHashCodeMethodInfo.DeclaringType != type) { throw new Exception(type.FullName); } #endif SharedComponentTypeStart = i; break; } }
public static Components GetComponents(EntityManager m, Entity e) { Components components = new Components(); components.entity = e; components.components = new List <object>(); if (!m.Exists(e)) { return(components); } #if UNITY_EDITOR components.name = m.GetName(e); components.components.Add(components.name); #endif var access = m.GetCheckedEntityDataAccess(); var ecs = access->EntityComponentStore; ecs->GetChunk(e, out var chunk, out var chunkIndex); if (chunk == null) { return(components); } var archetype = chunk->Archetype; var types = chunk->Archetype->TypesCount; for (var i = 0; i < types; ++i) { var componentType = chunk->Archetype->Types[i]; if (componentType.IsSharedComponent) { continue; } var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex); var type = TypeManager.GetType(typeInfo.TypeIndex); var offset = archetype->Offsets[i]; var size = archetype->SizeOfs[i]; var pointer = chunk->Buffer + (offset + size * chunkIndex); components.components.Add(GetComponent(pointer, type)); } return(components); }
static string CheckJobDependencies(object system, int type, ComponentDependencyManager *dependencyManager) { var h = dependencyManager->Safety.GetSafetyHandle(type, true); var readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero); JobHandle *readers = stackalloc JobHandle[readerCount]; AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers); for (var i = 0; i < readerCount; ++i) { if (!dependencyManager->HasReaderOrWriterDependency(type, readers[i])) { if (IsSystemV1(system)) { return($"The system {system.GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method."); } else { return($"The system {system.GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method."); } } } if (!dependencyManager->HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(h))) { if (IsSystemV1(system)) { return($"The system {system.GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method."); } else { return($"The system {system.GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method."); } } return(null); }
/// <summary> /// Gets array of all ComponentTypes in this ComponentGroup's ArchetypeQueries. /// </summary> /// <returns>Array of ComponentTypes</returns> internal ComponentType[] GetQueryTypes() { #if !UNITY_CSHARP_TINY var types = new HashSet <ComponentType>(); #else var types = new SlowListSet <ComponentType>(); #endif for (var i = 0; i < m_GroupData->ArchetypeQueryCount; ++i) { for (var j = 0; j < m_GroupData->ArchetypeQuery[i].AnyCount; ++j) { types.Add(TypeManager.GetType(m_GroupData->ArchetypeQuery[i].Any[j])); } for (var j = 0; j < m_GroupData->ArchetypeQuery[i].AllCount; ++j) { types.Add(TypeManager.GetType(m_GroupData->ArchetypeQuery[i].All[j])); } for (var j = 0; j < m_GroupData->ArchetypeQuery[i].NoneCount; ++j) { types.Add(ComponentType.Subtractive(TypeManager.GetType(m_GroupData->ArchetypeQuery[i].None[j]))); } } #if !UNITY_CSHARP_TINY var array = new ComponentType[types.Count]; var t = 0; foreach (var type in types) { array[t++] = type; } return(array); #else return(types.ToArray()); #endif }
unsafe string CheckJobDependencies(int type) { var h = m_SafetyManager.GetSafetyHandle(type, true); var readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero); JobHandle *readers = stackalloc JobHandle[readerCount]; AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers); for (var i = 0; i < readerCount; ++i) { if (!m_SafetyManager.HasReaderOrWriterDependency(type, readers[i])) { return($"The system {GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method."); } } if (!m_SafetyManager.HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(h))) { return($"The system {GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method."); } return(null); }