static void AddBlobAssetsWithDistinctHash( byte *componentData, TypeManager.EntityOffsetInfo *blobAssetRefOffsets, int blobAssetRefCount, BlobAssetsWithDistinctHash blobAssets) { for (var i = 0; i < blobAssetRefCount; ++i) { var blobAssetRefOffset = blobAssetRefOffsets[i].Offset; var blobAssetRefPtr = (BlobAssetReferenceData *)(componentData + blobAssetRefOffset); if (blobAssetRefPtr->m_Ptr == null) { continue; } void *validationPtr = null; try { // Try to read ValidationPtr, this might throw if the memory has been unmapped validationPtr = blobAssetRefPtr->Header->ValidationPtr; } catch (Exception) { // Ignored } if (validationPtr != blobAssetRefPtr->m_Ptr) { continue; } blobAssets.TryAdd(new BlobAssetPtr(blobAssetRefPtr->Header)); } }
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); }