static unsafe void Initialize(ComponentSystemBase system, EntityQuery entityQuery, Type jobType, Type wrapperJobType, bool isParallelFor, ref JobForEachCache 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 = GetIJobForEachInterface(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 EntityQuery and ComponentSystem data. if (system != null) { if (cache.ComponentSystem != system) { cache.EntityQuery = system.GetEntityQueryInternal(cache.Types); // If the cached filter has changed, update the newly cached EntityQuery with those changes. if (cache.FilterChanged.Length != 0) { cache.EntityQuery.SetFilterChanged(cache.FilterChanged); } // Otherwise, just reset our newly cached EntityQuery's filter. else { cache.EntityQuery.ResetFilter(); } cache.ComponentSystem = system; } } else if (entityQuery != null) { if (cache.EntityQuery != entityQuery) { // Cache the new EntityQuery and cache that our system is null. cache.EntityQuery = entityQuery; cache.ComponentSystem = null; } } var query = cache.EntityQuery; 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 = query.CalculateNumberOfChunksWithoutFiltering(); iterator.GlobalSystemVersion = query.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] = query.GetSafetyHandle(query.GetIndexInEntityQuery(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] = query.GetSafetyHandle(query.GetIndexInEntityQuery(cache.Types[i].TypeIndex)); iterator.m_SafetyReadWriteCount++; } } } Assert.AreEqual(cache.ProcessTypesCount, iterator.m_SafetyReadWriteCount + iterator.m_SafetyReadOnlyCount); #endif }
//NOTE: It would be much better if C# could resolve the branch with generic resolving, // but apparently the interface constraint is not enough.. public static void PrepareEntityQuery <T>(this T jobData, ComponentSystemBase system) where T : struct, IBaseJobForEach { PrepareEntityQuery(system, typeof(T)); }
public DummyDelegateWrapper(ComponentSystemBase sys) { m_System = sys; }
public unsafe static JobHandle ScheduleSingle <TJob>(this TJob job, ComponentSystemBase system, JobHandle dependsOn = default(JobHandle)) where TJob : struct, IBaseJobForEach { throw new CodegenShouldReplaceException(); }
public ComponentGroupArrayStaticCache(Type type, EntityManager entityManager, ComponentSystemBase system = null) { 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 (fieldType.IsSubclassOf(TypeManager.UnityEngineComponentType)) { 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(); if (system != null) { ComponentGroup = system.GetComponentGroup(ComponentTypes); SafetyManager = entityManager.ComponentJobSafetyManager; } else { ComponentGroup = entityManager.CreateComponentGroup(ComponentTypes); SafetyManager = entityManager.ComponentJobSafetyManager; } CachedType = type; }
private static string CollectInjectedGroup(ComponentSystemBase system, FieldInfo groupField, Type injectedGroupType, out FieldInfo entityArrayField, out FieldInfo indexFromEntityField, InjectionContext injectionContext, out FieldInfo lengthField, out FieldInfo componentGroupIndexField, ISet <ComponentType> componentRequirements, ICollection <InjectionData> componentDataInjections, ICollection <InjectionData> bufferDataInjections, ICollection <InjectionData> sharedComponentInjections) { string str; FieldInfo[] fields = injectedGroupType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); entityArrayField = null; indexFromEntityField = null; lengthField = null; componentGroupIndexField = null; FieldInfo[] infoArray2 = fields; int index = 0; while (true) { if (index >= infoArray2.Length) { if (injectionContext.HasComponentRequirements) { foreach (ComponentType type in injectionContext.ComponentRequirements) { componentRequirements.Add(type); } } str = null; break; } FieldInfo field = infoArray2[index]; bool isReadOnly = field.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0; if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(ComponentDataArray <>))) { InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); componentDataInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>))) { componentRequirements.Add(ComponentType.Subtractive(field.FieldType.GetGenericArguments()[0])); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(BufferArray <>))) { InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); bufferDataInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType.IsGenericType && (field.FieldType.GetGenericTypeDefinition() == typeof(SharedComponentDataArray <>))) { if (!isReadOnly) { str = $"{system.GetType().Name}:{groupField.Name} SharedComponentDataArray<> must always be injected as [ReadOnly]"; break; } InjectionData item = new InjectionData(field, field.FieldType.GetGenericArguments()[0], true); sharedComponentInjections.Add(item); componentRequirements.Add(item.ComponentType); } else if (field.FieldType == typeof(EntityArray)) { if (entityArrayField != null) { str = $"{system.GetType().Name}:{groupField.Name} An [Inject] struct, may only contain a single EntityArray"; break; } entityArrayField = field; } else if (!(field.FieldType == typeof(int))) { InjectionHook hook = InjectionHookSupport.HookFor(field); if (hook == null) { str = $"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", (IEnumerable<string>) (from h in InjectionHookSupport.Hooks select h.FieldTypeOfInterest.Name))} and int Length."; break; } string str2 = hook.ValidateField(field, isReadOnly, injectionContext); if (str2 != null) { str = str2; break; } injectionContext.AddEntry(hook.CreateInjectionInfoFor(field, isReadOnly)); } else { if ((field.Name != "Length") && (field.Name != "GroupIndex")) { str = $"{system.GetType().Name}:{groupField.Name} Int in an [Inject] struct should be named " Length " (group length) or " GroupIndex " (index in ComponentGroup[])"; break; } if (!field.IsInitOnly) { str = $"{system.GetType().Name}:{groupField.Name} {field.Name} must use the " readonly " keyword";
public static void PrepareComponentGroup <T>(this T jobData, ComponentSystemBase system) where T : struct, JobForEachExtensions.IBaseJobForEach { jobData.PrepareEntityQuery(system); }
public static int CalculateEntityCount <T>(this T jobData, ComponentSystemBase system) where T : struct, IBaseJobProcessComponentData { return(CalculateEntityCount(system, typeof(T))); }
public static void PrepareComponentGroup <T>(this T jobData, ComponentSystemBase system) where T : struct, JobForEachExtensions.IBaseJobForEach { throw new NotImplementedException(); }
public static ComponentGroup GetComponentGroupForIJobForEach(this ComponentSystemBase system, Type jobType) { throw new NotImplementedException(); }
public unsafe static JobHandle Schedule <TJob>(this TJob job, ComponentSystemBase system, JobHandle dependsOn = default(JobHandle)) where TJob : struct, IBaseJobForEach { throw new NotImplementedException("Schedule<TJob>(ComponentSystemBase system) should have been replaced by code-gen."); }
void AddSystem_Add_Internal(ComponentSystemBase system) { m_Systems.Add(system); AddTypeLookupInternal(system.GetType(), system); }
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; }
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; } } // Set process iteration data's ComponentChunkIterator iterator.Iterator = group.GetComponentChunkIterator(); // Get each type's index in the component group and store them on the process iteration data for output. iterator.IndexInGroup0 = iterator.IndexInGroup1 = iterator.IndexInGroup2 = iterator.IndexInGroup3 = iterator.IndexInGroup4 = iterator.IndexInGroup5 = -1; fixed(int *groupIndices = &iterator.IndexInGroup0) { for (var i = 0; i != cache.ProcessTypesCount; i++) { groupIndices[i] = group.GetIndexInComponentGroup(cache.Types[i].TypeIndex); } } iterator.m_IsParallelFor = isParallelFor; iterator.m_Length = group.CalculateNumberOfChunksWithoutFiltering(); #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 static ComponentGroup GetComponentGroupForIJobProcessComponentData(this ComponentSystemBase system, Type jobType) { return(system.GetEntityQueryForIJobForEach(jobType)); }
//NOTE: It would be much better if C# could resolve the branch with generic resolving, // but apparently the interface constraint is not enough.. public static void PrepareComponentGroup <T>(this T jobData, ComponentSystemBase system) where T : struct, IBaseJobProcessComponentData { PrepareComponentGroup(system, typeof(T)); }
public static InjectComponentGroupData CreateInjection(Type injectedGroupType, FieldInfo groupField, ComponentSystemBase system) { FieldInfo entityArrayField; FieldInfo indexFromEntityField; FieldInfo lengthField; var injectionContext = new InjectionContext(); var componentDataInjections = new List <InjectionData>(); var fixedArrayInjections = new List <InjectionData>(); var sharedComponentInjections = new List <InjectionData>(); var componentRequirements = new HashSet <ComponentType>(); var error = CollectInjectedGroup(system, groupField, injectedGroupType, out entityArrayField, out indexFromEntityField, injectionContext, out lengthField, componentRequirements, componentDataInjections, fixedArrayInjections, sharedComponentInjections); if (error != null) { throw new ArgumentException(error); } return(new InjectComponentGroupData(system, groupField, componentDataInjections.ToArray(), fixedArrayInjections.ToArray(), sharedComponentInjections.ToArray(), entityArrayField, indexFromEntityField, injectionContext, lengthField, componentRequirements.ToArray())); }
public void RemoveSystemFromUpdateList(ComponentSystemBase sys) { m_systemSortDirty = true; m_systemsToRemove.Add(sys); }
static string CollectInjectedGroup(ComponentSystemBase system, FieldInfo groupField, Type injectedGroupType, out FieldInfo entityArrayField, out FieldInfo indexFromEntityField, InjectionContext injectionContext, out FieldInfo lengthField, ISet <ComponentType> componentRequirements, ICollection <InjectionData> componentDataInjections, ICollection <InjectionData> fixedArrayInjections, ICollection <InjectionData> sharedComponentInjections) { //@TODO: Improve error messages... var fields = injectedGroupType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); entityArrayField = null; indexFromEntityField = null; lengthField = null; foreach (var field in fields) { var isReadOnly = field.GetCustomAttributes(typeof(ReadOnlyAttribute), true).Length != 0; //@TODO: Prevent using GameObjectEntity, it will never show up. Point to GameObjectArray instead... if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(ComponentDataArray <>)) { var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); componentDataInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent <>)) { componentRequirements.Add(ComponentType.Subtractive(field.FieldType.GetGenericArguments()[0])); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(FixedArrayArray <>)) { var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); fixedArrayInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(SharedComponentDataArray <>)) { if (!isReadOnly) { return($"{system.GetType().Name}:{groupField.Name} SharedComponentDataArray<> must always be injected as [ReadOnly]"); } var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], true); sharedComponentInjections.Add(injection); componentRequirements.Add(injection.ComponentType); } else if (field.FieldType == typeof(EntityArray)) { // Error on multiple EntityArray if (entityArrayField != null) { return($"{system.GetType().Name}:{groupField.Name} An [Inject] struct, may only contain a single EntityArray"); } entityArrayField = field; } else if (field.FieldType == typeof(IndexFromEntity)) { // Error on multiple IndexFromEntity if (indexFromEntityField != null) { return($"{system.GetType().Name}:{groupField.Name} An [Inject] struct, may only contain a single IndexFromEntity"); } indexFromEntityField = field; } else if (field.FieldType == typeof(int)) { // Error on multiple EntityArray if (field.Name != "Length") { return($"{system.GetType().Name}:{groupField.Name} An [Inject] struct, supports only a specialized int storing the length of the group. (\"int Length;\")"); } lengthField = field; } else { var hook = InjectionHookSupport.HookFor(field); if (hook == null) { return ($"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", InjectionHookSupport.Hooks.Select(h => h.FieldTypeOfInterest.Name))} and int Length."); } var error = hook.ValidateField(field, isReadOnly, injectionContext); if (error != null) { return(error); } injectionContext.AddEntry(hook.CreateInjectionInfoFor(field, isReadOnly)); } } if (injectionContext.HasComponentRequirements) { foreach (var requirement in injectionContext.ComponentRequirements) { componentRequirements.Add(requirement); } } return(null); }
internal static unsafe 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, out cache.FilterChanged); } 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); if (cache.FilterChanged.Length != 0) { cache.ComponentGroup.SetFilterChanged(cache.FilterChanged); } else { cache.ComponentGroup.ResetFilter(); } 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.IsChangedFilter0 = 0; iterator.IsChangedFilter1 = 0; iterator.IsChangedFilter2 = 0; fixed(ComponentChunkIterator *iterators = &iterator.Iterator0) fixed(int *isChangedFilters = &iterator.IsChangedFilter0) { foreach (var type in cache.FilterChanged) { var componentIndexInGroup = group.GetIndexInComponentGroup(type.TypeIndex); for (var iteratorIndex = 0; iteratorIndex < 3; ++iteratorIndex) { if (componentIndexInGroup == iterators[iteratorIndex].IndexInComponentGroup) { isChangedFilters[iteratorIndex] = 1; } } } } iterator.m_IsParallelFor = isParallelFor; iterator.m_Length = cache.FilterChanged.Length > 0 ? group.CalculateNumberOfChunksWithoutFiltering() : 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 }
public void DestroyManager(ComponentSystemBase manager) { throw new NotImplementedException(); }