public void RemoveComponent(Entity entity, ComponentType type) { CheckAccess(); m_EntityDataAccess.RemoveComponent(entity, type); }
public void AddComponent(Entity entity, ComponentType componentType) { CheckAccess(); m_EntityDataAccess.AddComponent(entity, componentType); }
public DynamicBuffer<T> AddBuffer<T>(Entity entity) where T : struct, IBufferElementData { CheckAccess(); m_EntityDataAccess.AddComponent(entity, ComponentType.ReadWrite<T>()); return GetBuffer<T>(entity); }
public ComponentTypeInArchetype(ComponentType type) { TypeIndex = type.TypeIndex; FixedArrayLength = type.FixedArrayLength; }
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) { //@TODO: Improve error messages... var fields = injectedGroupType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); entityArrayField = null; indexFromEntityField = null; lengthField = null; componentGroupIndexField = 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(BufferArray <>)) { var injection = new InjectionData(field, field.FieldType.GetGenericArguments()[0], isReadOnly); bufferDataInjections.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(int)) { if (field.Name != "Length" && field.Name != "GroupIndex") { return ($"{system.GetType().Name}:{groupField.Name} Int in an [Inject] struct should be named \"Length\" (group length) or \"GroupIndex\" (index in ComponentGroup[])"); } if (!field.IsInitOnly) { return ($"{system.GetType().Name}:{groupField.Name} {field.Name} must use the \"readonly\" keyword"); } if (field.Name == "Length") { lengthField = field; } if (field.Name == "GroupIndex") { componentGroupIndexField = 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 void AddEntityComponentTypeCommand(EntityCommandBufferChain *chain, ECBCommand op, Entity e, ComponentType t) { var sizeNeeded = Align(sizeof(EntityComponentCommand), 8); var data = (EntityComponentCommand *)Reserve(chain, sizeNeeded); data->Header.Header.CommandType = (int)op; data->Header.Header.TotalSize = sizeNeeded; data->Header.Entity = e; data->ComponentTypeIndex = t.TypeIndex; }
private static void MarkSchedulingAndWaitingJobs(Dictionary <Type, DependantBehavior> dependencyGraph) { HashSet <DependantBehavior> set = new HashSet <DependantBehavior>(); foreach (KeyValuePair <Type, DependantBehavior> pair in dependencyGraph) { DependantBehavior item = pair.Value; if (item.Manager is JobComponentSystem) { item.spawnsJobs = true; set.Add(item); } } foreach (KeyValuePair <Type, DependantBehavior> pair2 in dependencyGraph) { ComponentGroup[] componentGroups; DependantBehavior behavior2 = pair2.Value; ComponentSystem manager = behavior2.Manager as ComponentSystem; if (manager != null) { componentGroups = manager.ComponentGroups; } else { object obj1 = manager; componentGroups = null; } if (componentGroups != null) { HashSet <int> set2 = new HashSet <int>(); ComponentGroup[] componentGroups = ((ComponentSystem)behavior2.Manager).ComponentGroups; int index = 0; while (true) { if (index >= componentGroups.Length) { using (HashSet <DependantBehavior> .Enumerator enumerator3 = set.GetEnumerator()) { while (true) { if (enumerator3.MoveNext()) { DependantBehavior current = enumerator3.Current; if (!(current.Manager is ComponentSystem)) { continue; } HashSet <int> set3 = new HashSet <int>(); ComponentGroup[] groupArray2 = ((ComponentSystem)current.Manager).ComponentGroups; int num3 = 0; while (true) { if (num3 < groupArray2.Length) { ComponentGroup group2 = groupArray2[num3]; ComponentType[] typeArray2 = group2.Types; int num4 = 0; while (true) { if (num4 >= typeArray2.Length) { num3++; break; } ComponentType type2 = typeArray2[num4]; if (type2.RequiresJobDependency) { set3.Add(type2.TypeIndex); } num4++; } continue; } bool flag4 = false; foreach (int num5 in set2) { if (set3.Contains(num5)) { flag4 = true; break; } } if (flag4) { behavior2.WaitsForJobs = true; } else { continue; } break; } } break; } } break; } ComponentGroup group = componentGroups[index]; ComponentType[] types = group.Types; int num2 = 0; while (true) { if (num2 >= types.Length) { index++; break; } ComponentType type = types[num2]; if (type.RequiresJobDependency) { set2.Add(type.TypeIndex); } num2++; } } } } }
// ---------------------------------------------------------------------------------------------------------- // PUBLIC // ---------------------------------------------------------------------------------------------------------- public Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *inTypesSorted, int count) { var srcArchetype = GetExistingArchetype(inTypesSorted, count); if (srcArchetype != null) { return(srcArchetype); } srcArchetype = CreateArchetype(inTypesSorted, count); var types = stackalloc ComponentTypeInArchetype[count + 1]; srcArchetype->InstantiateArchetype = CreateInstanceArchetype(inTypesSorted, count, types, srcArchetype, true); srcArchetype->CopyArchetype = CreateInstanceArchetype(inTypesSorted, count, types, srcArchetype, false); if (srcArchetype->InstantiateArchetype != null) { Assert.IsTrue(srcArchetype->InstantiateArchetype->InstantiateArchetype == srcArchetype->InstantiateArchetype); Assert.IsTrue(srcArchetype->InstantiateArchetype->SystemStateResidueArchetype == null); } if (srcArchetype->CopyArchetype != null) { Assert.IsTrue(srcArchetype->CopyArchetype->CopyArchetype == srcArchetype->CopyArchetype); Assert.IsTrue(srcArchetype->CopyArchetype->SystemStateResidueArchetype == null); } // Setup System state cleanup archetype if (srcArchetype->SystemStateCleanupNeeded) { var cleanupEntityType = new ComponentTypeInArchetype(ComponentType.FromTypeIndex(m_CleanupEntityType)); bool cleanupAdded = false; types[0] = inTypesSorted[0]; var newTypeCount = 1; for (var t = 1; t < srcArchetype->TypesCount; ++t) { var type = srcArchetype->Types[t]; if (type.IsSystemStateComponent) { if (!cleanupAdded && (cleanupEntityType < srcArchetype->Types[t])) { types[newTypeCount++] = cleanupEntityType; cleanupAdded = true; } types[newTypeCount++] = srcArchetype->Types[t]; } } if (!cleanupAdded) { types[newTypeCount++] = cleanupEntityType; } var systemStateResidueArchetype = GetOrCreateArchetype(types, newTypeCount); srcArchetype->SystemStateResidueArchetype = systemStateResidueArchetype; Assert.IsTrue(systemStateResidueArchetype->SystemStateResidueArchetype == systemStateResidueArchetype); Assert.IsTrue(systemStateResidueArchetype->InstantiateArchetype == null); Assert.IsTrue(systemStateResidueArchetype->CopyArchetype == null); } // Setup meta chunk archetype if (count > 1) { types[0] = new ComponentTypeInArchetype(m_EntityComponentType); int metaArchetypeTypeCount = 1; for (int i = 1; i < count; ++i) { var t = inTypesSorted[i]; ComponentType typeToInsert; if (inTypesSorted[i].IsChunkComponent) { typeToInsert = new ComponentType { TypeIndex = ChunkComponentToNormalTypeIndex(t.TypeIndex) }; SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, typeToInsert); } } if (metaArchetypeTypeCount > 1) { SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, m_ChunkHeaderComponentType); srcArchetype->MetaChunkArchetype = GetOrCreateArchetype(types, metaArchetypeTypeCount); } } return(srcArchetype); }
ArchetypeChunkFilter GetArchetypeChunkFilterWithChangedSharedComponent(Chunk *srcChunk, ComponentType componentType, int dstSharedComponentIndex) { var typeIndex = componentType.TypeIndex; var srcArchetype = srcChunk->Archetype; var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(srcArchetype, typeIndex); var srcSharedComponentValueArray = srcChunk->SharedComponentValues; var sharedComponentOffset = indexInTypeArray - srcArchetype->FirstSharedComponent; var srcSharedComponentIndex = srcSharedComponentValueArray[sharedComponentOffset]; if (dstSharedComponentIndex == srcSharedComponentIndex) { return(default);
/// <summary> /// Sets the value of a component of an entity. /// </summary> /// <param name="entity">The entity.</param> /// <param name="componentData">The data to set.</param> /// <typeparam name="T">The component type.</typeparam> /// <exception cref="ArgumentException">Thrown if the component type has no fields.</exception> public static void SetComponentData <T>(this EntityManager manager, Entity entity, T componentData) where T : class, IComponentData { var type = ComponentType.ReadWrite <T>(); manager.SetComponentObject(entity, type, componentData); }
internal void AddSharedComponentDataBoxed(Entity entity, int typeIndex, int hashCode, object componentData) { //TODO: optimize this (no need to move the entity to a new chunk twice) AddComponent(entity, ComponentType.FromTypeIndex(typeIndex)); SetSharedComponentDataBoxed(entity, typeIndex, hashCode, componentData); }
public void AddSharedComponentData <T>(Entity entity, T componentData) where T : struct, ISharedComponentData { //TODO: optimize this (no need to move the entity to a new chunk twice) AddComponent(entity, ComponentType.Create <T>()); SetSharedComponentData(entity, componentData); }
public void AddBuffer <T>(Entity entity) where T : struct, IBufferElementData { AddComponent(entity, ComponentType.Create <T>()); }
public void RemoveComponent <T>(Entity entity) { RemoveComponent(entity, ComponentType.Create <T>()); }