예제 #1
0
        // Ensure there are at least "count" free managed component indices and
        // resize managed component array directly if needed
        public void ReserveManagedComponentIndicesDirect(int count, ref EntityComponentStore entityComponentStore)
        {
            int freeCount = entityComponentStore.ManagedComponentFreeCount;

            if (freeCount >= count)
            {
                return;
            }

            int newCapacity = entityComponentStore.GrowManagedComponentCapacity(count - freeCount);

            SetManagedComponentCapacity(newCapacity);
        }
예제 #2
0
        public void UpdateManagedComponentValue(int *index, object value, ref EntityComponentStore entityComponentStore)
        {
            entityComponentStore.AssertNoQueuedManagedDeferredCommands();
            var iManagedComponent = *index;

            if (value != null)
            {
                if (iManagedComponent == 0)
                {
                    ReserveManagedComponentIndicesDirect(1, ref entityComponentStore);
                    iManagedComponent = *index = entityComponentStore.AllocateManagedComponentIndex();
                }
            }
            else
            {
                if (iManagedComponent == 0)
                {
                    return;
                }
                *index = 0;
                entityComponentStore.FreeManagedComponentIndex(iManagedComponent);
            }
            m_ManagedComponentData[iManagedComponent] = value;
        }
        public static void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            Assert.IsFalse(srcChunk == dstChunk);
            var srcArch = srcChunk->Archetype;
            var dstArch = dstChunk->Archetype;

            if (srcArch != dstArch)
            {
                Assert.IsFalse(srcArch == null);
            }

            var srcI = srcArch->NonZeroSizedTypesCount - 1;
            var dstI = dstArch->NonZeroSizedTypesCount - 1;

            var sourceTypesToDealloc      = stackalloc int[srcI + 1];
            int sourceTypesToDeallocCount = 0;

            while (dstI >= 0)
            {
                var srcType = srcArch->Types[srcI];
                var dstType = dstArch->Types[dstI];

                if (srcType > dstType)
                {
                    //Type in source is not moved so deallocate it
                    sourceTypesToDealloc[sourceTypesToDeallocCount++] = srcI;
                    --srcI;
                    continue;
                }

                var srcStride = srcArch->SizeOfs[srcI];
                var dstStride = dstArch->SizeOfs[dstI];
                var src       = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride;
                var dst       = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstStride;

                if (srcType == dstType)
                {
                    UnsafeUtility.MemCpy(dst, src, count * srcStride);
                    --srcI;
                    --dstI;
                }
                else
                {
                    if (dstType.IsBuffer)
                    {
                        InitializeBuffersInChunk(dst, count, dstStride, dstArch->BufferCapacities[dstI]);
                    }
                    else
                    {
                        UnsafeUtility.MemClear(dst, count * dstStride);
                    }
                    --dstI;
                }
            }

            if (sourceTypesToDeallocCount == 0)
            {
                return;
            }

            sourceTypesToDealloc[sourceTypesToDeallocCount] = 0;

            int iDealloc = 0;

            if (sourceTypesToDealloc[iDealloc] >= srcArch->FirstManagedComponent)
            {
                var freeCommandHandle = entityComponentStore.ManagedChangesTracker.BeginFreeManagedComponentCommand();
                do
                {
                    srcI = sourceTypesToDealloc[iDealloc];
                    var srcStride = srcArch->SizeOfs[srcI];
                    var src       = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride;

                    var a = (int *)src;
                    for (int i = 0; i < count; i++)
                    {
                        var managedComponentIndex = a[i];
                        if (managedComponentIndex == 0)
                        {
                            continue;
                        }
                        entityComponentStore.FreeManagedComponentIndex(managedComponentIndex);
                        entityComponentStore.ManagedChangesTracker.AddToFreeManagedComponentCommand(managedComponentIndex);
                    }
                } while ((sourceTypesToDealloc[++iDealloc] >= srcArch->FirstManagedComponent));
                entityComponentStore.ManagedChangesTracker.EndDeallocateManagedComponentCommand(freeCommandHandle);
            }

            while (sourceTypesToDealloc[iDealloc] >= srcArch->FirstBufferComponent)
            {
                srcI = sourceTypesToDealloc[iDealloc];
                var srcStride = srcArch->SizeOfs[srcI];
                var srcPtr    = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride;
                for (int i = 0; i < count; i++)
                {
                    BufferHeader.Destroy((BufferHeader *)srcPtr);
                    srcPtr += srcStride;
                }
                ++iDealloc;
            }
        }
        public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            var srcArchetype        = srcChunk->Archetype;
            var srcBuffer           = srcChunk->Buffer;
            var dstBuffer           = dstChunk->Buffer;
            var dstArchetype        = dstChunk->Archetype;
            var srcOffsets          = srcArchetype->Offsets;
            var srcSizeOfs          = srcArchetype->SizeOfs;
            var srcBufferCapacities = srcArchetype->BufferCapacities;
            var srcTypes            = srcArchetype->Types;
            var dstTypes            = dstArchetype->Types;
            var dstOffsets          = dstArchetype->Offsets;
            var dstTypeIndex        = 1;

            var nativeComponentsEnd = srcArchetype->NativeComponentsEnd;

            for (var srcTypeIndex = 1; srcTypeIndex != nativeComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                UnsafeUtility.MemCpyReplicate(dst, src, srcSizeOf, count);
                dstTypeIndex++;
            }

            dstTypeIndex = dstArchetype->FirstBufferComponent;
            var bufferComponentsEnd = srcArchetype->BufferComponentsEnd;

            for (var srcTypeIndex = srcArchetype->FirstBufferComponent; srcTypeIndex != bufferComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                var srcBufferCapacity = srcBufferCapacities[srcTypeIndex];
                var alignment         = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager
                var elementSize       = TypeManager.GetTypeInfo(srcType.TypeIndex).ElementSize;
                for (int i = 0; i < count; ++i)
                {
                    BufferHeader *srcHdr = (BufferHeader *)src;
                    BufferHeader *dstHdr = (BufferHeader *)dst;
                    BufferHeader.Initialize(dstHdr, srcBufferCapacity);
                    BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, elementSize, alignment, false, 0);

                    dst += srcSizeOf;
                }

                dstTypeIndex++;
            }

            if (dstArchetype->NumManagedComponents > 0)
            {
                ReplicateManagedComponents(srcChunk, srcIndex, dstChunk, dstBaseIndex, count, ref entityComponentStore);
            }
        }
        public static void ReplicateManagedComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            var dstArchetype   = dstChunk->Archetype;
            var srcArchetype   = srcChunk->Archetype;
            var srcTypes       = srcArchetype->Types;
            var dstTypes       = dstArchetype->Types;
            var srcOffsets     = srcArchetype->Offsets;
            var dstOffsets     = dstArchetype->Offsets;
            int componentCount = dstArchetype->NumManagedComponents;

            int nonNullManagedComponents = 0;
            int nonNullHybridComponents  = 0;
            var componentIndices         = stackalloc int[componentCount];
            var componentDstArrayStart   = stackalloc IntPtr[componentCount];

            var firstDstManagedComponent = dstArchetype->FirstManagedComponent;
            var dstTypeIndex             = firstDstManagedComponent;
            var managedComponentsEnd     = srcArchetype->ManagedComponentsEnd;
            var srcBaseAddr = srcChunk->Buffer + sizeof(int) * srcIndex;
            var dstBaseAddr = dstChunk->Buffer + sizeof(int) * dstBaseIndex;

            bool hasHybridComponents = dstArchetype->HasHybridComponents;

            for (var srcTypeIndex = srcArchetype->FirstManagedComponent; srcTypeIndex != managedComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                int srcManagedComponentIndex = *(int *)(srcBaseAddr + srcOffsets[srcTypeIndex]);
                var dstArrayStart            = dstBaseAddr + dstOffsets[dstTypeIndex];

                if (srcManagedComponentIndex == 0)
                {
                    UnsafeUtility.MemClear(dstArrayStart, sizeof(int) * count);
                }
                else
                {
                    if (hasHybridComponents && TypeManager.GetTypeInfo(srcType.TypeIndex).Category == TypeManager.TypeCategory.Class)
                    {
                        //Hybrid component, put at end of array
                        var index = componentCount - nonNullHybridComponents - 1;
                        componentIndices[index]       = srcManagedComponentIndex;
                        componentDstArrayStart[index] = (IntPtr)dstArrayStart;
                        ++nonNullHybridComponents;
                    }
                    else
                    {
                        componentIndices[nonNullManagedComponents]       = srcManagedComponentIndex;
                        componentDstArrayStart[nonNullManagedComponents] = (IntPtr)dstArrayStart;
                        ++nonNullManagedComponents;
                    }
                }

                dstTypeIndex++;
            }

            entityComponentStore.ReserveManagedComponentIndices(count * (nonNullManagedComponents + nonNullHybridComponents));
            entityComponentStore.ManagedChangesTracker.CloneManagedComponentBegin(componentIndices, nonNullManagedComponents, count);
            for (int c = 0; c < nonNullManagedComponents; ++c)
            {
                var dst = (int *)(componentDstArrayStart[c]);
                entityComponentStore.AllocateManagedComponentIndices(dst, count);
                entityComponentStore.ManagedChangesTracker.CloneManagedComponentAddDstIndices(dst, count);
            }

            if (hasHybridComponents)
            {
                var companionLinkIndexInTypeArray = GetIndexInTypeArray(dstArchetype, ManagedComponentStore.CompanionLinkTypeIndex);
                var companionLinkIndices          = (companionLinkIndexInTypeArray == -1) ? null : (int *)(dstBaseAddr + dstOffsets[companionLinkIndexInTypeArray]);

                var dstEntities = (Entity *)dstChunk->Buffer + dstBaseIndex;
                entityComponentStore.ManagedChangesTracker.CloneHybridComponentBegin(
                    componentIndices + componentCount - nonNullHybridComponents, nonNullHybridComponents, dstEntities, count, companionLinkIndices);
                for (int c = componentCount - nonNullHybridComponents; c < componentCount; ++c)
                {
                    var dst = (int *)(componentDstArrayStart[c]);
                    entityComponentStore.AllocateManagedComponentIndices(dst, count);
                    entityComponentStore.ManagedChangesTracker.CloneHybridComponentAddDstIndices(dst, count);
                }
            }
        }
예제 #6
0
 public void ResetManagedComponentStoreForDeserialization(int managedComponentCount, ref EntityComponentStore entityComponentStore)
 {
     managedComponentCount++; // also need space for 0 index (null)
     UnityEngine.Assertions.Assert.AreEqual(0, entityComponentStore.ManagedComponentIndexUsedCount);
     entityComponentStore.m_ManagedComponentFreeIndex.Size = 0;
     entityComponentStore.m_ManagedComponentIndex          = managedComponentCount;
     if (managedComponentCount > entityComponentStore.m_ManagedComponentIndexCapacity)
     {
         entityComponentStore.m_ManagedComponentIndexCapacity = managedComponentCount;
         SetManagedComponentCapacity(managedComponentCount);
     }
 }
예제 #7
0
 public void CloneManagedComponentsFromDifferentWorld(int *indices, int count, ManagedComponentStore srcManagedComponentStore, ref EntityComponentStore dstEntityComponentStore)
 {
     dstEntityComponentStore.AssertNoQueuedManagedDeferredCommands();
     ReserveManagedComponentIndicesDirect(count, ref dstEntityComponentStore);
     for (int i = 0; i < count; ++i)
     {
         var obj      = srcManagedComponentStore.m_ManagedComponentData[indices[i]];
         var clone    = CloneManagedComponent(obj);
         int dstIndex = dstEntityComponentStore.AllocateManagedComponentIndex();
         m_ManagedComponentData[dstIndex] = clone;
     }
 }