static NativeList <BlobAssetPtr> GetReferencedBlobAssets( NativeArray <ArchetypeChunk> chunks, Allocator allocator, out JobHandle jobHandle, JobHandle dependsOn = default) { var blobAssets = new NativeList <BlobAssetPtr>(1, allocator); var blobAssetsMap = new NativeHashMap <ulong, int>(1, allocator); var gatherUniqueBlobAssets = new GatherUniqueBlobAssetReferences { TypeInfo = TypeManager.GetTypeInfoPointer(), BlobAssetRefOffsets = TypeManager.GetBlobAssetRefOffsetsPointer(), Chunks = chunks, BlobAssets = blobAssets, BlobAssetsMap = blobAssetsMap }.Schedule(dependsOn); var sortBlobAssets = new SortNativeArrayWithComparer <BlobAssetPtr, BlobAssetPtrComparer> { Array = blobAssets.AsDeferredJobArray() }.Schedule(gatherUniqueBlobAssets); jobHandle = blobAssetsMap.Dispose(sortBlobAssets); return(blobAssets); }
static void ClearMissingReferences(EntityManager entityManager, NativeArray <ArchetypeChunk> chunks, out JobHandle jobHandle, JobHandle dependsOn) { jobHandle = new ClearMissingReferencesJob { TypeInfo = TypeManager.GetTypeInfoPointer(), EntityOffsetInfo = TypeManager.GetEntityOffsetsPointer(), GlobalSystemVersion = entityManager.GlobalSystemVersion, Chunks = chunks, EntityComponentStore = entityManager.EntityComponentStore, }.Schedule(chunks.Length, 64, dependsOn); }
public void ReleaseUnusedBlobAssets() { using (var chunks = EntityManager.CreateEntityQuery(EntityGuidQueryDesc).CreateArchetypeChunkArray(Allocator.TempJob)) using (var blobAssets = new NativeList <BlobAssetPtr>(1, Allocator.TempJob)) using (var blobAssetsMap = new NativeHashMap <ulong, int>(1, Allocator.TempJob)) { new EntityDiffer.GatherUniqueBlobAssetReferences { TypeInfo = TypeManager.GetTypeInfoPointer(), BlobAssetRefOffsets = TypeManager.GetBlobAssetRefOffsetsPointer(), Chunks = chunks, BlobAssets = blobAssets, BlobAssetsMap = blobAssetsMap }.Schedule().Complete(); m_BlobAssetBatchPtr->RemoveUnusedBlobAssets(blobAssetsMap); } }
internal static BlobAssetsWithDistinctHash GetBlobAssetsWithDistinctHash( ManagedComponentStore managedComponentStore, NativeArray <ArchetypeChunk> chunks, Allocator allocator) { s_GetBlobAssetsWithDistinctHash.Begin(); var blobAssetsWithDistinctHash = new BlobAssetsWithDistinctHash(allocator); var typeInfoPtr = TypeManager.GetTypeInfoPointer(); var blobAssetRefOffsetPtr = TypeManager.GetBlobAssetRefOffsetsPointer(); var managedObjectBlobs = new ManagedObjectBlobs(); var managedObjectBlobAssets = new NativeList <BlobAssetPtr>(16, Allocator.Temp); var managedObjectBlobAssetsMap = new NativeHashMap <BlobAssetPtr, int>(16, Allocator.Temp); for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) { var chunk = chunks[chunkIndex].m_Chunk; var archetype = chunk->Archetype; // skip this chunk only if we are _certain_ there are no blob asset refs. if (!archetype->HasBlobAssetRefs) { continue; } var typesCount = archetype->TypesCount; var entityCount = chunks[chunkIndex].Count; for (var unorderedTypeIndexInArchetype = 0; unorderedTypeIndexInArchetype < typesCount; unorderedTypeIndexInArchetype++) { var typeIndexInArchetype = archetype->TypeMemoryOrder[unorderedTypeIndexInArchetype]; var componentTypeInArchetype = archetype->Types[typeIndexInArchetype]; if (componentTypeInArchetype.IsZeroSized) { continue; } ref var typeInfo = ref typeInfoPtr[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask]; if (!typeInfo.HasBlobAssetRefs) { continue; } var chunkBuffer = chunk->Buffer; var subArrayOffset = archetype->Offsets[typeIndexInArchetype]; var componentArrayStart = chunkBuffer + subArrayOffset; if (componentTypeInArchetype.IsManagedComponent) { var componentSize = archetype->SizeOfs[typeIndexInArchetype]; var end = componentArrayStart + componentSize * entityCount; for (var componentData = componentArrayStart; componentData < end; componentData += componentSize) { var managedComponentIndex = *(int *)componentData; var managedComponentValue = managedComponentStore.GetManagedComponent(managedComponentIndex); if (null != managedComponentValue) { managedObjectBlobs.GatherBlobAssetReferences(managedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap); } } } else { var blobAssetRefCount = typeInfo.BlobAssetRefOffsetCount; var blobAssetRefOffsets = blobAssetRefOffsetPtr + typeInfo.BlobAssetRefOffsetStartIndex; if (componentTypeInArchetype.IsBuffer) { var header = (BufferHeader *)componentArrayStart; var strideSize = archetype->SizeOfs[typeIndexInArchetype]; var elementSize = typeInfo.ElementSize; for (var entityIndex = 0; entityIndex < entityCount; entityIndex++) { var bufferStart = BufferHeader.GetElementPointer(header); var bufferEnd = bufferStart + header->Length * elementSize; for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize) { AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash); } header = (BufferHeader *)(((byte *)header) + strideSize); } } else { var componentSize = archetype->SizeOfs[typeIndexInArchetype]; var end = componentArrayStart + componentSize * entityCount; for (var componentData = componentArrayStart; componentData < end; componentData += componentSize) { AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash); } } } } }
internal static BlobAssetsWithDistinctHash GetBlobAssetsWithDistinctHash( ManagedComponentStore managedComponentStore, NativeArray <ArchetypeChunk> chunks, Allocator allocator) { var blobAssetsWithDistinctHash = new BlobAssetsWithDistinctHash(allocator); var typeInfoPtr = TypeManager.GetTypeInfoPointer(); var blobAssetRefOffsetPtr = TypeManager.GetBlobAssetRefOffsetsPointer(); var managedObjectBlobs = new ManagedObjectBlobs(); var managedObjectBlobAssets = new NativeList <BlobAssetPtr>(16, Allocator.Temp); var managedObjectBlobAssetsMap = new NativeHashMap <BlobAssetPtr, int>(16, Allocator.Temp); for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) { var chunk = chunks[chunkIndex].m_Chunk; var archetype = chunk->Archetype; // skip this chunk only if we are _certain_ there are no blob asset refs. if (archetype->NumManagedComponents == 0 && archetype->NumSharedComponents == 0 && !archetype->ContainsBlobAssetRefs) { continue; } var typesCount = archetype->TypesCount; var entityCount = chunks[chunkIndex].Count; for (var unorderedTypeIndexInArchetype = 0; unorderedTypeIndexInArchetype < typesCount; unorderedTypeIndexInArchetype++) { var typeIndexInArchetype = archetype->TypeMemoryOrder[unorderedTypeIndexInArchetype]; var componentTypeInArchetype = archetype->Types[typeIndexInArchetype]; if (componentTypeInArchetype.IsZeroSized) { continue; } var chunkBuffer = chunk->Buffer; var subArrayOffset = archetype->Offsets[typeIndexInArchetype]; var componentArrayStart = chunkBuffer + subArrayOffset; if (componentTypeInArchetype.IsManagedComponent) { var componentSize = archetype->SizeOfs[typeIndexInArchetype]; var end = componentArrayStart + componentSize * entityCount; for (var componentData = componentArrayStart; componentData < end; componentData += componentSize) { var managedComponentIndex = *(int *)componentData; var managedComponentValue = managedComponentStore.GetManagedComponent(managedComponentIndex); if (null != managedComponentValue) { managedObjectBlobs.GatherBlobAssetReferences(managedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap); } } } else { var typeInfo = typeInfoPtr[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask]; var blobAssetRefCount = typeInfo.BlobAssetRefOffsetCount; if (blobAssetRefCount == 0) { continue; } var blobAssetRefOffsets = blobAssetRefOffsetPtr + typeInfo.BlobAssetRefOffsetStartIndex; if (componentTypeInArchetype.IsBuffer) { var header = (BufferHeader *)componentArrayStart; var strideSize = archetype->SizeOfs[typeIndexInArchetype]; var elementSize = typeInfo.ElementSize; for (var entityIndex = 0; entityIndex < entityCount; entityIndex++) { var bufferStart = BufferHeader.GetElementPointer(header); var bufferEnd = bufferStart + header->Length * elementSize; for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize) { AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash); } header = (BufferHeader *)(((byte *)header) + strideSize); } } else { var componentSize = archetype->SizeOfs[typeIndexInArchetype]; var end = componentArrayStart + componentSize * entityCount; for (var componentData = componentArrayStart; componentData < end; componentData += componentSize) { AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash); } } } } } for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) { var chunk = chunks[chunkIndex].m_Chunk; var archetype = chunk->Archetype; var sharedComponentValues = chunk->SharedComponentValues; for (var i = 0; i < archetype->NumSharedComponents; i++) { var sharedComponentIndex = sharedComponentValues[i]; if (sharedComponentIndex == 0) { continue; } var sharedComponentValue = managedComponentStore.GetSharedComponentDataNonDefaultBoxed(sharedComponentIndex); managedObjectBlobs.GatherBlobAssetReferences(sharedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap); } } for (var i = 0; i < managedObjectBlobAssets.Length; i++) { var blobAssetPtr = managedObjectBlobAssets[i]; void *validationPtr = null; try { // Try to read ValidationPtr, this might throw if the memory has been unmapped validationPtr = blobAssetPtr.Header->ValidationPtr; } catch (Exception) { // Ignored } if (validationPtr != blobAssetPtr.Data) { continue; } blobAssetsWithDistinctHash.TryAdd(blobAssetPtr); } managedObjectBlobAssets.Dispose(); managedObjectBlobAssetsMap.Dispose(); new SortBlobAssetPtr { Array = blobAssetsWithDistinctHash.BlobAssets.AsDeferredJobArray() }.Run(); return(blobAssetsWithDistinctHash); }