Пример #1
0
        void InstantiateEntitiesGroup(Entity *srcEntities, int srcEntityCount,
                                      Entity *outputRootEntities, int instanceCount)
        {
            int totalCount = srcEntityCount * instanceCount;

            var tempAllocSize = sizeof(Entity) * totalCount +
                                sizeof(InstantiateRemapChunk) * totalCount + sizeof(Entity) * instanceCount;
            byte *    allocation;
            const int kMaxStackAllocSize = 16 * 1024;

            if (tempAllocSize > kMaxStackAllocSize)
            {
                allocation = (byte *)UnsafeUtility.Malloc(tempAllocSize, 16, Allocator.Temp);
            }
            else
            {
                var temp = stackalloc byte[tempAllocSize];

                allocation = temp;
            }

            var entityRemap    = (Entity *)allocation;
            var remapChunks    = (InstantiateRemapChunk *)(entityRemap + totalCount);
            var outputEntities = (Entity *)(remapChunks + totalCount);

            var remapChunksCount = 0;

            for (int i = 0; i != srcEntityCount; i++)
            {
                var srcEntity = srcEntities[i];

                remapChunksCount = InstantiateEntitiesOne(srcEntity,
                                                          outputEntities, instanceCount, remapChunks, remapChunksCount);

                for (int r = 0; r != instanceCount; r++)
                {
                    var ptr = entityRemap + (r * srcEntityCount + i);
                    *   ptr = outputEntities[r];
                }

                if (i == 0)
                {
                    for (int r = 0; r != instanceCount; r++)
                    {
                        outputRootEntities[r] = outputEntities[r];
                    }
                }
            }


            for (int i = 0; i != remapChunksCount; i++)
            {
                var chunk              = remapChunks[i].Chunk;
                var dstArchetype       = chunk->Archetype;
                var allocatedCount     = remapChunks[i].AllocatedCount;
                var indexInChunk       = remapChunks[i].IndexInChunk;
                var instanceBeginIndex = remapChunks[i].InstanceBeginIndex;

                var localRemap = entityRemap + instanceBeginIndex * srcEntityCount;

                EntityRemapUtility.PatchEntitiesForPrefab(dstArchetype->ScalarEntityPatches + 1, dstArchetype->ScalarEntityPatchCount - 1,
                                                          dstArchetype->BufferEntityPatches, dstArchetype->BufferEntityPatchCount,
                                                          chunk->Buffer, indexInChunk, allocatedCount, srcEntities, localRemap, srcEntityCount);

                if (dstArchetype->ManagedEntityPatchCount > 0)
                {
                    ManagedChangesTracker.PatchEntitiesForPrefab(dstArchetype, chunk, indexInChunk, allocatedCount, srcEntities, localRemap, srcEntityCount, Allocator.Temp);
                }
            }

            if (tempAllocSize > kMaxStackAllocSize)
            {
                UnsafeUtility.Free(allocation, Allocator.Temp);
            }
        }