internal static void PrepareComponentGroup(ComponentSystemBase system, Type jobType) { ComponentType[] typeArray; int num; Type iJobProcessComponentDataInterface = GetIJobProcessComponentDataInterface(jobType); ComponentType[] componentTypes = GetComponentTypes(jobType, iJobProcessComponentDataInterface, out num, out typeArray); system.GetComponentGroupInternal(componentTypes); }
static void PrepareComponentGroup(ComponentSystemBase system, Type jobType) { var iType = GetIJobProcessComponentDataInterface(jobType); ComponentType[] filterChanged; int processTypesCount; var types = GetComponentTypes(jobType, iType, out processTypesCount, out filterChanged); system.GetComponentGroupInternal(types); }
private unsafe InjectComponentGroupData(ComponentSystemBase system, FieldInfo groupField, InjectionData[] componentDataInjections, InjectionData[] bufferArrayInjections, InjectionData[] sharedComponentInjections, FieldInfo entityArrayInjection, FieldInfo indexFromEntityInjection, InjectionContext injectionContext, FieldInfo lengthInjection, FieldInfo componentGroupIndexField, ComponentType[] componentRequirements) { m_EntityGroup = system.GetComponentGroupInternal(componentRequirements); m_ComponentGroupIndex = Array.IndexOf(system.ComponentGroups, m_EntityGroup); m_ComponentDataInjections = componentDataInjections; m_BufferArrayInjections = bufferArrayInjections; m_SharedComponentInjections = sharedComponentInjections; m_InjectionContext = injectionContext; PatchGetIndexInComponentGroup(m_ComponentDataInjections); PatchGetIndexInComponentGroup(m_BufferArrayInjections); PatchGetIndexInComponentGroup(m_SharedComponentInjections); injectionContext.PrepareEntries(m_EntityGroup); if (entityArrayInjection != null) { m_EntityArrayOffset = UnsafeUtility.GetFieldOffset(entityArrayInjection); } else { m_EntityArrayOffset = -1; } if (lengthInjection != null) { m_LengthOffset = UnsafeUtility.GetFieldOffset(lengthInjection); } else { m_LengthOffset = -1; } m_GroupFieldOffset = UnsafeUtility.GetFieldOffset(groupField); if (componentGroupIndexField != null) { ulong gchandle; var pinnedSystemPtr = (byte *)UnsafeUtility.PinGCObjectAndGetAddress(system, out gchandle); var groupIndexPtr = pinnedSystemPtr + m_GroupFieldOffset + UnsafeUtility.GetFieldOffset(componentGroupIndexField); int groupIndex = m_ComponentGroupIndex; UnsafeUtility.CopyStructureToPtr(ref groupIndex, groupIndexPtr); UnsafeUtility.ReleaseGCObject(gchandle); } }
public static ComponentGroup GetComponentGroupForIJobProcessComponentData(this ComponentSystemBase system, Type jobType) { var types = GetComponentTypes(jobType); if (types != null) { return(system.GetComponentGroupInternal(types)); } else { return(null); } }
InjectComponentGroupData(ComponentSystemBase system, FieldInfo groupField, InjectionData[] componentDataInjections, InjectionData[] fixedArrayInjections, InjectionData[] sharedComponentInjections, FieldInfo entityArrayInjection, FieldInfo indexFromEntityInjection, InjectionContext injectionContext, FieldInfo lengthInjection, ComponentType[] componentRequirements) { m_EntityGroup = system.GetComponentGroupInternal(componentRequirements); m_ComponentDataInjections = componentDataInjections; m_FixedArrayInjections = fixedArrayInjections; m_SharedComponentInjections = sharedComponentInjections; m_InjectionContext = injectionContext; PatchGetIndexInComponentGroup(m_ComponentDataInjections); PatchGetIndexInComponentGroup(m_FixedArrayInjections); PatchGetIndexInComponentGroup(m_SharedComponentInjections); injectionContext.PrepareEntries(m_EntityGroup); if (entityArrayInjection != null) { m_EntityArrayOffset = UnsafeUtility.GetFieldOffset(entityArrayInjection); } else { m_EntityArrayOffset = -1; } if (indexFromEntityInjection != null) { m_IndexFromEntityOffset = UnsafeUtility.GetFieldOffset(indexFromEntityInjection); } else { m_IndexFromEntityOffset = -1; } if (lengthInjection != null) { m_LengthOffset = UnsafeUtility.GetFieldOffset(lengthInjection); } else { m_LengthOffset = -1; } m_GroupFieldOffset = UnsafeUtility.GetFieldOffset(groupField); }
private unsafe InjectComponentGroupData(ComponentSystemBase system, FieldInfo groupField, InjectionData[] componentDataInjections, InjectionData[] bufferArrayInjections, InjectionData[] sharedComponentInjections, FieldInfo entityArrayInjection, FieldInfo indexFromEntityInjection, InjectionContext injectionContext, FieldInfo lengthInjection, FieldInfo componentGroupIndexField, ComponentType[] componentRequirements) { this.m_EntityGroup = system.GetComponentGroupInternal(componentRequirements); this.m_ComponentGroupIndex = Array.IndexOf <ComponentGroup>(system.ComponentGroups, this.m_EntityGroup); this.m_ComponentDataInjections = componentDataInjections; this.m_BufferArrayInjections = bufferArrayInjections; this.m_SharedComponentInjections = sharedComponentInjections; this.m_InjectionContext = injectionContext; this.PatchGetIndexInComponentGroup(this.m_ComponentDataInjections); this.PatchGetIndexInComponentGroup(this.m_BufferArrayInjections); this.PatchGetIndexInComponentGroup(this.m_SharedComponentInjections); injectionContext.PrepareEntries(this.m_EntityGroup); if (entityArrayInjection != null) { this.m_EntityArrayOffset = UnsafeUtility.GetFieldOffset(entityArrayInjection); } else { this.m_EntityArrayOffset = -1; } if (lengthInjection != null) { this.m_LengthOffset = UnsafeUtility.GetFieldOffset(lengthInjection); } else { this.m_LengthOffset = -1; } this.m_GroupFieldOffset = UnsafeUtility.GetFieldOffset(groupField); if (componentGroupIndexField != null) { ulong num; UnsafeUtility.CopyStructureToPtr <int>(ref this.m_ComponentGroupIndex, (UnsafeUtility.PinGCObjectAndGetAddress(system, out num) + this.m_GroupFieldOffset) + UnsafeUtility.GetFieldOffset(componentGroupIndexField)); UnsafeUtility.ReleaseGCObject(num); } }
public ComponentGroupArrayStaticCache(Type type, EntityManager entityManager, ComponentSystemBase system) { var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var componentFieldOffsetsBuilder = new List <int>(); var componentTypesBuilder = new List <ComponentType>(); var componentDataFieldOffsetsBuilder = new List <int>(); var componentDataTypesBuilder = new List <ComponentType>(); var subtractiveComponentTypesBuilder = new List <ComponentType>(); foreach (var field in fields) { var fieldType = field.FieldType; var offset = UnsafeUtility.GetFieldOffset(field); if (fieldType.IsPointer) { var isReadOnly = field.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0; var accessMode = isReadOnly ? ComponentType.AccessMode.ReadOnly : ComponentType.AccessMode.ReadWrite; var elementType = fieldType.GetElementType(); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!typeof(IComponentData).IsAssignableFrom(elementType) && elementType != typeof(Entity)) { throw new ArgumentException( $"{type}.{field.Name} is a pointer type but not a IComponentData. Only IComponentData or Entity may be a pointer type for enumeration."); } #endif componentDataFieldOffsetsBuilder.Add(offset); componentDataTypesBuilder.Add(new ComponentType(elementType, accessMode)); } else if (TypeManager.UnityEngineComponentType?.IsAssignableFrom(fieldType) ?? false) { componentFieldOffsetsBuilder.Add(offset); componentTypesBuilder.Add(fieldType); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>)) { subtractiveComponentTypesBuilder.Add(ComponentType.Subtractive(fieldType.GetGenericArguments()[0])); } #if ENABLE_UNITY_COLLECTIONS_CHECKS else if (typeof(IComponentData).IsAssignableFrom(fieldType)) { throw new ArgumentException( $"{type}.{field.Name} must be an unsafe pointer to the {fieldType}. Like this: {fieldType}* {field.Name};"); } else { throw new ArgumentException($"{type}.{field.Name} can not be used in a component enumerator"); } #endif } #if ENABLE_UNITY_COLLECTIONS_CHECKS if (componentTypesBuilder.Count + componentDataTypesBuilder.Count > ComponentGroupArrayData.kMaxStream) { throw new ArgumentException( $"{type} has too many component references. A ComponentGroup Array can have up to {ComponentGroupArrayData.kMaxStream}."); } #endif ComponentDataCount = componentDataTypesBuilder.Count; ComponentCount = componentTypesBuilder.Count; componentDataTypesBuilder.AddRange(componentTypesBuilder); componentDataTypesBuilder.AddRange(subtractiveComponentTypesBuilder); ComponentTypes = componentDataTypesBuilder.ToArray(); componentDataFieldOffsetsBuilder.AddRange(componentFieldOffsetsBuilder); ComponentFieldOffsets = componentDataFieldOffsetsBuilder.ToArray(); ComponentGroup = system.GetComponentGroupInternal(ComponentTypes); SafetyManager = entityManager.ComponentJobSafetyManager; CachedType = type; }
internal static unsafe void Initialize(ComponentSystemBase system, Type jobType, Type wrapperJobType, bool isParallelFor, ref JobProcessComponentDataCache cache, out ProcessIterationData iterator) { int num; int num1; if (!isParallelFor || !(cache.JobReflectionDataParallelFor == IntPtr.Zero)) { num1 = isParallelFor ? 0 : ((int)(cache.JobReflectionData == IntPtr.Zero)); } else { num1 = 1; } if (num1 != 0) { Type iJobProcessComponentDataInterface = GetIJobProcessComponentDataInterface(jobType); if (cache.Types == null) { cache.Types = GetComponentTypes(jobType, iJobProcessComponentDataInterface, out cache.ProcessTypesCount, out cache.FilterChanged); } IntPtr ptr = GetJobReflection(jobType, wrapperJobType, iJobProcessComponentDataInterface, isParallelFor); if (isParallelFor) { cache.JobReflectionDataParallelFor = ptr; } else { cache.JobReflectionData = ptr; } } if (cache.ComponentSystem != system) { cache.ComponentGroup = system.GetComponentGroupInternal(cache.Types); if (cache.FilterChanged.Length != 0) { cache.ComponentGroup.SetFilterChanged(cache.FilterChanged); } else { cache.ComponentGroup.ResetFilter(); } cache.ComponentSystem = system; } ComponentGroup componentGroup = cache.ComponentGroup; iterator.IsReadOnly3 = num = 0; iterator.IsReadOnly2 = num = num; iterator.IsReadOnly1 = num = num; iterator.IsReadOnly0 = num; int *numPtr = &iterator.IsReadOnly0; int index = 0; while (true) { if (index == cache.ProcessTypesCount) { fixed(int *numRef = null) { componentGroup.GetComponentChunkIterator(out iterator.Iterator); iterator.IndexInGroup3 = num = -1; iterator.IndexInGroup2 = num = num; iterator.IndexInGroup0 = iterator.IndexInGroup1 = num; int *numPtr2 = &iterator.IndexInGroup0; int num3 = 0; while (true) { if (num3 == cache.ProcessTypesCount) { fixed(int *numRef2 = null) { iterator.m_IsParallelFor = isParallelFor; iterator.m_Length = componentGroup.CalculateNumberOfChunksWithoutFiltering(); iterator.m_MaxIndex = iterator.m_Length - 1; iterator.m_MinIndex = 0; AtomicSafetyHandle handle = new AtomicSafetyHandle(); iterator.m_Safety3 = handle = handle; iterator.m_Safety2 = handle = handle; iterator.m_Safety0 = iterator.m_Safety1 = handle; iterator.m_SafetyReadOnlyCount = 0; AtomicSafetyHandle *handlePtr = &iterator.m_Safety0; int num4 = 0; while (true) { if (num4 == cache.ProcessTypesCount) { fixed(AtomicSafetyHandle *handleRef = null) { iterator.m_SafetyReadWriteCount = 0; AtomicSafetyHandle *handlePtr2 = &iterator.m_Safety0; int num5 = 0; while (true) { if (num5 == cache.ProcessTypesCount) { fixed(AtomicSafetyHandle *handleRef2 = null) { Assert.AreEqual(cache.ProcessTypesCount, iterator.m_SafetyReadWriteCount + iterator.m_SafetyReadOnlyCount); return; } } if (cache.Types[num5].AccessModeType == ComponentType.AccessMode.ReadWrite) { handlePtr2[iterator.m_SafetyReadOnlyCount + iterator.m_SafetyReadWriteCount] = componentGroup.GetSafetyHandle(componentGroup.GetIndexInComponentGroup(cache.Types[num5].TypeIndex)); int *numPtr1 = (int *)ref iterator.m_SafetyReadWriteCount; numPtr1[0]++; } num5++; } } } if (cache.Types[num4].AccessModeType == ComponentType.AccessMode.ReadOnly) { handlePtr[iterator.m_SafetyReadOnlyCount] = componentGroup.GetSafetyHandle(componentGroup.GetIndexInComponentGroup(cache.Types[num4].TypeIndex)); int *numPtr3 = (int *)ref iterator.m_SafetyReadOnlyCount; numPtr3[0]++; } num4++; } } } numPtr2[num3] = componentGroup.GetIndexInComponentGroup(cache.Types[num3].TypeIndex); num3++; } } } numPtr[index] = (cache.Types[index].AccessModeType == ComponentType.AccessMode.ReadOnly) ? 1 : 0; index++; } }
unsafe internal static void Initialize(ComponentSystemBase system, Type jobType, Type wrapperJobType, bool isParallelFor, ref JobProcessComponentDataCache cache, out ProcessIterationData iterator) { if ((isParallelFor && cache.JobReflectionDataParallelFor == IntPtr.Zero) || (!isParallelFor && cache.JobReflectionData == IntPtr.Zero)) { var iType = GetIJobProcessComponentDataInterface(jobType); if (cache.Types == null) { cache.Types = GetComponentTypes(jobType, iType, out cache.ProcessTypesCount); } var res = GetJobReflection(jobType, wrapperJobType, iType, isParallelFor); if (isParallelFor) { cache.JobReflectionDataParallelFor = res; } else { cache.JobReflectionData = res; } } if (cache.ComponentSystem != system) { cache.ComponentGroup = system.GetComponentGroupInternal(cache.Types); cache.ComponentSystem = system; } var group = cache.ComponentGroup; // Readonly iterator.IsReadOnly0 = iterator.IsReadOnly1 = iterator.IsReadOnly2 = 0; fixed(int *isReadOnly = &iterator.IsReadOnly0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { isReadOnly[i] = cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadOnly ? 1 : 0; } } // Iterator & length iterator.Iterator0 = default(ComponentChunkIterator); iterator.Iterator1 = default(ComponentChunkIterator); iterator.Iterator2 = default(ComponentChunkIterator); var length = -1; fixed(ComponentChunkIterator *iterators = &iterator.Iterator0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { group.GetComponentChunkIterator(out length, out iterators[i]); iterators[i].IndexInComponentGroup = group.GetIndexInComponentGroup(cache.Types[i].TypeIndex); } } iterator.m_IsParallelFor = isParallelFor; iterator.m_Length = length; #if ENABLE_UNITY_COLLECTIONS_CHECKS iterator.m_MaxIndex = length - 1; iterator.m_MinIndex = 0; // Safety iterator.m_Safety0 = iterator.m_Safety1 = iterator.m_Safety2 = default(AtomicSafetyHandle); iterator.m_SafetyReadOnlyCount = 0; fixed(AtomicSafetyHandle *safety = &iterator.m_Safety0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { if (cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadOnly) { safety[iterator.m_SafetyReadOnlyCount] = group.GetSafetyHandle(group.GetIndexInComponentGroup(cache.Types[i].TypeIndex)); iterator.m_SafetyReadOnlyCount++; } } } iterator.m_SafetyReadWriteCount = 0; fixed(AtomicSafetyHandle *safety = &iterator.m_Safety0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { if (cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadWrite) { safety[iterator.m_SafetyReadOnlyCount + iterator.m_SafetyReadWriteCount] = group.GetSafetyHandle(group.GetIndexInComponentGroup(cache.Types[i].TypeIndex)); iterator.m_SafetyReadWriteCount++; } } } Assert.AreEqual(cache.ProcessTypesCount, iterator.m_SafetyReadWriteCount + iterator.m_SafetyReadOnlyCount); #endif }
static unsafe void Initialize(ComponentSystemBase system, ComponentGroup componentGroup, Type jobType, Type wrapperJobType, bool isParallelFor, ref JobProcessComponentDataCache cache, out ProcessIterationData iterator) { // Get the job reflection data and cache it if we don't already have it cached. if (isParallelFor && cache.JobReflectionDataParallelFor == IntPtr.Zero || !isParallelFor && cache.JobReflectionData == IntPtr.Zero) { var iType = GetIJobProcessComponentDataInterface(jobType); if (cache.Types == null) { cache.Types = GetComponentTypes(jobType, iType, out cache.ProcessTypesCount, out cache.FilterChanged); } var res = GetJobReflection(jobType, wrapperJobType, iType, isParallelFor); if (isParallelFor) { cache.JobReflectionDataParallelFor = res; } else { cache.JobReflectionData = res; } } // Update cached ComponentGroup and ComponentSystem data. if (system != null) { if (cache.ComponentSystem != system) { cache.ComponentGroup = system.GetComponentGroupInternal(cache.Types); // If the cached filter has changed, update the newly cached ComponentGroup with those changes. if (cache.FilterChanged.Length != 0) { cache.ComponentGroup.SetFilterChanged(cache.FilterChanged); } // Otherwise, just reset our newly cached ComponentGroup's filter. else { cache.ComponentGroup.ResetFilter(); } cache.ComponentSystem = system; } } else if (componentGroup != null) { if (cache.ComponentGroup != componentGroup) { // Cache the new ComponentGroup and cache that our system is null. cache.ComponentGroup = componentGroup; cache.ComponentSystem = null; } } var group = cache.ComponentGroup; iterator.IsReadOnly0 = iterator.IsReadOnly1 = iterator.IsReadOnly2 = iterator.IsReadOnly3 = iterator.IsReadOnly4 = iterator.IsReadOnly5 = 0; fixed(int *isReadOnly = &iterator.IsReadOnly0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { isReadOnly[i] = cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadOnly ? 1 : 0; } } iterator.TypeIndex0 = iterator.TypeIndex1 = iterator.TypeIndex2 = iterator.TypeIndex3 = iterator.TypeIndex4 = iterator.TypeIndex5 = -1; fixed(int *typeIndices = &iterator.TypeIndex0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { typeIndices[i] = cache.Types[i].TypeIndex; } } iterator.m_IsParallelFor = isParallelFor; iterator.m_Length = group.CalculateNumberOfChunksWithoutFiltering(); iterator.GlobalSystemVersion = group.GetComponentChunkIterator().m_GlobalSystemVersion; #if ENABLE_UNITY_COLLECTIONS_CHECKS iterator.m_MaxIndex = iterator.m_Length - 1; iterator.m_MinIndex = 0; iterator.m_Safety0 = iterator.m_Safety1 = iterator.m_Safety2 = iterator.m_Safety3 = iterator.m_Safety4 = iterator.m_Safety5 = default(AtomicSafetyHandle); iterator.m_SafetyReadOnlyCount = 0; fixed(AtomicSafetyHandle *safety = &iterator.m_Safety0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { if (cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadOnly) { safety[iterator.m_SafetyReadOnlyCount] = group.GetSafetyHandle(group.GetIndexInComponentGroup(cache.Types[i].TypeIndex)); iterator.m_SafetyReadOnlyCount++; } } } iterator.m_SafetyReadWriteCount = 0; fixed(AtomicSafetyHandle *safety = &iterator.m_Safety0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { if (cache.Types[i].AccessModeType == ComponentType.AccessMode.ReadWrite) { safety[iterator.m_SafetyReadOnlyCount + iterator.m_SafetyReadWriteCount] = group.GetSafetyHandle(group.GetIndexInComponentGroup(cache.Types[i].TypeIndex)); iterator.m_SafetyReadWriteCount++; } } } Assert.AreEqual(cache.ProcessTypesCount, iterator.m_SafetyReadWriteCount + iterator.m_SafetyReadOnlyCount); #endif }
public ComponentGroupArrayStaticCache(Type type, EntityManager entityManager, ComponentSystemBase system) { List <int> collection = new List <int>(); List <ComponentType> list2 = new List <ComponentType>(); List <int> list3 = new List <int>(); List <ComponentType> list4 = new List <ComponentType>(); List <ComponentType> list5 = new List <ComponentType>(); foreach (FieldInfo info in type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { Type fieldType = info.FieldType; int fieldOffset = UnsafeUtility.GetFieldOffset(info); if (fieldType.IsPointer) { ComponentType.AccessMode accessModeType = (info.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0) ? ComponentType.AccessMode.ReadOnly : ComponentType.AccessMode.ReadWrite; Type elementType = fieldType.GetElementType(); if (!typeof(IComponentData).IsAssignableFrom(elementType) && (elementType != typeof(Entity))) { throw new ArgumentException($"{type}.{info.Name} is a pointer type but not a IComponentData. Only IComponentData or Entity may be a pointer type for enumeration."); } list3.Add(fieldOffset); list4.Add(new ComponentType(elementType, accessModeType)); } else { bool flag1; if (TypeManager.UnityEngineComponentType != null) { flag1 = TypeManager.UnityEngineComponentType.IsAssignableFrom(fieldType); } else { object unityEngineComponentType = TypeManager.UnityEngineComponentType; flag1 = false; } if (flag1) { collection.Add(fieldOffset); list2.Add(fieldType); } else { if (!(fieldType.IsGenericType && (fieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>)))) { if (!typeof(IComponentData).IsAssignableFrom(fieldType)) { throw new ArgumentException($"{type}.{info.Name} can not be used in a component enumerator"); } throw new ArgumentException($"{type}.{info.Name} must be an unsafe pointer to the {fieldType}. Like this: {fieldType}* {info.Name};"); } list5.Add(ComponentType.Subtractive(fieldType.GetGenericArguments()[0])); } } } if ((list2.Count + list4.Count) > 6) { throw new ArgumentException($"{type} has too many component references. A ComponentGroup Array can have up to {6}."); } this.ComponentDataCount = list4.Count; this.ComponentCount = list2.Count; list4.AddRange(list2); list4.AddRange(list5); this.ComponentTypes = list4.ToArray(); list3.AddRange(collection); this.ComponentFieldOffsets = list3.ToArray(); this.ComponentGroup = system.GetComponentGroupInternal(this.ComponentTypes); this.SafetyManager = entityManager.ComponentJobSafetyManager; this.CachedType = type; }