public static void ReplicateManagedObjects( ManagedComponentStore srcStore, Archetype *srcArch, int srcManagedArrayIndex, int srcChunkCapacity, int srcIndex, ManagedComponentStore dstStore, Archetype *dstArch, int dstManagedArrayIndex, int dstChunkCapacity, int dstBaseIndex, int count, Entity srcEntity, Entity *dstEntities, int entityCount) { object[] companionGameObjectInstances = null; var srcI = 0; var dstI = 0; while (srcI < srcArch->TypesCount && dstI < dstArch->TypesCount) { if (srcArch->Types[srcI] < dstArch->Types[dstI]) { ++srcI; } else if (srcArch->Types[srcI] > dstArch->Types[dstI]) { ++dstI; } else { if (srcArch->IsManaged(srcI)) { var componentType = srcArch->Types[srcI]; var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex); var obj = srcStore.GetManagedObject(srcArch, srcManagedArrayIndex, srcChunkCapacity, srcI, srcIndex); if (typeInfo.Category == TypeManager.TypeCategory.Class) { // If we're dealing with a class based type, we will defer the execution to InstantiateHybridComponent (if dependency injection was made), this method will // - Determine if the object should be cloned (true is returned) or referenced (false is returned) // - Clone the GameObject and its components (as many times as we have in 'count'), and make it a Companion Game Object by adding a CompanionLink component to it // - Add the Cloned Hybrid Component to the instantiated entities (again 'count' times) if (InstantiateHybridComponent == null || !InstantiateHybridComponent(obj, srcStore, dstArch, dstStore, dstManagedArrayIndex, dstChunkCapacity, srcEntity, dstEntities, entityCount, dstI, dstBaseIndex, ref companionGameObjectInstances)) { // We end up here if we have to reference the object and not cloning it for (var i = 0; i < count; ++i) { dstStore.SetManagedObject(dstArch, dstManagedArrayIndex, dstChunkCapacity, dstI, dstBaseIndex + i, obj); } } } else { #if NET_DOTS for (var i = 0; i < count; ++i) { // Until DOTS Runtime supports Properties just perform a simple shallow copy dstStore.SetManagedObject(dstArch, dstManagedArrayIndex, dstChunkCapacity, dstI, dstBaseIndex + i, obj); } #else if (obj == null) { // If we are dealing with a Class/GameObject types just perform a shallow copy for (var i = 0; i < count; ++i) { dstStore.SetManagedObject(dstArch, dstManagedArrayIndex, dstChunkCapacity, dstI, dstBaseIndex + i, obj); } } else { // Unless we want to enforce managed components to implement an IDeepClonable interface // we instead generate a binary stream of an object and then use that to instantiate our new deep copy var type = TypeManager.GetType(componentType.TypeIndex); var buffer = new UnsafeAppendBuffer(16, 16, Allocator.Temp); var writer = new PropertiesBinaryWriter(&buffer); BoxedProperties.WriteBoxedType(obj, writer); for (var i = 0; i < count; ++i) { var readBuffer = buffer.AsReader(); var reader = new PropertiesBinaryReader(&readBuffer, writer.GetObjectTable()); object newObj = BoxedProperties.ReadBoxedClass(type, reader); dstStore.SetManagedObject(dstArch, dstManagedArrayIndex, dstChunkCapacity, dstI, dstBaseIndex + i, newObj); } buffer.Dispose(); } #endif } } ++srcI; ++dstI; } } }
public void PatchEntitiesForPrefab(ManagedComponentStore managedComponentStore, Archetype *archetype, Chunk *chunk, int indexInChunk, int entityCount, EntityRemapUtility.SparseEntityRemapInfo *remapping, int remappingCount, Allocator allocator) { #if !NET_DOTS var managedPatches = archetype->ManagedEntityPatches; var managedPatchCount = archetype->ManagedEntityPatchCount; // Patch managed components with entity references. for (int p = 0; p < managedPatchCount; p++) { var componentType = managedPatches[p].Type; for (int e = 0; e != entityCount; e++) { var obj = managedComponentStore.GetManagedObject(chunk, componentType, e + indexInChunk); EntityRemapUtility.PatchEntityForPrefabInBoxedType(obj, remapping + e * remappingCount, remappingCount); } } UnsafeUtility.Free(remapping, allocator); #endif }
public static void AssertArchetypeDoesNotRemoveSystemStateComponents(Archetype *src, Archetype *dst) { int o = 0; int n = 0; for (; n < src->TypesCount && o < dst->TypesCount;) { int srcType = src->Types[o].TypeIndex; int dstType = dst->Types[n].TypeIndex; if (srcType == dstType) { o++; n++; } else if (dstType > srcType) { if (src->Types[o].IsSystemStateComponent) { throw new System.ArgumentException( $"SystemState components may not be removed via SetArchetype: {src->Types[o]}"); } o++; } else { n++; } } for (; o < src->TypesCount; o++) { if (src->Types[o].IsSystemStateComponent) { throw new System.ArgumentException($"SystemState components may not be removed via SetArchetype: {src->Types[o]}"); } } }
private void AddComponentData( Chunk *afterChunk, Archetype *afterArchetype, ComponentTypeInArchetype afterTypeInArchetype, int afterIndexInTypeArray, int afterEntityIndexInChunk, EntityGuid entityGuid, int typeIndex, TypeInfo typeInfo ) { var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash); AddComponents.Add(packedComponent); if (afterTypeInArchetype.IsSharedComponent) { var offset = afterIndexInTypeArray - afterChunk->Archetype->FirstSharedComponent; var sharedComponentIndex = afterChunk->GetSharedComponentValue(offset); // No managed objects in burst land. Do what we can a defer the actual unpacking until later. ComponentDataStream.SetSharedComponentDataDeferred(entityGuid, afterTypeInArchetype.TypeIndex, sharedComponentIndex); return; } // IMPORTANT This means `IsZeroSizedInChunk` which is always true for shared components. // Always check shared components first. if (afterTypeInArchetype.IsZeroSized) { // Zero sized components have no data to copy. return; } if (afterTypeInArchetype.IsBuffer) { var sizeOf = afterArchetype->SizeOfs[afterIndexInTypeArray]; var buffer = (BufferHeader *)(ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterEntityIndexInChunk * sizeOf); var length = buffer->Length; if (length == 0) { return; } var elementPtr = BufferHeader.GetElementPointer(buffer); if (afterTypeInArchetype.TypeIndex == TypeInfoStream.LinkedEntityGroupTypeIndex) { // Magic in AddComponent already put a self-reference at the top of the buffer, so there's no need for us to add it. // The rest of the elements should be interpreted as LinkedEntityGroupAdditions. for (var elementIndex = 1; elementIndex < length; elementIndex++) { var childEntity = ((Entity *)elementPtr)[elementIndex]; if (!AfterEntityToEntityGuid.TryGetValue(childEntity, out var childEntityGuid)) { // If the child entity doesn't have a guid, there's no way for us to communicate its identity to the destination world. throw new Exception("LinkedEntityGroup child is missing an EntityGuid component."); } LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange { RootEntityGuid = entityGuid, ChildEntityGuid = childEntityGuid }); } } else { ComponentDataStream.SetComponentData(packedComponent, elementPtr, typeInfo.ElementSize * length); ExtractEntityReferencePatches(typeInfo, packedComponent, elementPtr, length); } } else { var sizeOf = afterArchetype->SizeOfs[afterIndexInTypeArray]; var ptr = ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterEntityIndexInChunk * sizeOf; ComponentDataStream.SetComponentData(packedComponent, ptr, sizeOf); ExtractEntityReferencePatches(typeInfo, packedComponent, ptr, 1); } }
public bool Contains(Archetype *value) { return(IndexOf(value) != -1); }
static bool RequiresBuildingResidueSharedComponentIndices(Archetype *srcArchetype, Archetype *dstArchetype) { return(dstArchetype->NumSharedComponents > 0 && dstArchetype->NumSharedComponents != srcArchetype->NumSharedComponents); }
public bool Contains(Archetype *value) { return(ListData.Contains(value)); }
public bool Contains(Archetype *value) { return(this.ListData().Contains(value)); }
internal void MoveChunksFromFiltered( NativeArray <ArchetypeChunk> chunks, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping, EntityComponentStore *srcEntityComponentStore, ManagedComponentStore srcManagedComponentStore) { var access = GetCheckedEntityDataAccess(); var ecs = access->EntityComponentStore; var mcs = access->ManagedComponentStore; new MoveChunksJob { srcEntityComponentStore = srcEntityComponentStore, dstEntityComponentStore = ecs, entityRemapping = entityRemapping, chunks = chunks }.Run(); int chunkCount = chunks.Length; var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob); Archetype *previousSrcArchetypee = null; Archetype *dstArchetype = null; int managedComponentCount = 0; NativeList <IntPtr> managedChunks = new NativeList <IntPtr>(0, Allocator.TempJob); for (int i = 0; i < chunkCount; ++i) { var chunk = chunks[i].m_Chunk; var archetype = chunk->Archetype; // Move Chunk World. ChangeVersion:Yes OrderVersion:Yes if (previousSrcArchetypee != archetype) { dstArchetype = ecs->GetOrCreateArchetype(archetype->Types, archetype->TypesCount); } remapChunks[i] = new RemapChunk { chunk = chunk, dstArchetype = dstArchetype }; if (dstArchetype->NumManagedComponents > 0) { managedComponentCount += chunk->Count * dstArchetype->NumManagedComponents; managedChunks.Add((IntPtr)chunk); } if (archetype->MetaChunkArchetype != null) { Entity srcEntity = chunk->metaChunkEntity; Entity dstEntity; ecs->CreateEntities(dstArchetype->MetaChunkArchetype, &dstEntity, 1); var srcEntityInChunk = srcEntityComponentStore->GetEntityInChunk(srcEntity); var dstEntityInChunk = ecs->GetEntityInChunk(dstEntity); ChunkDataUtility.SwapComponents(srcEntityInChunk.Chunk, srcEntityInChunk.IndexInChunk, dstEntityInChunk.Chunk, dstEntityInChunk.IndexInChunk, 1, srcEntityComponentStore->GlobalSystemVersion, ecs->GlobalSystemVersion); EntityRemapUtility.AddEntityRemapping(ref entityRemapping, srcEntity, dstEntity); srcEntityComponentStore->DestroyEntities(&srcEntity, 1); } } NativeArray <int> srcManagedIndices = default; NativeArray <int> dstManagedIndices = default; int nonNullManagedComponentCount = 0; if (managedComponentCount > 0) { srcManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob); dstManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob); new GatherManagedComponentIndicesInChunkJob() { SrcEntityComponentStore = srcEntityComponentStore, DstEntityComponentStore = ecs, SrcManagedIndices = srcManagedIndices, DstManagedIndices = dstManagedIndices, Chunks = managedChunks, NonNullCount = &nonNullManagedComponentCount }.Run(); } mcs.Playback(ref ecs->ManagedChangesTracker); srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker); k_ProfileMoveSharedComponents.Begin(); var remapShared = access->MoveSharedComponents(srcManagedComponentStore, chunks, Allocator.TempJob); k_ProfileMoveSharedComponents.End(); if (managedComponentCount > 0) { k_ProfileMoveManagedComponents.Begin(); mcs.MoveManagedComponentsFromDifferentWorld(srcManagedIndices, dstManagedIndices, nonNullManagedComponentCount, srcManagedComponentStore); srcEntityComponentStore->m_ManagedComponentFreeIndex.Add(srcManagedIndices.GetUnsafeReadOnlyPtr(), sizeof(int) * srcManagedIndices.Length); k_ProfileMoveManagedComponents.End(); } new ChunkPatchEntities { RemapChunks = remapChunks, EntityRemapping = entityRemapping, EntityComponentStore = ecs }.Run(); var remapChunksJob = new RemapChunksFilteredJob { dstEntityComponentStore = ecs, remapChunks = remapChunks, entityRemapping = entityRemapping, chunkHeaderType = TypeManager.GetTypeIndex <ChunkHeader>() }.Schedule(remapChunks.Length, 1); var moveChunksBetweenArchetypeJob = new MoveFilteredChunksBetweenArchetypexJob { RemapChunks = remapChunks, RemapShared = remapShared, GlobalSystemVersion = ecs->GlobalSystemVersion }.Schedule(remapChunksJob); moveChunksBetweenArchetypeJob.Complete(); mcs.Playback(ref ecs->ManagedChangesTracker); if (managedComponentCount > 0) { srcManagedIndices.Dispose(); dstManagedIndices.Dispose(); } managedChunks.Dispose(); remapShared.Dispose(); remapChunks.Dispose(); }
public int IndexOf(Archetype *value) { return(ListData.IndexOf(value)); }
public Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *types, int count, EntityGroupManager groupManager) { var type = GetExistingArchetype(types, count); if (type != null) { return(type); } AssertArchetypeComponents(types, count); // This is a new archetype, allocate it and add it to the hash map type = (Archetype *)m_ArchetypeChunkAllocator.Allocate(sizeof(Archetype), 8); type->TypesCount = count; type->Types = (ComponentTypeInArchetype *)m_ArchetypeChunkAllocator.Construct(sizeof(ComponentTypeInArchetype) * count, 4, types); type->EntityCount = 0; type->NumSharedComponents = 0; type->SharedComponentOffset = null; for (var i = 0; i < count; ++i) { if (TypeManager.GetComponentType(types[i].TypeIndex).Category == TypeManager.TypeCategory.ISharedComponentData) { ++type->NumSharedComponents; } } var chunkDataSize = Chunk.GetChunkBufferSize(type->NumSharedComponents); // FIXME: proper alignment type->Offsets = (int *)m_ArchetypeChunkAllocator.Allocate(sizeof(int) * count, 4); type->SizeOfs = (int *)m_ArchetypeChunkAllocator.Allocate(sizeof(int) * count, 4); var bytesPerInstance = 0; for (var i = 0; i < count; ++i) { var cType = TypeManager.GetComponentType(types[i].TypeIndex); var sizeOf = cType.SizeInChunk * types[i].FixedArrayLengthMultiplier; type->SizeOfs[i] = sizeOf; bytesPerInstance += sizeOf; } type->ChunkCapacity = chunkDataSize / bytesPerInstance; Assert.IsTrue(Chunk.kMaximumEntitiesPerChunk >= type->ChunkCapacity); var usedBytes = 0; for (var i = 0; i < count; ++i) { var sizeOf = type->SizeOfs[i]; type->Offsets[i] = usedBytes; usedBytes += sizeOf * type->ChunkCapacity; } type->NumManagedArrays = 0; type->ManagedArrayOffset = null; for (var i = 0; i < count; ++i) { if (TypeManager.GetComponentType(types[i].TypeIndex).Category == TypeManager.TypeCategory.Class) { ++type->NumManagedArrays; } } if (type->NumManagedArrays > 0) { type->ManagedArrayOffset = (int *)m_ArchetypeChunkAllocator.Allocate(sizeof(int) * count, 4); var mi = 0; for (var i = 0; i < count; ++i) { var cType = TypeManager.GetComponentType(types[i].TypeIndex); if (cType.Category == TypeManager.TypeCategory.Class) { type->ManagedArrayOffset[i] = mi++; } else { type->ManagedArrayOffset[i] = -1; } } } if (type->NumSharedComponents > 0) { type->SharedComponentOffset = (int *)m_ArchetypeChunkAllocator.Allocate(sizeof(int) * count, 4); var mi = 0; for (var i = 0; i < count; ++i) { var cType = TypeManager.GetComponentType(types[i].TypeIndex); if (cType.Category == TypeManager.TypeCategory.ISharedComponentData) { type->SharedComponentOffset[i] = mi++; } else { type->SharedComponentOffset[i] = -1; } } } // Update the list of all created archetypes type->PrevArchetype = m_LastArchetype; m_LastArchetype = type; UnsafeLinkedListNode.InitializeList(&type->ChunkList); UnsafeLinkedListNode.InitializeList(&type->ChunkListWithEmptySlots); m_TypeLookup.Add(GetHash(types, count), (IntPtr)type); groupManager.OnArchetypeAdded(type); return(type); }
public void Move(Entity entity, Archetype *archetype, SharedComponentValues sharedComponentValues) { var archetypeChunkFilter = new ArchetypeChunkFilter(archetype, sharedComponentValues); Move(entity, ref archetypeChunkFilter); }
private void SetComponentData( Chunk *afterChunk, Archetype *afterArchetype, ComponentTypeInArchetype afterTypeInArchetype, int afterIndexInTypeArray, int afterEntityIndexInChunk, Chunk *beforeChunk, Archetype *beforeArchetype, int beforeIndexInTypeArray, int beforeEntityIndexInChunk, EntityGuid entityGuid, int typeIndex, TypeInfo typeInfo) { if (afterTypeInArchetype.IsSharedComponent) { var beforeOffset = beforeIndexInTypeArray - beforeChunk->Archetype->FirstSharedComponent; var beforeSharedComponentIndex = beforeChunk->GetSharedComponentValue(beforeOffset); var afterOffset = afterIndexInTypeArray - afterChunk->Archetype->FirstSharedComponent; var afterSharedComponentIndex = afterChunk->GetSharedComponentValue(afterOffset); // No managed objects in burst land. Do what we can and defer the actual unpacking until later. ComponentDataStream.SetSharedComponentDataDeferred(entityGuid, afterTypeInArchetype.TypeIndex, afterSharedComponentIndex, beforeSharedComponentIndex); return; } // IMPORTANT This means `IsZeroSizedInChunk` which is always true for shared components. // Always check shared components first. if (afterTypeInArchetype.IsZeroSized) { return; } if (afterTypeInArchetype.IsBuffer) { var beforeBuffer = (BufferHeader *)(ChunkUtility.GetBuffer(beforeChunk) + beforeArchetype->Offsets[beforeIndexInTypeArray] + beforeEntityIndexInChunk * beforeArchetype->SizeOfs[beforeIndexInTypeArray]); var beforeElementPtr = BufferHeader.GetElementPointer(beforeBuffer); var beforeLength = beforeBuffer->Length; var afterBuffer = (BufferHeader *)(ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterEntityIndexInChunk * afterArchetype->SizeOfs[afterIndexInTypeArray]); var afterElementPtr = BufferHeader.GetElementPointer(afterBuffer); var afterLength = afterBuffer->Length; if (afterTypeInArchetype.TypeIndex == TypeInfoStream.LinkedEntityGroupTypeIndex) { var beforeLinkedEntityGroups = (LinkedEntityGroup *)beforeElementPtr; var afterLinkedEntityGroups = (LinkedEntityGroup *)afterElementPtr; // Using is not supported by burst. var beforeLinkedEntityGroupEntityGuids = new NativeArray <EntityGuid>(beforeLength, Allocator.Temp); var afterLinkedEntityGroupEntityGuids = new NativeArray <EntityGuid>(afterLength, Allocator.Temp); { for (var i = 0; i < beforeLength; i++) { if (!BeforeEntityToEntityGuid.TryGetValue(beforeLinkedEntityGroups[i].Value, out var beforeEntityGuid)) { throw new Exception("LinkedEntityGroup child is missing an EntityGuid component."); } beforeLinkedEntityGroupEntityGuids[i] = beforeEntityGuid; } for (var i = 0; i < afterLength; i++) { if (!AfterEntityToEntityGuid.TryGetValue(afterLinkedEntityGroups[i].Value, out var afterEntityGuid)) { throw new Exception("LinkedEntityGroup child is missing an EntityGuid component."); } afterLinkedEntityGroupEntityGuids[i] = afterEntityGuid; } beforeLinkedEntityGroupEntityGuids.Sort(); afterLinkedEntityGroupEntityGuids.Sort(); var beforeIndex = 0; var afterIndex = 0; while (beforeIndex < beforeLength && afterIndex < afterLength) { var beforeEntityGuid = beforeLinkedEntityGroupEntityGuids[beforeIndex]; var afterEntityGuid = afterLinkedEntityGroupEntityGuids[afterIndex]; var comparison = beforeEntityGuid.CompareTo(afterEntityGuid); if (comparison == 0) { // If the entity is in both "before" and "after", then there is no change. beforeIndex++; afterIndex++; } else if (comparison > 0) { // If the entity is in "before" but not "after", it's been removed. LinkedEntityGroupRemovals.Add(new LinkedEntityGroupChange { RootEntityGuid = entityGuid, ChildEntityGuid = beforeEntityGuid }); beforeIndex++; } else if (comparison < 0) { // If the entity is in "after" but not "before", it's been added. LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange { RootEntityGuid = entityGuid, ChildEntityGuid = afterEntityGuid }); afterIndex++; } } while (beforeIndex < beforeLength) { // If the entity is in "before" but not "after", it's been removed. LinkedEntityGroupRemovals.Add(new LinkedEntityGroupChange { RootEntityGuid = entityGuid, ChildEntityGuid = beforeLinkedEntityGroupEntityGuids[beforeIndex++] }); } while (afterIndex < afterLength) { // If the entity is in "after" but not "before", it's been added. LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange { RootEntityGuid = entityGuid, ChildEntityGuid = afterLinkedEntityGroupEntityGuids[afterIndex++] }); } } } else { if (afterLength != beforeLength || UnsafeUtility.MemCmp(beforeElementPtr, afterElementPtr, afterLength * typeInfo.ElementSize) != 0) { var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash); ComponentDataStream.SetComponentData(packedComponent, afterElementPtr, typeInfo.ElementSize * afterLength); ExtractEntityReferencePatches(typeInfo, packedComponent, afterElementPtr, afterLength); } } } else { if (beforeArchetype->SizeOfs[beforeIndexInTypeArray] != afterArchetype->SizeOfs[afterIndexInTypeArray]) { throw new Exception("Archetype->SizeOfs do not match"); } var beforeAddress = ChunkUtility.GetBuffer(beforeChunk) + beforeArchetype->Offsets[beforeIndexInTypeArray] + beforeArchetype->SizeOfs[beforeIndexInTypeArray] * beforeEntityIndexInChunk; var afterAddress = ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterArchetype->SizeOfs[afterIndexInTypeArray] * afterEntityIndexInChunk; if (UnsafeUtility.MemCmp(beforeAddress, afterAddress, beforeArchetype->SizeOfs[beforeIndexInTypeArray]) != 0) { var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash); ComponentDataStream.SetComponentData(packedComponent, afterAddress, beforeArchetype->SizeOfs[beforeIndexInTypeArray]); ExtractEntityReferencePatches(typeInfo, packedComponent, afterAddress, 1); } } }
private void AddArchetypeIfMatching(Archetype *archetype, EntityGroupData *group) { // If the group has more actually required types than the archetype it can never match, so early out as an optimization if (group->RequiredComponentsCount - group->SubtractiveComponentsCount > archetype->TypesCount) { return; } var typeI = 0; var prevTypeI = 0; var disabledIndex = TypeManager.GetTypeIndex <Disabled>(); var prefabIndex = TypeManager.GetTypeIndex <Prefab>(); var requestedDisabled = false; var requestedPrefab = false; for (var i = 0; i < group->RequiredComponentsCount; ++i, ++typeI) { while (archetype->Types[typeI].TypeIndex < group->RequiredComponents[i].TypeIndex && typeI < archetype->TypesCount) { ++typeI; } if (group->RequiredComponents[i].TypeIndex == disabledIndex) { requestedDisabled = true; } if (group->RequiredComponents[i].TypeIndex == prefabIndex) { requestedPrefab = true; } var hasComponent = !(typeI >= archetype->TypesCount); // Type mismatch if (hasComponent && archetype->Types[typeI].TypeIndex != group->RequiredComponents[i].TypeIndex) { hasComponent = false; } if (hasComponent && group->RequiredComponents[i].AccessModeType == ComponentType.AccessMode.Subtractive) { return; } if (!hasComponent && group->RequiredComponents[i].AccessModeType != ComponentType.AccessMode.Subtractive) { return; } if (hasComponent) { prevTypeI = typeI; } else { typeI = prevTypeI; } } if (archetype->Disabled && (!requestedDisabled)) { return; } if (archetype->Prefab && (!requestedPrefab)) { return; } var match = (MatchingArchetypes *)m_GroupDataChunkAllocator.Allocate( MatchingArchetypes.GetAllocationSize(group->RequiredComponentsCount), 8); match->Archetype = archetype; var typeIndexInArchetypeArray = match->IndexInArchetype; if (group->LastMatchingArchetype == null) { group->LastMatchingArchetype = match; } match->Next = group->FirstMatchingArchetype; group->FirstMatchingArchetype = match; for (var component = 0; component < group->RequiredComponentsCount; ++component) { var typeComponentIndex = -1; if (group->RequiredComponents[component].AccessModeType != ComponentType.AccessMode.Subtractive) { typeComponentIndex = ChunkDataUtility.GetIndexInTypeArray(archetype, group->RequiredComponents[component].TypeIndex); Assert.AreNotEqual(-1, typeComponentIndex); } typeIndexInArchetypeArray[component] = typeComponentIndex; } }
public void Add(Archetype *value) { ListData.Add(value); }
public int IndexOf(Archetype *value) { return(this.ListData().IndexOf(value)); }
Archetype *CreateInstanceArchetype(ComponentTypeInArchetype *inTypesSorted, int count, ComponentTypeInArchetype *types, Archetype *srcArchetype, bool removePrefab) { UnsafeUtility.MemCpy(types, inTypesSorted, sizeof(ComponentTypeInArchetype) * count); var hasCleanup = false; var removedTypes = 0; for (var t = 0; t < srcArchetype->TypesCount; ++t) { var type = srcArchetype->Types[t]; hasCleanup |= type.TypeIndex == m_CleanupEntityType; var skip = type.IsSystemStateComponent || (removePrefab && type.TypeIndex == m_PrefabType); if (skip) { ++removedTypes; } else { types[t - removedTypes] = srcArchetype->Types[t]; } } // Entity has already been destroyed, so it shouldn't be instantiated anymore if (hasCleanup) { return(null); } else if (removedTypes > 0) { return(GetOrCreateArchetype(types, count - removedTypes)); } else { return(srcArchetype); } }
public void Add(Archetype *value) { this.ListData().Add(value); }
ArchetypeChunkFilter GetArchetypeChunkFilterWithChangedArchetype(Chunk *srcChunk, Archetype *dstArchetype) { var srcArchetype = srcChunk->Archetype; var archetypeChunkFilter = new ArchetypeChunkFilter(); archetypeChunkFilter.Archetype = dstArchetype; BuildSharedComponentIndicesWithChangedArchetype(srcArchetype, dstArchetype, srcChunk->SharedComponentValues, archetypeChunkFilter.SharedComponentValues); return(archetypeChunkFilter); }
public void AddNoResize(Archetype *value) { Writer.AddNoResize(value); }
internal object GetManagedObject(Archetype *archetype, int managedArrayIndex, int chunkCapacity, int type, int index) { var managedStart = archetype->ManagedArrayOffset[type] * chunkCapacity; return(m_ManagedArrays[managedArrayIndex].ManagedArray[index + managedStart]); }
internal void MoveChunksFromFiltered( NativeArray <ArchetypeChunk> chunks, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping, EntityComponentStore *srcEntityComponentStore, ManagedComponentStore srcManagedComponentStore) { new MoveChunksJob { srcEntityComponentStore = srcEntityComponentStore, dstEntityComponentStore = EntityComponentStore, entityRemapping = entityRemapping, chunks = chunks }.Run(); var managedArrayChunks = new NativeList <IntPtr>(Allocator.Temp); int chunkCount = chunks.Length; var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob); Archetype *previousSrcArchetypee = null; Archetype *dstArchetype = null; for (int i = 0; i < chunkCount; ++i) { var chunk = chunks[i].m_Chunk; var archetype = chunk->Archetype; if (previousSrcArchetypee != archetype) { dstArchetype = EntityComponentStore->GetOrCreateArchetype(archetype->Types, archetype->TypesCount); EntityComponentStore->IncrementComponentTypeOrderVersion(dstArchetype); } remapChunks[i] = new RemapChunk { chunk = chunk, dstArchetype = dstArchetype }; if (archetype->NumManagedArrays > 0) { managedArrayChunks.Add((IntPtr)chunk); } if (archetype->MetaChunkArchetype != null) { Entity srcEntity = chunk->metaChunkEntity; Entity dstEntity; EntityComponentStore->CreateEntities(dstArchetype->MetaChunkArchetype, &dstEntity, 1); var srcEntityInChunk = srcEntityComponentStore->GetEntityInChunk(srcEntity); var dstEntityInChunk = EntityComponentStore->GetEntityInChunk(dstEntity); ChunkDataUtility.SwapComponents(srcEntityInChunk.Chunk, srcEntityInChunk.IndexInChunk, dstEntityInChunk.Chunk, dstEntityInChunk.IndexInChunk, 1, srcEntityComponentStore->GlobalSystemVersion, EntityComponentStore->GlobalSystemVersion); EntityRemapUtility.AddEntityRemapping(ref entityRemapping, srcEntity, dstEntity); srcEntityComponentStore->DestroyEntities(&srcEntity, 1); } } var managedArrayDstIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); var managedArraySrcIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); EntityComponentStore->ReserveManagedObjectArrays(managedArrayDstIndices); var remapManaged = new RemapManagedArraysJob { chunks = managedArrayChunks, dstIndices = managedArrayDstIndices, srcIndices = managedArraySrcIndices, }.Schedule(managedArrayChunks.Length, 64); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker); k_ProfileMoveObjectComponents.Begin(); remapManaged.Complete(); m_ManagedComponentStore.MoveManagedObjectArrays(managedArraySrcIndices, managedArrayDstIndices, srcManagedComponentStore); k_ProfileMoveObjectComponents.End(); managedArrayDstIndices.Dispose(); managedArraySrcIndices.Dispose(); managedArrayChunks.Dispose(); k_ProfileMoveSharedComponents.Begin(); var remapShared = ManagedComponentStore.MoveSharedComponents(srcManagedComponentStore, chunks, Allocator.TempJob); k_ProfileMoveSharedComponents.End(); new ChunkPatchEntities { RemapChunks = remapChunks, EntityRemapping = entityRemapping, EntityComponentStore = EntityComponentStore }.Run(); var remapChunksJob = new RemapChunksFilteredJob { dstEntityComponentStore = EntityComponentStore, remapChunks = remapChunks, entityRemapping = entityRemapping }.Schedule(remapChunks.Length, 1); var moveChunksBetweenArchetypeJob = new MoveFilteredChunksBetweenArchetypexJob { remapChunks = remapChunks, remapShared = remapShared, globalSystemVersion = EntityComponentStore->GlobalSystemVersion }.Schedule(remapChunksJob); moveChunksBetweenArchetypeJob.Complete(); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); remapShared.Dispose(); remapChunks.Dispose(); }
public void SetManagedObject(Archetype *archetype, int managedArrayIndex, int chunkCapacity, int type, int index, object val) { var managedStart = archetype->ManagedArrayOffset[type] * chunkCapacity; m_ManagedArrays[managedArrayIndex].ManagedArray[index + managedStart] = val; }
static unsafe void WriteChunkData(YamlWriter writer, EntityManager entityManager, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapInfos, Chunk *initialChunk, Archetype *archetype, int archetypeIndex, bool dumpChunkRawData) { var tempChunkMem = stackalloc byte[Chunk.kChunkSize]; Chunk *tempChunk = (Chunk *)tempChunkMem; if (dumpChunkRawData) { UnsafeUtility.MemCpy(tempChunk, initialChunk, Chunk.kChunkSize); byte *tempChunkBuffer = tempChunk->Buffer; BufferHeader.PatchAfterCloningChunk(tempChunk); EntityRemapUtility.PatchEntities(archetype->ScalarEntityPatches, archetype->ScalarEntityPatchCount, archetype->BufferEntityPatches, archetype->BufferEntityPatchCount, tempChunkBuffer, tempChunk->Count, ref entityRemapInfos); ClearChunkHeaderComponents(tempChunk); ChunkDataUtility.MemsetUnusedChunkData(tempChunk, 0); tempChunk->Archetype = (Archetype *)archetypeIndex; } using (writer.WriteCollection(k_ChunkDataCollectionTag)) { using (writer.WriteCollection("Header")) { WriteEntity(writer, nameof(Chunk.metaChunkEntity), initialChunk->metaChunkEntity); writer.WriteKeyValue(nameof(Chunk.Capacity), initialChunk->Capacity); writer.WriteKeyValue(nameof(Chunk.Count), initialChunk->Count); if (dumpChunkRawData) { writer.WriteFormattedBinaryData("Header-RawData", tempChunk, Chunk.kBufferOffset); } } // First pass to sort by component type var entitiesByChunkIndex = new Dictionary <int, Entity>(); var componentDataList = new List <int>(); var chunkComponentDataList = new List <int>(); var chunkTypes = archetype->Types; for (int typeI = 0; typeI < archetype->TypesCount; typeI++) { var componentType = &chunkTypes[typeI]; var type = TypeManager.GetType(componentType->TypeIndex); ref readonly var typeInfo = ref TypeManager.GetTypeInfo(componentType->TypeIndex);
static unsafe void WriteChunkData(YamlWriter writer, EntityManager entityManager, Chunk *initialChunk, Archetype *archetype, bool dumpChunkRawData) { using (writer.WriteCollection(k_ChunkDataCollectionTag)) { using (writer.WriteCollection("Header")) { WriteEntity(writer, nameof(Chunk.metaChunkEntity), initialChunk->metaChunkEntity); writer.WriteKeyValue(nameof(Chunk.Capacity), initialChunk->Capacity) .WriteKeyValue(nameof(Chunk.Count), initialChunk->Count); if (dumpChunkRawData) { writer.WriteFormattedBinaryData("RawData", initialChunk, Chunk.kBufferOffset); } } // First pass to sort by component type var entitiesByChunkIndex = new Dictionary <int, Entity>(); var componentDataList = new List <int>(); var chunkComponentDataList = new List <int>(); var chunkTypes = archetype->Types; for (int typeI = 0; typeI < archetype->TypesCount; typeI++) { var componentType = &chunkTypes[typeI]; var type = TypeManager.GetType(componentType->TypeIndex); var typeInfo = TypeManager.GetTypeInfo(componentType->TypeIndex); if (componentType->IsChunkComponent) { chunkComponentDataList.Add(typeI); } // Is it a Component Data ? else if (typeof(IComponentData).IsAssignableFrom(type) || typeof(Entity).IsAssignableFrom(type) || typeof(IBufferElementData).IsAssignableFrom(type)) { // Ignore Tag Component, no data to dump if (typeInfo.IsZeroSized) { continue; } if (typeof(Entity).IsAssignableFrom(type)) { componentDataList.Insert(0, typeI); for (int i = 0; i < initialChunk->Count;) { var entity = (Entity)Marshal.PtrToStructure((IntPtr)initialChunk->Buffer + archetype->SizeOfs[0] * i, type); if (entityManager.Exists(entity)) { entitiesByChunkIndex.Add(i, entity); i++; } } } else { componentDataList.Add(typeI); } } } // Parse the Component Data for this chunk and store them using (writer.WriteCollection(k_ComponentDataCollectionTag)) { foreach (var typeI in componentDataList) { var componentTypeInArchetype = &chunkTypes[typeI]; var componentType = TypeManager.GetType(componentTypeInArchetype->TypeIndex); var componentTypeInfo = TypeManager.GetTypeInfo(componentTypeInArchetype->TypeIndex); var componentExtractedInfo = TypeDataExtractor.GetTypeExtractedInfo(componentType); using (writer.WriteCollection(k_ComponentDataTag)) { writer.WriteInlineMap("info", new[] { new KeyValuePair <object, object>(nameof(Type), componentType.Name), new KeyValuePair <object, object>(nameof(TypeManager.TypeInfo.SizeInChunk), componentTypeInfo.SizeInChunk) }); using (writer.WriteCollection("Entities")) { var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, componentTypeInArchetype->TypeIndex); var componentOffsetInChunk = archetype->Offsets[indexInTypeArray]; var componentSize = archetype->SizeOfs[indexInTypeArray]; var componentsBuffer = initialChunk->Buffer + componentOffsetInChunk; var entityData = new Dictionary <string, string>(); // Dump all entities in this chunk foreach (var kvp in entitiesByChunkIndex) { var entity = kvp.Value; entityData.Clear(); // Get the location of the component data var compData = componentsBuffer + kvp.Key * componentSize; // If the component we are dumping is a Dynamic Buffer if (typeof(IBufferElementData).IsAssignableFrom(componentType)) { var header = (BufferHeader *)compData; var begin = BufferHeader.GetElementPointer(header); var size = Marshal.SizeOf(componentType); using (writer.WriteCollection(entity.ToString())) { for (var it = 0; it < header->Length; it++) { var item = begin + (size * it); entityData.Clear(); // Dump each field of the current entity's component data foreach (var componentFieldInfo in componentExtractedInfo.Fields) { var compDataObject = Marshal.PtrToStructure((IntPtr)item + componentFieldInfo.Offset, componentFieldInfo.Type); entityData.Add(componentFieldInfo.Name, compDataObject.ToString()); } writer.WriteInlineMap($"{it:0000}", entityData); } } } // If it's a Component Data else { // Dump each field of the current entity's component data foreach (var componentFieldInfo in componentExtractedInfo.Fields) { var compDataObject = Marshal.PtrToStructure((IntPtr)compData + componentFieldInfo.Offset, componentFieldInfo.Type); entityData.Add(componentFieldInfo.Name, compDataObject.ToString()); } writer.WriteInlineMap(entity.ToString(), entityData); } } if (dumpChunkRawData) { var csize = EntityComponentStore.GetComponentArraySize(componentSize, archetype->ChunkCapacity); writer.WriteFormattedBinaryData("RawData", componentsBuffer, csize, componentOffsetInChunk + Chunk.kBufferOffset); } } } } } } }