Exemplo n.º 1
0
        private static unsafe void ApplySetComponents(
            EntityManager entityManager,
            NativeArray <PackedComponentDataChange> changes,
            NativeArray <byte> payload,
            NativeArray <EntityGuid> packedEntityGuids,
            NativeMultiHashMap <int, Entity> packedEntities,
            NativeArray <ComponentType> packedTypes,
            NativeMultiHashMap <EntityGuid, Entity> entityGuidToEntity,
            NativeHashMap <Entity, EntityGuid> entityToEntityGuid)
        {
            var entityGuidTypeIndex = TypeManager.GetTypeIndex <EntityGuid>();

            var offset = 0L;

            for (var i = 0; i < changes.Length; i++)
            {
                var packedComponentDataChange = changes[i];
                var packedComponent           = packedComponentDataChange.Component;
                var component = packedTypes[packedComponent.PackedTypeIndex];
                var size      = packedComponentDataChange.Size;
                var data      = (byte *)payload.GetUnsafeReadOnlyPtr() + offset;
                var componentTypeInArchetype = new ComponentTypeInArchetype(component);

                if (packedEntities.TryGetFirstValue(packedComponent.PackedEntityIndex, out var entity, out var iterator))
                {
                    do
                    {
                        if (!entityManager.Exists(entity))
                        {
                            Debug.LogWarning($"SetComponent<{component}>({packedEntityGuids[packedComponent.PackedEntityIndex]}) but entity does not exist.");
                        }
                        else if (!entityManager.HasComponent(entity, component))
                        {
                            Debug.LogWarning($"SetComponent<{component}>({packedEntityGuids[packedComponent.PackedEntityIndex]}) but component does not exist.");
                        }
                        else
                        {
                            if (componentTypeInArchetype.IsZeroSized)
                            {
                                // Nothing to set.
                            }
                            else if (componentTypeInArchetype.IsBuffer)
                            {
                                var typeInfo         = TypeManager.GetTypeInfo(componentTypeInArchetype.TypeIndex);
                                var elementSize      = typeInfo.ElementSize;
                                var lengthInElements = size / elementSize;
                                var header           = (BufferHeader *)entityManager.GetComponentDataRawRW(entity, component.TypeIndex);
                                BufferHeader.Assign(header, data, lengthInElements, elementSize, 16);
                            }
                            else
                            {
                                var target = (byte *)entityManager.GetComponentDataRawRW(entity, component.TypeIndex);

                                // Perform incremental updates on the entityGuidToEntity map to avoid a full rebuild.
                                if (componentTypeInArchetype.TypeIndex == entityGuidTypeIndex)
                                {
                                    EntityGuid entityGuid;
                                    UnsafeUtility.MemCpy(&entityGuid, target, sizeof(EntityGuid));

                                    if (!entityGuid.Equals(default))
        public static Archetype *GetArchetypeWithAddedComponentType(Archetype *archetype, ComponentType addedComponentType, EntityComponentStore *entityComponentStore, int *indexInTypeArray = null)
        {
            var componentType = new ComponentTypeInArchetype(addedComponentType);
            ComponentTypeInArchetype *newTypes = stackalloc ComponentTypeInArchetype[archetype->TypesCount + 1];

            var t = 0;

            while (t < archetype->TypesCount && archetype->Types[t] < componentType)
            {
                newTypes[t] = archetype->Types[t];
                ++t;
            }

            if (indexInTypeArray != null)
            {
                *indexInTypeArray = t;
            }

            if (archetype->Types[t] == componentType)
            {
                Assert.IsTrue(addedComponentType.IgnoreDuplicateAdd, $"{addedComponentType} is already part of the archetype.");
                // Tag component type is already there, no new archetype required.
                return(null);
            }

            newTypes[t] = componentType;
            while (t < archetype->TypesCount)
            {
                newTypes[t + 1] = archetype->Types[t];
                ++t;
            }

            return(GetOrCreateArchetype(newTypes, archetype->TypesCount + 1, entityComponentStore));
        }
        public static Archetype *GetArchetypeWithRemovedComponentType(Archetype *archetype, ComponentType addedComponentType, EntityComponentStore *entityComponentStore, int *indexInOldTypeArray = null)
        {
            var componentType = new ComponentTypeInArchetype(addedComponentType);
            ComponentTypeInArchetype *newTypes = stackalloc ComponentTypeInArchetype[archetype->TypesCount];

            var removedTypes = 0;

            for (var t = 0; t < archetype->TypesCount; ++t)
            {
                if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                {
                    if (indexInOldTypeArray != null)
                    {
                        *indexInOldTypeArray = t;
                    }
                    ++removedTypes;
                }
                else
                {
                    newTypes[t - removedTypes] = archetype->Types[t];
                }
            }

            return(GetOrCreateArchetype(newTypes, archetype->TypesCount - removedTypes, entityComponentStore));
        }
Exemplo n.º 4
0
 int PopulatedCachedTypeInArchetypeArray(ComponentType[] requiredComponents)
 {
     m_CachedComponentTypeInArchetypeArray[0] = new ComponentTypeInArchetype(ComponentType.Create <Entity>());
     for (var i = 0; i < requiredComponents.Length; ++i)
     {
         SortingUtilities.InsertSorted(m_CachedComponentTypeInArchetypeArray, i + 1, requiredComponents[i]);
     }
     return(requiredComponents.Length + 1);
 }
Exemplo n.º 5
0
 private int PopulatedCachedTypeInArchetypeArray(ComponentType *requiredComponents, int count)
 {
     m_CachedComponentTypeInArchetypeArray[0] = new ComponentTypeInArchetype(ComponentType.Create <Entity>());
     for (var i = 0; i < count; ++i)
     {
         SortingUtilities.InsertSorted(m_CachedComponentTypeInArchetypeArray, i + 1, requiredComponents[i]);
     }
     return(count + 1);
 }
        public static unsafe void InsertSorted(ComponentTypeInArchetype *data, int length, ComponentType newValue)
        {
            var newVal = new ComponentTypeInArchetype(newValue);

            while (length > 0 && newVal < data[length - 1])
            {
                data[length] = data[length - 1];
                --length;
            }
            data[length] = newVal;
        }
        public static unsafe void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count)
        {
            Archetype *archetypePtr                 = srcChunk.Archetype;
            byte *     numPtr                       = &srcChunk.Buffer.FixedElementField;
            byte *     numPtr2                      = &dstChunk.Buffer.FixedElementField;
            Archetype *archetypePtr2                = dstChunk.Archetype;
            int *      offsets                      = archetypePtr->Offsets;
            int *      sizeOfs                      = archetypePtr->SizeOfs;
            int        typesCount                   = archetypePtr->TypesCount;
            ComponentTypeInArchetype *types         = archetypePtr->Types;
            ComponentTypeInArchetype *archetypePtr4 = archetypePtr2->Types;
            int *numPtr5 = archetypePtr2->Offsets;
            int  index   = 1;

            for (int i = 1; i != typesCount; i++)
            {
                ComponentTypeInArchetype archetype  = types[i];
                ComponentTypeInArchetype archetype2 = archetypePtr4[index];
                if (archetype.TypeIndex == archetype2.TypeIndex)
                {
                    int   size    = sizeOfs[i];
                    byte *numPtr6 = numPtr + (offsets[i] + (size * srcIndex));
                    byte *numPtr7 = numPtr2 + (numPtr5[index] + (size * dstBaseIndex));
                    if (!archetype.IsBuffer)
                    {
                        UnsafeUtility.MemCpyReplicate((void *)numPtr7, (void *)numPtr6, size, count);
                    }
                    else
                    {
                        int alignment   = 8;
                        int elementSize = TypeManager.GetTypeInfo(archetype.TypeIndex).ElementSize;
                        int num9        = 0;
                        while (true)
                        {
                            if (num9 >= count)
                            {
                                break;
                            }
                            BufferHeader *header     = (BufferHeader *)numPtr6;
                            BufferHeader *headerPtr2 = (BufferHeader *)numPtr7;
                            BufferHeader.Initialize(headerPtr2, archetype.BufferCapacity);
                            BufferHeader.Assign(headerPtr2, BufferHeader.GetElementPointer(header), header->Length, elementSize, alignment);
                            numPtr7 += size;
                            num9++;
                        }
                    }
                    index++;
                }
            }
        }
Exemplo n.º 8
0
        public EntityArchetype GetEntityOnlyArchetype()
        {
            if (!m_EntityOnlyArchetype.Valid)
            {
                ComponentTypeInArchetype entityType = new ComponentTypeInArchetype(ComponentType.ReadWrite <Entity>());
                var archetype = EntityManagerCreateArchetypeUtility.GetOrCreateArchetype(&entityType,
                                                                                         1, EntityComponentStore, EntityGroupManager);
                m_EntityOnlyArchetype = new EntityArchetype {
                    Archetype = archetype
                };
            }

            return(m_EntityOnlyArchetype);
        }
Exemplo n.º 9
0
        public static unsafe void InsertSorted(ComponentTypeInArchetype *data, int length, ComponentType newValue)
        {
            ComponentTypeInArchetype archetype = new ComponentTypeInArchetype(newValue);

            while (true)
            {
                if ((length <= 0) || (archetype >= data[length - 1]))
                {
                    data[length] = archetype;
                    return;
                }
                data[length] = data[length - 1];
                length--;
            }
        }
Exemplo n.º 10
0
        private int PopulatedCachedTypeInArchetypeArray(ComponentType *requiredComponents, int count)
        {
            #if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (count + 1 > m_CachedComponentTypeInArchetypeArrayLength)
            {
                throw new System.ArgumentException($"Archetypes can't hold more than {m_CachedComponentTypeInArchetypeArrayLength}");
            }
            #endif

            m_CachedComponentTypeInArchetypeArray[0] = new ComponentTypeInArchetype(ComponentType.Create <Entity>());
            for (var i = 0; i < count; ++i)
            {
                SortingUtilities.InsertSorted(m_CachedComponentTypeInArchetypeArray, i + 1, requiredComponents[i]);
            }
            return(count + 1);
        }
Exemplo n.º 11
0
        public EntityArchetype GetEntityOnlyArchetype()
        {
            if (!m_EntityOnlyArchetype.Valid)
            {
                var archetypeChanges = EntityComponentStore->BeginArchetypeChangeTracking();
                ComponentTypeInArchetype entityType = new ComponentTypeInArchetype(ComponentType.ReadWrite <Entity>());
                var archetype = EntityComponentStore->GetOrCreateArchetype(&entityType, 1);
                m_EntityOnlyArchetype = new EntityArchetype {
                    Archetype = archetype
                };
                var changedArchetypes = EntityComponentStore->EndArchetypeChangeTracking(archetypeChanges);
                EntityQueryManager.AddAdditionalArchetypes(changedArchetypes);
            }

            return(m_EntityOnlyArchetype);
        }
Exemplo n.º 12
0
        public void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager,
                                 SharedComponentDataManager sharedComponentDataManager,
                                 EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);
            var archetype     = GetArchetype(entity);

            var t = 0;

            while (t < archetype->TypesCount && archetype->Types[t] < componentType)
            {
                componentTypeInArchetypeArray[t] = archetype->Types[t];
                ++t;
            }

            var indexInTypeArray = t;

            componentTypeInArchetypeArray[t] = componentType;
            while (t < archetype->TypesCount)
            {
                componentTypeInArchetypeArray[t + 1] = archetype->Types[t];
                ++t;
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount + 1, groupManager);

            int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;

            if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents))
            {
                var  oldSharedComponentDataIndices = sharedComponentDataIndices;
                int *stackAlloced = stackalloc int[newType->NumSharedComponents];
                sharedComponentDataIndices = stackAlloced;

                int indexOfNewSharedComponent = newType->SharedComponentOffset[indexInTypeArray];
                UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfNewSharedComponent * sizeof(int));
                sharedComponentDataIndices[indexOfNewSharedComponent] = 0;
                UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfNewSharedComponent + 1, oldSharedComponentDataIndices + indexOfNewSharedComponent,
                                     (archetype->NumSharedComponents - indexOfNewSharedComponent) * sizeof(int));
            }

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
            IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager);
        }
Exemplo n.º 13
0
        public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager,
                                    SharedComponentDataManager sharedComponentDataManager,
                                    EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);

            var archetype = GetArchetype(entity);

            var removedTypes        = 0;
            int indexInOldTypeArray = -1;

            for (var t = 0; t < archetype->TypesCount; ++t)
            {
                if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                {
                    indexInOldTypeArray = t;
                    ++removedTypes;
                }
                else
                {
                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                }
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount - removedTypes, groupManager);

            int *sharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;

            if ((newType->NumSharedComponents > 0) && (newType->NumSharedComponents != archetype->NumSharedComponents))
            {
                var  oldSharedComponentDataIndices = sharedComponentDataIndices;
                int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                sharedComponentDataIndices = tempAlloc;

                int indexOfRemovedSharedComponent = archetype->SharedComponentOffset[indexInOldTypeArray];
                UnsafeUtility.MemCpy(sharedComponentDataIndices, oldSharedComponentDataIndices, indexOfRemovedSharedComponent * sizeof(int));
                UnsafeUtility.MemCpy(sharedComponentDataIndices + indexOfRemovedSharedComponent, oldSharedComponentDataIndices + indexOfRemovedSharedComponent + 1, (newType->NumSharedComponents - indexOfRemovedSharedComponent) * sizeof(int));
            }

            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager);

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
        }
Exemplo n.º 14
0
        public Archetype *GetExistingArchetype(ComponentTypeInArchetype *types, int count)
        {
            IntPtr typePtr;
            NativeMultiHashMapIterator <uint> it;

            if (!m_TypeLookup.TryGetFirstValue(GetHash(types, count), out typePtr, out it))
            {
                return(null);
            }

            do
            {
                var type = (Archetype *)typePtr;
                if (ComponentTypeInArchetype.CompareArray(type->Types, type->TypesCount, types, count))
                {
                    return(type);
                }
            } while (m_TypeLookup.TryGetNextValue(out typePtr, ref it));

            return(null);
        }
Exemplo n.º 15
0
            private void AddComponentData(
                Chunk *afterChunk,
                Archetype *afterArchetype,
                ComponentTypeInArchetype afterTypeInArchetype,
                int afterIndexInTypeArray,
                int afterEntityIndexInChunk,
                EntityGuid entityGuid,
                int typeIndex,
                TypeInfo typeInfo
                )
            {
                var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash);

                AddComponents.Add(packedComponent);

                if (afterTypeInArchetype.IsSharedComponent)
                {
                    var offset = afterIndexInTypeArray - afterChunk->Archetype->FirstSharedComponent;
                    var sharedComponentIndex = afterChunk->GetSharedComponentValue(offset);

                    // No managed objects in burst land. Do what we can a defer the actual unpacking until later.
                    ComponentDataStream.SetSharedComponentDataDeferred(entityGuid, afterTypeInArchetype.TypeIndex, sharedComponentIndex);
                    return;
                }

                // IMPORTANT This means `IsZeroSizedInChunk` which is always true for shared components.
                // Always check shared components first.
                if (afterTypeInArchetype.IsZeroSized)
                {
                    // Zero sized components have no data to copy.
                    return;
                }

                if (afterTypeInArchetype.IsBuffer)
                {
                    var sizeOf = afterArchetype->SizeOfs[afterIndexInTypeArray];
                    var buffer = (BufferHeader *)(ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterEntityIndexInChunk * sizeOf);
                    var length = buffer->Length;

                    if (length == 0)
                    {
                        return;
                    }

                    var elementPtr = BufferHeader.GetElementPointer(buffer);

                    if (afterTypeInArchetype.TypeIndex == TypeInfoStream.LinkedEntityGroupTypeIndex)
                    {
                        // Magic in AddComponent already put a self-reference at the top of the buffer, so there's no need for us to add it.
                        // The rest of the elements should be interpreted as LinkedEntityGroupAdditions.
                        for (var elementIndex = 1; elementIndex < length; elementIndex++)
                        {
                            var childEntity = ((Entity *)elementPtr)[elementIndex];
                            if (!AfterEntityToEntityGuid.TryGetValue(childEntity, out var childEntityGuid))
                            {
                                // If the child entity doesn't have a guid, there's no way for us to communicate its identity to the destination world.
                                throw new Exception("LinkedEntityGroup child is missing an EntityGuid component.");
                            }

                            LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange
                            {
                                RootEntityGuid  = entityGuid,
                                ChildEntityGuid = childEntityGuid
                            });
                        }
                    }
                    else
                    {
                        ComponentDataStream.SetComponentData(packedComponent, elementPtr, typeInfo.ElementSize * length);
                        ExtractEntityReferencePatches(typeInfo, packedComponent, elementPtr, length);
                    }
                }
                else
                {
                    var sizeOf = afterArchetype->SizeOfs[afterIndexInTypeArray];
                    var ptr    = ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterEntityIndexInChunk * sizeOf;
                    ComponentDataStream.SetComponentData(packedComponent, ptr, sizeOf);
                    ExtractEntityReferencePatches(typeInfo, packedComponent, ptr, 1);
                }
            }
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------

        public static Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *inTypesSorted, int count,
                                                      EntityComponentStore *entityComponentStore)
        {
            var srcArchetype = entityComponentStore->GetExistingArchetype(inTypesSorted, count);

            if (srcArchetype != null)
            {
                return(srcArchetype);
            }

            srcArchetype = entityComponentStore->CreateArchetype(inTypesSorted, count);
            var types = stackalloc ComponentTypeInArchetype[count + 1];

            // Setup Instantiable archetype
            {
                UnsafeUtility.MemCpy(types, inTypesSorted, sizeof(ComponentTypeInArchetype) * count);

                var hasCleanup       = false;
                var removedTypes     = 0;
                var prefabTypeIndex  = TypeManager.GetTypeIndex <Prefab>();
                var cleanupTypeIndex = TypeManager.GetTypeIndex <CleanupEntity>();
                for (var t = 0; t < srcArchetype->TypesCount; ++t)
                {
                    var type = srcArchetype->Types[t];

                    hasCleanup |= type.TypeIndex == cleanupTypeIndex;

                    var skip = type.IsSystemStateComponent || type.TypeIndex == prefabTypeIndex;
                    if (skip)
                    {
                        ++removedTypes;
                    }
                    else
                    {
                        types[t - removedTypes] = srcArchetype->Types[t];
                    }
                }

                // Entity has already been destroyed, so it shouldn't be instantiated anymore
                if (hasCleanup)
                {
                    srcArchetype->InstantiableArchetype = null;
                }
                else if (removedTypes > 0)
                {
                    var instantiableArchetype = GetOrCreateArchetype(types, count - removedTypes, entityComponentStore);

                    srcArchetype->InstantiableArchetype = instantiableArchetype;
                    Assert.IsTrue(instantiableArchetype->InstantiableArchetype == instantiableArchetype);
                    Assert.IsTrue(instantiableArchetype->SystemStateResidueArchetype == null);
                }
                else
                {
                    srcArchetype->InstantiableArchetype = srcArchetype;
                }
            }


            // Setup System state cleanup archetype
            if (srcArchetype->SystemStateCleanupNeeded)
            {
                var  cleanupEntityType = new ComponentTypeInArchetype(ComponentType.ReadWrite <CleanupEntity>());
                bool cleanupAdded      = false;

                types[0] = inTypesSorted[0];
                var newTypeCount = 1;

                for (var t = 1; t < srcArchetype->TypesCount; ++t)
                {
                    var type = srcArchetype->Types[t];

                    if (type.IsSystemStateComponent)
                    {
                        if (!cleanupAdded && (cleanupEntityType < srcArchetype->Types[t]))
                        {
                            types[newTypeCount++] = cleanupEntityType;
                            cleanupAdded          = true;
                        }

                        types[newTypeCount++] = srcArchetype->Types[t];
                    }
                }

                if (!cleanupAdded)
                {
                    types[newTypeCount++] = cleanupEntityType;
                }

                var systemStateResidueArchetype = GetOrCreateArchetype(types, newTypeCount, entityComponentStore);
                srcArchetype->SystemStateResidueArchetype = systemStateResidueArchetype;

                Assert.IsTrue(systemStateResidueArchetype->SystemStateResidueArchetype == systemStateResidueArchetype);
                Assert.IsTrue(systemStateResidueArchetype->InstantiableArchetype == null);
            }

            // Setup meta chunk archetype
            if (count > 1)
            {
                types[0] = new ComponentTypeInArchetype(typeof(Entity));
                int metaArchetypeTypeCount = 1;
                for (int i = 1; i < count; ++i)
                {
                    var           t = inTypesSorted[i];
                    ComponentType typeToInsert;
                    if (inTypesSorted[i].IsChunkComponent)
                    {
                        typeToInsert = new ComponentType
                        {
                            TypeIndex = TypeManager.ChunkComponentToNormalTypeIndex(t.TypeIndex)
                        };
                        SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, typeToInsert);
                    }
                }

                if (metaArchetypeTypeCount > 1)
                {
                    SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, new ComponentType(typeof(ChunkHeader)));
                    srcArchetype->MetaChunkArchetype = GetOrCreateArchetype(types, metaArchetypeTypeCount, entityComponentStore);
                }
            }

            return(srcArchetype);
        }
Exemplo n.º 17
0
        // ----------------------------------------------------------------------------------------------------------
        // PUBLIC
        // ----------------------------------------------------------------------------------------------------------
        public Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *inTypesSorted, int count)
        {
            var srcArchetype = GetExistingArchetype(inTypesSorted, count);

            if (srcArchetype != null)
            {
                return(srcArchetype);
            }

            srcArchetype = CreateArchetype(inTypesSorted, count);

            var types = stackalloc ComponentTypeInArchetype[count + 1];

            srcArchetype->InstantiateArchetype = CreateInstanceArchetype(inTypesSorted, count, types, srcArchetype, true);
            srcArchetype->CopyArchetype        = CreateInstanceArchetype(inTypesSorted, count, types, srcArchetype, false);

            if (srcArchetype->InstantiateArchetype != null)
            {
                Assert.IsTrue(srcArchetype->InstantiateArchetype->InstantiateArchetype == srcArchetype->InstantiateArchetype);
                Assert.IsTrue(srcArchetype->InstantiateArchetype->SystemStateResidueArchetype == null);
            }

            if (srcArchetype->CopyArchetype != null)
            {
                Assert.IsTrue(srcArchetype->CopyArchetype->CopyArchetype == srcArchetype->CopyArchetype);
                Assert.IsTrue(srcArchetype->CopyArchetype->SystemStateResidueArchetype == null);
            }


            // Setup System state cleanup archetype
            if (srcArchetype->SystemStateCleanupNeeded)
            {
                var  cleanupEntityType = new ComponentTypeInArchetype(ComponentType.FromTypeIndex(m_CleanupEntityType));
                bool cleanupAdded      = false;

                types[0] = inTypesSorted[0];
                var newTypeCount = 1;

                for (var t = 1; t < srcArchetype->TypesCount; ++t)
                {
                    var type = srcArchetype->Types[t];

                    if (type.IsSystemStateComponent)
                    {
                        if (!cleanupAdded && (cleanupEntityType < srcArchetype->Types[t]))
                        {
                            types[newTypeCount++] = cleanupEntityType;
                            cleanupAdded          = true;
                        }

                        types[newTypeCount++] = srcArchetype->Types[t];
                    }
                }

                if (!cleanupAdded)
                {
                    types[newTypeCount++] = cleanupEntityType;
                }

                var systemStateResidueArchetype = GetOrCreateArchetype(types, newTypeCount);
                srcArchetype->SystemStateResidueArchetype = systemStateResidueArchetype;

                Assert.IsTrue(systemStateResidueArchetype->SystemStateResidueArchetype == systemStateResidueArchetype);
                Assert.IsTrue(systemStateResidueArchetype->InstantiateArchetype == null);
                Assert.IsTrue(systemStateResidueArchetype->CopyArchetype == null);
            }

            // Setup meta chunk archetype
            if (count > 1)
            {
                types[0] = new ComponentTypeInArchetype(m_EntityComponentType);
                int metaArchetypeTypeCount = 1;
                for (int i = 1; i < count; ++i)
                {
                    var           t = inTypesSorted[i];
                    ComponentType typeToInsert;
                    if (inTypesSorted[i].IsChunkComponent)
                    {
                        typeToInsert = new ComponentType
                        {
                            TypeIndex = ChunkComponentToNormalTypeIndex(t.TypeIndex)
                        };
                        SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, typeToInsert);
                    }
                }

                if (metaArchetypeTypeCount > 1)
                {
                    SortingUtilities.InsertSorted(types, metaArchetypeTypeCount++, m_ChunkHeaderComponentType);
                    srcArchetype->MetaChunkArchetype = GetOrCreateArchetype(types, metaArchetypeTypeCount);
                }
            }

            return(srcArchetype);
        }
Exemplo n.º 18
0
        public void RemoveComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager,
                                    EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);

            var archetype = GetArchetype(entity);

            var removedTypes = 0;

            for (var t = 0; t < archetype->TypesCount; ++t)
            {
                if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                {
                    ++removedTypes;
                }
                else
                {
                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                }
            }

            Assert.AreNotEqual(-1, removedTypes);

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount - removedTypes, groupManager);

            int *sharedComponentDataIndices = null;

            if (newType->NumSharedComponents > 0)
            {
                var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;
                var removedComponentIsShared      = TypeManager.TypeCategory.ISharedComponentData ==
                                                    TypeManager.GetComponentType(type.TypeIndex).Category;
                removedTypes = 0;
                if (removedComponentIsShared)
                {
                    int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                    sharedComponentDataIndices = tempAlloc;

                    int srcIndex = 0;
                    int dstIndex = 0;
                    for (var t = 0; t < archetype->TypesCount; ++t)
                    {
                        if (archetype->SharedComponentOffset[t] != -1)
                        {
                            if (archetype->Types[t].TypeIndex == componentType.TypeIndex)
                            {
                                srcIndex++;
                            }
                            else
                            {
                                sharedComponentDataIndices[dstIndex] = oldSharedComponentDataIndices[srcIndex];
                                srcIndex++;
                                dstIndex++;
                            }
                        }
                    }
                }
                else
                {
                    // reuse old sharedComponentDataIndices
                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                }
            }

            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity), sharedComponentDataManager);

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
        }
Exemplo n.º 19
0
        public void AddComponent(Entity entity, ComponentType type, ArchetypeManager archetypeManager, SharedComponentDataManager sharedComponentDataManager,
                                 EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var componentType = new ComponentTypeInArchetype(type);
            var archetype     = GetArchetype(entity);

            var t = 0;

            while (t < archetype->TypesCount && archetype->Types[t] < componentType)
            {
                componentTypeInArchetypeArray[t] = archetype->Types[t];
                ++t;
            }

            componentTypeInArchetypeArray[t] = componentType;
            while (t < archetype->TypesCount)
            {
                componentTypeInArchetypeArray[t + 1] = archetype->Types[t];
                ++t;
            }

            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                archetype->TypesCount + 1, groupManager);

            int *sharedComponentDataIndices = null;

            if (newType->NumSharedComponents > 0)
            {
                var oldSharedComponentDataIndices = GetComponentChunk(entity)->SharedComponentValueArray;
                var newComponentIsShared          = (TypeManager.TypeCategory.ISharedComponentData ==
                                                     TypeManager.GetComponentType(type.TypeIndex).Category);
                if (newComponentIsShared)
                {
                    int *stackAlloced = stackalloc int[newType->NumSharedComponents];
                    sharedComponentDataIndices = stackAlloced;

                    if (archetype->SharedComponentOffset == null)
                    {
                        sharedComponentDataIndices[0] = 0;
                    }
                    else
                    {
                        t = 0;
                        var sharedIndex = 0;
                        while (t < archetype->TypesCount && archetype->Types[t] < componentType)
                        {
                            if (archetype->SharedComponentOffset[t] != -1)
                            {
                                sharedComponentDataIndices[sharedIndex] = oldSharedComponentDataIndices[sharedIndex];
                                ++sharedIndex;
                            }

                            ++t;
                        }

                        sharedComponentDataIndices[sharedIndex] = 0;
                        while (t < archetype->TypesCount)
                        {
                            if (archetype->SharedComponentOffset[t] != -1)
                            {
                                sharedComponentDataIndices[sharedIndex + 1] =
                                    oldSharedComponentDataIndices[sharedIndex];
                                ++sharedIndex;
                            }

                            ++t;
                        }
                    }
                }
                else
                {
                    // reuse old sharedComponentDataIndices
                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                }
            }

            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);

            IncrementComponentOrderVersion(newType, GetComponentChunk(entity), sharedComponentDataManager);
        }
Exemplo n.º 20
0
        public Archetype *GetOrCreateArchetype(ComponentTypeInArchetype *types, int count,
                                               EntityGroupManager groupManager)
        {
            var srcArchetype = GetExistingArchetype(types, count);

            if (srcArchetype != null)
            {
                return(srcArchetype);
            }

            srcArchetype = CreateArchetypeInternal(types, count, groupManager);

            var removedTypes    = 0;
            var prefabTypeIndex = TypeManager.GetTypeIndex <Prefab>();

            for (var t = 0; t < srcArchetype->TypesCount; ++t)
            {
                var type = srcArchetype->Types[t];
                var skip = type.IsSystemStateComponent || type.IsSystemStateSharedComponent || (type.TypeIndex == prefabTypeIndex);
                if (skip)
                {
                    ++removedTypes;
                }
                else
                {
                    types[t - removedTypes] = srcArchetype->Types[t];
                }
            }

            srcArchetype->InstantiableArchetype = srcArchetype;
            if (removedTypes > 0)
            {
                var instantiableArchetype = GetOrCreateArchetypeInternal(types, count - removedTypes, groupManager);

                srcArchetype->InstantiableArchetype                = instantiableArchetype;
                instantiableArchetype->InstantiableArchetype       = instantiableArchetype;
                instantiableArchetype->SystemStateResidueArchetype = null;
            }

            if (!srcArchetype->SystemStateCleanupNeeded)
            {
                return(srcArchetype);
            }

            var  cleanupEntityType = new ComponentTypeInArchetype(ComponentType.Create <CleanupEntity>());
            bool cleanupAdded      = false;

            var newTypeCount = 1;

            for (var t = 1; t < srcArchetype->TypesCount; ++t)
            {
                var type = srcArchetype->Types[t];

                if (type.IsSystemStateComponent || type.IsSystemStateSharedComponent)
                {
                    if (!cleanupAdded && (cleanupEntityType < srcArchetype->Types[t]))
                    {
                        types[newTypeCount++] = cleanupEntityType;
                        cleanupAdded          = true;
                    }
                    types[newTypeCount++] = srcArchetype->Types[t];
                }
            }
            if (!cleanupAdded)
            {
                types[newTypeCount++] = cleanupEntityType;
            }
            var systemStateResidueArchetype = GetOrCreateArchetype(types, newTypeCount, groupManager);

            systemStateResidueArchetype->SystemStateResidueArchetype = systemStateResidueArchetype;
            systemStateResidueArchetype->InstantiableArchetype       = GetEntityOnlyArchetype(types, groupManager);

            srcArchetype->SystemStateResidueArchetype = systemStateResidueArchetype;

            return(srcArchetype);
        }
Exemplo n.º 21
0
            private void SetComponentData(
                Chunk *afterChunk,
                Archetype *afterArchetype,
                ComponentTypeInArchetype afterTypeInArchetype,
                int afterIndexInTypeArray,
                int afterEntityIndexInChunk,
                Chunk *beforeChunk,
                Archetype *beforeArchetype,
                int beforeIndexInTypeArray,
                int beforeEntityIndexInChunk,
                EntityGuid entityGuid,
                int typeIndex,
                TypeInfo typeInfo)
            {
                if (afterTypeInArchetype.IsSharedComponent)
                {
                    var beforeOffset = beforeIndexInTypeArray - beforeChunk->Archetype->FirstSharedComponent;
                    var beforeSharedComponentIndex = beforeChunk->GetSharedComponentValue(beforeOffset);

                    var afterOffset = afterIndexInTypeArray - afterChunk->Archetype->FirstSharedComponent;
                    var afterSharedComponentIndex = afterChunk->GetSharedComponentValue(afterOffset);

                    // No managed objects in burst land. Do what we can and defer the actual unpacking until later.
                    ComponentDataStream.SetSharedComponentDataDeferred(entityGuid, afterTypeInArchetype.TypeIndex, afterSharedComponentIndex, beforeSharedComponentIndex);
                    return;
                }

                // IMPORTANT This means `IsZeroSizedInChunk` which is always true for shared components.
                // Always check shared components first.
                if (afterTypeInArchetype.IsZeroSized)
                {
                    return;
                }

                if (afterTypeInArchetype.IsBuffer)
                {
                    var beforeBuffer = (BufferHeader *)(ChunkUtility.GetBuffer(beforeChunk) + beforeArchetype->Offsets[beforeIndexInTypeArray] +
                                                        beforeEntityIndexInChunk * beforeArchetype->SizeOfs[beforeIndexInTypeArray]);
                    var beforeElementPtr = BufferHeader.GetElementPointer(beforeBuffer);
                    var beforeLength     = beforeBuffer->Length;

                    var afterBuffer = (BufferHeader *)(ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] +
                                                       afterEntityIndexInChunk * afterArchetype->SizeOfs[afterIndexInTypeArray]);
                    var afterElementPtr = BufferHeader.GetElementPointer(afterBuffer);
                    var afterLength     = afterBuffer->Length;

                    if (afterTypeInArchetype.TypeIndex == TypeInfoStream.LinkedEntityGroupTypeIndex)
                    {
                        var beforeLinkedEntityGroups = (LinkedEntityGroup *)beforeElementPtr;
                        var afterLinkedEntityGroups  = (LinkedEntityGroup *)afterElementPtr;

                        // Using is not supported by burst.
                        var beforeLinkedEntityGroupEntityGuids = new NativeArray <EntityGuid>(beforeLength, Allocator.Temp);
                        var afterLinkedEntityGroupEntityGuids  = new NativeArray <EntityGuid>(afterLength, Allocator.Temp);
                        {
                            for (var i = 0; i < beforeLength; i++)
                            {
                                if (!BeforeEntityToEntityGuid.TryGetValue(beforeLinkedEntityGroups[i].Value, out var beforeEntityGuid))
                                {
                                    throw new Exception("LinkedEntityGroup child is missing an EntityGuid component.");
                                }

                                beforeLinkedEntityGroupEntityGuids[i] = beforeEntityGuid;
                            }

                            for (var i = 0; i < afterLength; i++)
                            {
                                if (!AfterEntityToEntityGuid.TryGetValue(afterLinkedEntityGroups[i].Value, out var afterEntityGuid))
                                {
                                    throw new Exception("LinkedEntityGroup child is missing an EntityGuid component.");
                                }

                                afterLinkedEntityGroupEntityGuids[i] = afterEntityGuid;
                            }

                            beforeLinkedEntityGroupEntityGuids.Sort();
                            afterLinkedEntityGroupEntityGuids.Sort();

                            var beforeIndex = 0;
                            var afterIndex  = 0;

                            while (beforeIndex < beforeLength && afterIndex < afterLength)
                            {
                                var beforeEntityGuid = beforeLinkedEntityGroupEntityGuids[beforeIndex];
                                var afterEntityGuid  = afterLinkedEntityGroupEntityGuids[afterIndex];

                                var comparison = beforeEntityGuid.CompareTo(afterEntityGuid);

                                if (comparison == 0)
                                {
                                    // If the entity is in both "before" and "after", then there is no change.
                                    beforeIndex++;
                                    afterIndex++;
                                }
                                else if (comparison > 0)
                                {
                                    // If the entity is in "before" but not "after", it's been removed.
                                    LinkedEntityGroupRemovals.Add(new LinkedEntityGroupChange {
                                        RootEntityGuid = entityGuid, ChildEntityGuid = beforeEntityGuid
                                    });
                                    beforeIndex++;
                                }
                                else if (comparison < 0)
                                {
                                    // If the entity is in "after" but not "before", it's been added.
                                    LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange {
                                        RootEntityGuid = entityGuid, ChildEntityGuid = afterEntityGuid
                                    });
                                    afterIndex++;
                                }
                            }

                            while (beforeIndex < beforeLength)
                            {
                                // If the entity is in "before" but not "after", it's been removed.
                                LinkedEntityGroupRemovals.Add(new LinkedEntityGroupChange
                                {
                                    RootEntityGuid = entityGuid, ChildEntityGuid = beforeLinkedEntityGroupEntityGuids[beforeIndex++]
                                });
                            }

                            while (afterIndex < afterLength)
                            {
                                // If the entity is in "after" but not "before", it's been added.
                                LinkedEntityGroupAdditions.Add(new LinkedEntityGroupChange
                                {
                                    RootEntityGuid = entityGuid, ChildEntityGuid = afterLinkedEntityGroupEntityGuids[afterIndex++]
                                });
                            }
                        }
                    }
                    else
                    {
                        if (afterLength != beforeLength ||
                            UnsafeUtility.MemCmp(beforeElementPtr, afterElementPtr, afterLength * typeInfo.ElementSize) != 0)
                        {
                            var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash);
                            ComponentDataStream.SetComponentData(packedComponent, afterElementPtr, typeInfo.ElementSize * afterLength);
                            ExtractEntityReferencePatches(typeInfo, packedComponent, afterElementPtr, afterLength);
                        }
                    }
                }
                else
                {
                    if (beforeArchetype->SizeOfs[beforeIndexInTypeArray] != afterArchetype->SizeOfs[afterIndexInTypeArray])
                    {
                        throw new Exception("Archetype->SizeOfs do not match");
                    }

                    var beforeAddress = ChunkUtility.GetBuffer(beforeChunk) + beforeArchetype->Offsets[beforeIndexInTypeArray] +
                                        beforeArchetype->SizeOfs[beforeIndexInTypeArray] * beforeEntityIndexInChunk;
                    var afterAddress = ChunkUtility.GetBuffer(afterChunk) + afterArchetype->Offsets[afterIndexInTypeArray] + afterArchetype->SizeOfs[afterIndexInTypeArray] * afterEntityIndexInChunk;

                    if (UnsafeUtility.MemCmp(beforeAddress, afterAddress, beforeArchetype->SizeOfs[beforeIndexInTypeArray]) != 0)
                    {
                        var packedComponent = PackComponent(entityGuid, typeIndex, typeInfo.StableTypeHash);
                        ComponentDataStream.SetComponentData(packedComponent, afterAddress, beforeArchetype->SizeOfs[beforeIndexInTypeArray]);
                        ExtractEntityReferencePatches(typeInfo, packedComponent, afterAddress, 1);
                    }
                }
            }
Exemplo n.º 22
0
        public void TryRemoveEntityId(Entity *entities, int count, ArchetypeManager archetypeManager,
                                      SharedComponentDataManager sharedComponentDataManager,
                                      EntityGroupManager groupManager, ComponentTypeInArchetype *componentTypeInArchetypeArray)
        {
            var entityIndex = 0;

            while (entityIndex != count)
            {
                int indexInChunk;
                int batchCount;
                fixed(EntityDataManager *manager = &this)
                {
                    var chunk = EntityChunkBatch(manager, entities + entityIndex, count - entityIndex, out indexInChunk,
                                                 out batchCount);
                    var archetype = GetArchetype(entities[entityIndex]);

                    if (!archetype->SystemStateCleanupNeeded)
                    {
                        DeallocateDataEntitiesInChunk(manager, entities + entityIndex, chunk, indexInChunk, batchCount);
                        IncrementComponentOrderVersion(chunk->Archetype, chunk, sharedComponentDataManager);

                        if (chunk->ManagedArrayIndex >= 0)
                        {
                            // We can just chop-off the end, no need to copy anything
                            if (chunk->Count != indexInChunk + batchCount)
                            {
                                ChunkDataUtility.CopyManagedObjects(archetypeManager, chunk, chunk->Count - batchCount,
                                                                    chunk,
                                                                    indexInChunk, batchCount);
                            }

                            ChunkDataUtility.ClearManagedObjects(archetypeManager, chunk, chunk->Count - batchCount,
                                                                 batchCount);
                        }

                        chunk->Archetype->EntityCount -= batchCount;
                        archetypeManager.SetChunkCount(chunk, chunk->Count - batchCount);
                    }
                    else
                    {
                        for (var batchEntityIndex = 0; batchEntityIndex < batchCount; batchEntityIndex++)
                        {
                            var entity                   = entities[entityIndex + batchEntityIndex];
                            var removedTypes             = 0;
                            var removedComponentIsShared = false;
                            for (var t = 1; t < archetype->TypesCount; ++t)
                            {
                                var type = archetype->Types[t];

                                if (!(type.IsSystemStateComponent || type.IsSystemStateSharedComponent))
                                {
                                    ++removedTypes;
                                    removedComponentIsShared |= type.IsSharedComponent;
                                }
                                else
                                {
                                    componentTypeInArchetypeArray[t - removedTypes] = archetype->Types[t];
                                }
                            }

                            componentTypeInArchetypeArray[archetype->TypesCount - removedTypes] =
                                new ComponentTypeInArchetype(ComponentType.Create <CleanupEntity>());

                            var newType = archetypeManager.GetOrCreateArchetype(componentTypeInArchetypeArray,
                                                                                archetype->TypesCount - removedTypes + 1, groupManager);

                            int *sharedComponentDataIndices = null;
                            if (newType->NumSharedComponents > 0)
                            {
                                var oldSharedComponentDataIndices =
                                    GetComponentChunk(entity)->SharedComponentValueArray;
                                if (removedComponentIsShared)
                                {
                                    int *tempAlloc = stackalloc int[newType->NumSharedComponents];
                                    sharedComponentDataIndices = tempAlloc;

                                    var srcIndex = 0;
                                    var dstIndex = 0;
                                    for (var t = 0; t < archetype->TypesCount; ++t)
                                    {
                                        if (archetype->SharedComponentOffset[t] != -1)
                                        {
                                            var typeIndex             = archetype->Types[t].TypeIndex;
                                            var systemStateType       = typeof(ISystemStateComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex));
                                            var systemStateSharedType = typeof(ISystemStateSharedComponentData).IsAssignableFrom(TypeManager.GetType(typeIndex));
                                            if (!(systemStateType || systemStateSharedType))
                                            {
                                                srcIndex++;
                                            }
                                            else
                                            {
                                                sharedComponentDataIndices[dstIndex] =
                                                    oldSharedComponentDataIndices[srcIndex];
                                                srcIndex++;
                                                dstIndex++;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // reuse old sharedComponentDataIndices
                                    sharedComponentDataIndices = oldSharedComponentDataIndices;
                                }
                            }

                            IncrementComponentOrderVersion(archetype, GetComponentChunk(entity),
                                                           sharedComponentDataManager);
                            SetArchetype(archetypeManager, entity, newType, sharedComponentDataIndices);
                        }
                    }
                }

                entityIndex += batchCount;
            }
        }