예제 #1
0
        private static unsafe void PatchBlobAssetsInChunkBeforeSave(Chunk *tempChunk, Chunk *originalChunk,
                                                                    NativeArray <int> blobAssetOffsets, NativeHashMap <BlobAssetRefKey, int> blobAssetRefs)
        {
            var archetype   = originalChunk->Archetype;
            var typeCount   = archetype->TypesCount;
            var entityCount = originalChunk->Count;

            for (var unordered_ti = 0; unordered_ti < typeCount; ++unordered_ti)
            {
                var ti   = archetype->TypeMemoryOrder[unordered_ti];
                var type = archetype->Types[ti];
                if (type.IsZeroSized)
                {
                    continue;
                }

                var ct = TypeManager.GetTypeInfo(type.TypeIndex);
                var blobAssetRefCount = ct.BlobAssetRefOffsetCount;
                if (blobAssetRefCount == 0)
                {
                    continue;
                }

                var chunkBuffer = tempChunk->Buffer;

                if (type.IsBuffer)
                {
                    throw new InvalidOperationException("BlobAssetReferences are not supported inside DynamicBuffer components");
                }
                else if (blobAssetRefCount > 0)
                {
                    int   subArrayOffset      = archetype->Offsets[ti];
                    byte *componentArrayStart = OffsetFromPointer(chunkBuffer, subArrayOffset);
                    int   size = archetype->SizeOfs[ti];
                    byte *end  = componentArrayStart + size * entityCount;
                    for (var componentData = componentArrayStart; componentData < end; componentData += size)
                    {
                        for (int i = 0; i < blobAssetRefCount; ++i)
                        {
                            var offset          = ct.BlobAssetRefOffsets[i].Offset;
                            var blobAssetRefPtr = (BlobAssetReferenceData *)(componentData + offset);
                            int value           = -1;
                            if (blobAssetRefPtr->m_Ptr != null)
                            {
                                var blobAssetPtr = new BlobAssetPtr((*(BlobAssetHeader **)blobAssetRefPtr) - 1);
                                var key          = new BlobAssetRefKey {
                                    chunk = originalChunk, offsetInBuffer = (int)((byte *)blobAssetRefPtr - chunkBuffer)
                                };

                                bool found = blobAssetRefs.TryGetValue(key, out value);
                                value = blobAssetOffsets[value];
                                Assert.IsTrue(found);
                            }
                            blobAssetRefPtr->m_Ptr = (byte *)value;
                        }
                    }
                }
            }
        }
        public bool TryGetBlobAsset(ulong hash, out BlobAssetPtr blobAssetPtr)
        {
            var blobAssets = (BlobAssetPtr *)m_BlobAssets->Ptr;

            for (var i = 0; i < m_BlobAssets->Length; i++)
            {
                if (blobAssets[i].Header->Hash != hash)
                {
                    continue;
                }

                blobAssetPtr = new BlobAssetPtr(blobAssets[i].Header);
                return(true);
            }

            blobAssetPtr = default;
            return(false);
        }
예제 #3
0
        private static unsafe void GatherAllUsedBlobAssets(EntityArchetype[] archetypeArray, out NativeHashMap <BlobAssetRefKey, int> blobAssetRefs, out NativeList <BlobAssetPtr> blobAssets)
        {
            var blobAssetMap = new NativeHashMap <BlobAssetPtr, int>(100, Allocator.Temp);

            blobAssetRefs = new NativeHashMap <BlobAssetRefKey, int>(100, Allocator.Temp);
            blobAssets    = new NativeList <BlobAssetPtr>(100, Allocator.Temp);
            for (int archetypeIndex = 0; archetypeIndex < archetypeArray.Length; ++archetypeIndex)
            {
                var archetype = archetypeArray[archetypeIndex].Archetype;
                if (!archetype->ContainsBlobAssetRefs)
                {
                    continue;
                }

                var typeCount = archetype->TypesCount;
                for (var ci = 0; ci < archetype->Chunks.Count; ++ci)
                {
                    var chunk       = archetype->Chunks.p[ci];
                    var entityCount = chunk->Count;
                    for (var unordered_ti = 0; unordered_ti < typeCount; ++unordered_ti)
                    {
                        var ti   = archetype->TypeMemoryOrder[unordered_ti];
                        var type = archetype->Types[ti];
                        if (type.IsZeroSized)
                        {
                            continue;
                        }

                        var ct = TypeManager.GetTypeInfo(type.TypeIndex);
                        var blobAssetRefCount = ct.BlobAssetRefOffsetCount;
                        if (blobAssetRefCount == 0)
                        {
                            continue;
                        }

                        var chunkBuffer = chunk->Buffer;

                        if (type.IsBuffer)
                        {
                        }
                        else if (blobAssetRefCount > 0)
                        {
                            int   subArrayOffset      = archetype->Offsets[ti];
                            byte *componentArrayStart = OffsetFromPointer(chunkBuffer, subArrayOffset);
                            int   size = archetype->SizeOfs[ti];
                            byte *end  = componentArrayStart + size * entityCount;
                            for (var componentData = componentArrayStart; componentData < end; componentData += size)
                            {
                                for (int i = 0; i < blobAssetRefCount; ++i)
                                {
                                    var offset          = ct.BlobAssetRefOffsets[i].Offset;
                                    var blobAssetRefPtr = (BlobAssetReferenceData *)(componentData + offset);
                                    if (blobAssetRefPtr->m_Ptr == null)
                                    {
                                        continue;
                                    }

                                    var blobAssetPtr = new BlobAssetPtr((*(BlobAssetHeader **)blobAssetRefPtr) - 1);
                                    var key          = new BlobAssetRefKey {
                                        chunk = chunk, offsetInBuffer = (int)((byte *)blobAssetRefPtr - chunkBuffer)
                                    };


                                    if (!blobAssetMap.TryGetValue(blobAssetPtr, out var blobAssetIndex))
                                    {
                                        blobAssetIndex = blobAssets.Length;
                                        blobAssets.Add(blobAssetPtr);
                                        blobAssetMap.TryAdd(blobAssetPtr, blobAssetIndex);
                                    }
                                    blobAssetRefs.TryAdd(key, blobAssetIndex);
                                }
                            }
                        }
                    }
                }
            }
            blobAssetMap.Dispose();
        }