public unsafe void Execute()
            {
                int index = 0;

                while (this.matchingArchetype != null)
                {
                    Archetype *archetype = this.matchingArchetype.Archetype;
                    Chunk *    begin     = (Chunk *)archetype->ChunkList.Begin;
                    while (true)
                    {
                        if (begin == archetype->ChunkList.End)
                        {
                            this.matchingArchetype = this.matchingArchetype.Next;
                            break;
                        }
                        index++;
                        ArchetypeChunk chunk = new ArchetypeChunk {
                            m_Chunk = begin
                        };
                        this.chunks.set_Item(index, chunk);
                        begin = (Chunk *)begin->ChunkListNode.Next;
                    }
                }
            }
Example #2
0
        public void AddExistingChunk(Chunk *chunk)
        {
            var archetype = chunk->Archetype;

            archetype->ChunkList.Add(&chunk->ChunkListNode);
            archetype->ChunkCount  += 1;
            archetype->EntityCount += chunk->Count;
            for (var i = 0; i < archetype->NumSharedComponents; ++i)
            {
                m_SharedComponentManager.AddReference(chunk->SharedComponentValueArray[i]);
            }

            if (chunk->Count < chunk->Capacity)
            {
                if (archetype->NumSharedComponents == 0)
                {
                    archetype->ChunkListWithEmptySlots.Add(&chunk->ChunkListWithEmptySlotsNode);
                }
                else
                {
                    archetype->FreeChunksBySharedComponents.Add(chunk);
                }
            }
        }
Example #3
0
        void ReleaseChunk(Chunk *chunk)
        {
            // Remove references to shared components
            if (chunk->Archetype->NumSharedComponents > 0)
            {
                var sharedComponentValueArray = chunk->SharedComponentValues;

                for (var i = 0; i < chunk->Archetype->NumSharedComponents; ++i)
                {
                    ManagedChangesTracker.RemoveReference(sharedComponentValueArray[i]);
                }
            }

            // this chunk is going away, so it shouldn't be in the empty slot list.
            if (chunk->Count < chunk->Capacity)
            {
                chunk->Archetype->EmptySlotTrackingRemoveChunk(chunk);
            }

            chunk->Archetype->RemoveFromChunkList(chunk);
            chunk->Archetype = null;

            FreeChunk(chunk);
        }
        private unsafe void MoveToNextMatchingChunk()
        {
            MatchingArchetypes *currentMatchingArchetype = this.m_CurrentMatchingArchetype;
            Chunk *currentChunk = this.m_CurrentChunk;
            Chunk *end          = (Chunk *)currentMatchingArchetype->Archetype.ChunkList.End;

            while (true)
            {
                currentChunk = (Chunk *)currentChunk->ChunkListNode.Next;
                while (true)
                {
                    if (currentChunk == end)
                    {
                        this.m_CurrentArchetypeEntityIndex += this.m_CurrentChunkEntityIndex;
                        this.m_CurrentChunkEntityIndex      = 0;
                        currentMatchingArchetype            = currentMatchingArchetype->Next;
                        if (currentMatchingArchetype != null)
                        {
                            currentChunk = (Chunk *)currentMatchingArchetype->Archetype.ChunkList.Begin;
                            end          = (Chunk *)currentMatchingArchetype->Archetype.ChunkList.End;
                            continue;
                        }
                        this.m_CurrentMatchingArchetype = null;
                        this.m_CurrentChunk             = null;
                        break;
                    }
                    else if (currentChunk.MatchesFilter(currentMatchingArchetype, ref this.m_Filter) && (currentChunk->Capacity > 0))
                    {
                        this.m_CurrentMatchingArchetype = currentMatchingArchetype;
                        this.m_CurrentChunk             = currentChunk;
                        break;
                    }
                    break;
                }
            }
        }
        public static unsafe void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex)
        {
            Archetype *archetype     = srcChunk.Archetype;
            Archetype *archetypePtr2 = dstChunk.Archetype;
            int        index         = 0;
            int        num2          = 0;

            while (true)
            {
                if ((index >= archetype->TypesCount) || (num2 >= archetypePtr2->TypesCount))
                {
                    while (true)
                    {
                        if (index >= archetype->TypesCount)
                        {
                            while (num2 < archetypePtr2->TypesCount)
                            {
                                byte *numPtr4 = (&dstChunk.Buffer.FixedElementField + archetypePtr2->Offsets[num2]) + (dstIndex * archetypePtr2->SizeOfs[num2]);
                                if ((archetypePtr2->Types + num2).IsBuffer)
                                {
                                    BufferHeader.Initialize((BufferHeader *)numPtr4, archetypePtr2->Types[num2].BufferCapacity);
                                }
                                else
                                {
                                    UnsafeUtility.MemClear((void *)numPtr4, (long)archetypePtr2->SizeOfs[num2]);
                                }
                                num2++;
                            }
                            return;
                        }
                        byte *numPtr3 = (&srcChunk.Buffer.FixedElementField + archetype->Offsets[index]) + (srcIndex * archetype->SizeOfs[index]);
                        if ((archetype->Types + index).IsBuffer)
                        {
                            BufferHeader.Destroy((BufferHeader *)numPtr3);
                        }
                        index++;
                    }
                }
                byte *numPtr  = (&srcChunk.Buffer.FixedElementField + archetype->Offsets[index]) + (srcIndex * archetype->SizeOfs[index]);
                byte *numPtr2 = (&dstChunk.Buffer.FixedElementField + archetypePtr2->Offsets[num2]) + (dstIndex * archetypePtr2->SizeOfs[num2]);
                if (archetype->Types[index] < archetypePtr2->Types[num2])
                {
                    if ((archetype->Types + index).IsBuffer)
                    {
                        BufferHeader.Destroy((BufferHeader *)numPtr);
                    }
                    index++;
                    continue;
                }
                if (archetype->Types[index] <= archetypePtr2->Types[num2])
                {
                    UnsafeUtility.MemCpy((void *)numPtr2, (void *)numPtr, (long)archetype->SizeOfs[index]);
                    if ((archetype->Types + index).IsBuffer)
                    {
                        BufferHeader.Initialize((BufferHeader *)numPtr, archetype->Types[index].BufferCapacity);
                    }
                    index++;
                    num2++;
                    continue;
                }
                if ((archetypePtr2->Types + num2).IsBuffer)
                {
                    BufferHeader.Initialize((BufferHeader *)numPtr2, archetypePtr2->Types[num2].BufferCapacity);
                }
                else
                {
                    UnsafeUtility.MemClear((void *)numPtr2, (long)archetypePtr2->SizeOfs[num2]);
                }
                num2++;
            }
        }
        public static unsafe void CopyManagedObjects(ArchetypeManager typeMan, Chunk *srcChunk, int srcStartIndex, Chunk *dstChunk, int dstStartIndex, int count)
        {
            Archetype *archetype     = srcChunk.Archetype;
            Archetype *archetypePtr2 = dstChunk.Archetype;
            int        index         = 0;
            int        num2          = 0;

            while ((index < archetype->TypesCount) && (num2 < archetypePtr2->TypesCount))
            {
                if (archetype->Types[index] < archetypePtr2->Types[num2])
                {
                    index++;
                    continue;
                }
                if (archetype->Types[index] > archetypePtr2->Types[num2])
                {
                    num2++;
                    continue;
                }
                if (archetype->ManagedArrayOffset[index] >= 0)
                {
                    int num3 = 0;
                    while (true)
                    {
                        if (num3 >= count)
                        {
                            break;
                        }
                        object val = typeMan.GetManagedObject(srcChunk, index, srcStartIndex + num3);
                        typeMan.SetManagedObject(dstChunk, num2, dstStartIndex + num3, val);
                        num3++;
                    }
                }
                index++;
                num2++;
            }
        }
Example #7
0
        public static unsafe void SerializeWorld(EntityManager entityManager, BinaryWriter writer, out int[] sharedComponentsToSerialize, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapInfos)
        {
            Dictionary <EntityArchetype, int> dictionary;

            EntityArchetype[] archetypeArray;
            writer.Write(CurrentFileFormatVersion);
            GetAllArchetypes(entityManager.ArchetypeManager, out dictionary, out archetypeArray);
            HashSet <int> source = new HashSet <int>();

            EntityArchetype[] archetypeArray2 = archetypeArray;
            int index = 0;

            while (index < archetypeArray2.Length)
            {
                EntityArchetype archetype = archetypeArray2[index];
                int             num4      = 0;
                while (true)
                {
                    if (num4 >= archetype.Archetype.TypesCount)
                    {
                        index++;
                        break;
                    }
                    source.Add(archetype.Archetype.Types[num4].TypeIndex);
                    num4++;
                }
            }
            var typeArray = (from t in source.Select(delegate(int index) {
                Type type = TypeManager.GetType(index);
                string assemblyQualifiedName = TypeManager.GetType(index).AssemblyQualifiedName;
                return(new {
                    index = index,
                    type = type,
                    name = assemblyQualifiedName,
                    hash = TypeManager.GetTypeInfo(index).FastEqualityTypeInfo.Hash,
                    asciiName = Encoding.ASCII.GetBytes(assemblyQualifiedName)
                });
            })
                             orderby t.name
                             select t).ToArray();
            int num = typeArray.Sum(t => t.asciiName.Length + 1);

            writer.Write(typeArray.Length);
            foreach (var type in typeArray)
            {
                writer.Write(type.hash);
            }
            writer.Write(num);
            foreach (var type2 in typeArray)
            {
                writer.Write(type2.asciiName);
                writer.Write((byte)0);
            }
            Dictionary <int, int> typeIndexMap = new Dictionary <int, int>();
            int num7 = 0;

            while (true)
            {
                if (num7 >= typeArray.Length)
                {
                    WriteArchetypes(writer, archetypeArray, typeIndexMap);
                    NativeList <BufferPatchRecord> data = new NativeList <BufferPatchRecord>(0x80, Allocator.Temp);
                    int num2 = GenerateRemapInfo(entityManager, archetypeArray, entityRemapInfos);
                    writer.Write(num2);
                    Chunk *chunk = (Chunk *)UnsafeUtility.Malloc(0x3f00L, 0x10, Allocator.Temp);
                    Dictionary <int, int> dictionary3 = new Dictionary <int, int>();
                    int num8 = 0;
                    while (true)
                    {
                        if (num8 >= archetypeArray.Length)
                        {
                            data.Dispose();
                            UnsafeUtility.Free((void *)chunk, Allocator.Temp);
                            sharedComponentsToSerialize = new int[dictionary3.Count];
                            foreach (KeyValuePair <int, int> pair in dictionary3)
                            {
                                sharedComponentsToSerialize[pair.Value - 1] = pair.Key;
                            }
                            return;
                        }
                        Archetype *archetype = archetypeArray[num8].Archetype;
                        Chunk *    begin     = (Chunk *)archetype->ChunkList.Begin;
                        while (true)
                        {
                            if (begin == archetype->ChunkList.End)
                            {
                                num8++;
                                break;
                            }
                            data.Clear();
                            UnsafeUtility.MemCpy((void *)chunk, (void *)begin, 0x3f00L);
                            chunk->SharedComponentValueArray = (int *)(chunk + Chunk.GetSharedComponentOffset(archetype->NumSharedComponents));
                            byte *numPtr = &chunk->Buffer.FixedElementField;
                            EntityRemapUtility.PatchEntities(archetype->ScalarEntityPatches, archetype->ScalarEntityPatchCount, archetype->BufferEntityPatches, archetype->BufferEntityPatchCount, numPtr, chunk->Count, ref entityRemapInfos);
                            int num9 = 0;
                            while (true)
                            {
                                if (num9 >= archetype->TypesCount)
                                {
                                    ClearUnusedChunkData(chunk);
                                    chunk->ChunkListNode.Next = null;
                                    chunk->ChunkListNode.Prev = null;
                                    chunk->ChunkListWithEmptySlotsNode.Next = null;
                                    chunk->ChunkListWithEmptySlotsNode.Prev = null;
                                    chunk->Archetype = (Archetype *)num8;
                                    if (archetype->NumManagedArrays != 0)
                                    {
                                        throw new ArgumentException("Serialization of GameObject components is not supported for pure entity scenes");
                                    }
                                    int num15 = 0;
                                    while (true)
                                    {
                                        if (num15 == archetype->NumSharedComponents)
                                        {
                                            writer.WriteBytes((void *)chunk, 0x3f00);
                                            writer.Write(data.Length);
                                            if (data.Length > 0)
                                            {
                                                writer.WriteList <BufferPatchRecord>(data);
                                                int num18 = 0;
                                                while (true)
                                                {
                                                    if (num18 >= data.Length)
                                                    {
                                                        break;
                                                    }
                                                    BufferPatchRecord record2    = data[num18];
                                                    BufferHeader *    headerPtr2 = (BufferHeader *)ref OffsetFromPointer((void *)&begin->Buffer.FixedElementField, record2.ChunkOffset);
                                                    writer.WriteBytes((void *)headerPtr2->Pointer, record2.AllocSizeBytes);
                                                    num18++;
                                                }
                                            }
                                            begin = (Chunk *)begin->ChunkListNode.Next;
                                            break;
                                        }
                                        int key = chunk->SharedComponentValueArray[num15];
                                        if (chunk->SharedComponentValueArray[num15] != 0)
                                        {
                                            int num17;
                                            if (dictionary3.TryGetValue(key, out num17))
                                            {
                                                chunk->SharedComponentValueArray[num15] = num17;
                                            }
                                            else
                                            {
                                                num17 = dictionary3.Count + 1;
                                                dictionary3.set_Item(key, num17);
                                                chunk->SharedComponentValueArray[num15] = num17;
                                            }
                                        }
                                        num15++;
                                    }
                                    break;
                                }
                                int num10 = archetype->TypeMemoryOrder[num9];
                                if ((archetype->Types + num10).IsBuffer)
                                {
                                    BufferHeader *       headerPtr = (BufferHeader *)OffsetFromPointer((void *)numPtr, archetype->Offsets[num10]);
                                    int                  offset    = archetype->SizeOfs[num10];
                                    int                  count     = begin->Count;
                                    TypeManager.TypeInfo typeInfo  = TypeManager.GetTypeInfo(archetype->Types[num10].TypeIndex);
                                    int                  num14     = 0;
                                    while (true)
                                    {
                                        if (num14 >= count)
                                        {
                                            break;
                                        }
                                        if (headerPtr->Pointer != null)
                                        {
                                            headerPtr->Pointer = null;
                                            BufferPatchRecord element = new BufferPatchRecord {
                                                ChunkOffset    = (int)((long)((headerPtr - numPtr) / 1)),
                                                AllocSizeBytes = typeInfo.ElementSize * headerPtr->Capacity
                                            };
                                            data.Add(element);
                                        }
                                        headerPtr = (BufferHeader *)OffsetFromPointer((void *)headerPtr, offset);
                                        num14++;
                                    }
                                }
                                num9++;
                            }
                        }
                    }
                }
                typeIndexMap.set_Item(typeArray[num7].index, num7);
                num7++;
            }
        }
        public void UpdateCache(int index, out ComponentChunkCache cache)
        {
            Assert.IsTrue(-1 != IndexInComponentGroup);

            if (m_FilteredSharedComponents == null)
            {
                if (index < m_CurrentArchetypeIndex)
                {
                    m_CurrentMatchingArchetype = m_FirstMatchingArchetype;
                    m_CurrentArchetypeIndex    = 0;
                    m_CurrentChunk             = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex        = 0;
                }

                while (index >= m_CurrentArchetypeIndex + m_CurrentMatchingArchetype->Archetype->EntityCount)
                {
                    m_CurrentArchetypeIndex   += m_CurrentMatchingArchetype->Archetype->EntityCount;
                    m_CurrentMatchingArchetype = m_CurrentMatchingArchetype->Next;
                    m_CurrentChunk             = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex        = 0;
                }

                index -= m_CurrentArchetypeIndex;
                if (index < m_CurrentChunkIndex)
                {
                    m_CurrentChunk      = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex = 0;
                }

                while (index >= m_CurrentChunkIndex + m_CurrentChunk->Count)
                {
                    m_CurrentChunkIndex += m_CurrentChunk->Count;
                    m_CurrentChunk       = (Chunk *)m_CurrentChunk->ChunkListNode.Next;
                }
            }
            else
            {
                if (index < m_CurrentArchetypeIndex + m_CurrentChunkIndex)
                {
                    if (index < m_CurrentArchetypeIndex)
                    {
                        m_CurrentMatchingArchetype = m_FirstMatchingArchetype;
                        m_CurrentArchetypeIndex    = 0;
                    }

                    m_CurrentChunk      = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex = 0;
                    if (!(m_CurrentChunk->MatchesFilter(m_CurrentMatchingArchetype, m_FilteredSharedComponents) &&
                          (m_CurrentChunk->Count > 0)))
                    {
                        MoveToNextMatchingChunk();
                    }
                }

                while (index >= m_CurrentArchetypeIndex + m_CurrentChunkIndex + m_CurrentChunk->Count)
                {
                    m_CurrentChunkIndex += m_CurrentChunk->Count;
                    MoveToNextMatchingChunk();
                }
            }

            var archetype            = m_CurrentMatchingArchetype->Archetype;
            var typeIndexInArchetype = m_CurrentMatchingArchetype->TypeIndexInArchetypeArray[IndexInComponentGroup];

            cache.CachedBeginIndex = m_CurrentChunkIndex + m_CurrentArchetypeIndex;
            cache.CachedEndIndex   = cache.CachedBeginIndex + m_CurrentChunk->Count;
            cache.CachedSizeOf     = archetype->SizeOfs[typeIndexInArchetype];
            cache.CachedPtr        = m_CurrentChunk->Buffer + archetype->Offsets[typeIndexInArchetype] - cache.CachedBeginIndex * cache.CachedSizeOf;
        }
        static unsafe void WriteChunkData(YamlWriter writer, EntityManager entityManager, Chunk *initialChunk, Archetype *archetype, bool dumpChunkRawData)
        {
            using (writer.WriteCollection(k_ChunkDataCollectionTag))
            {
                using (writer.WriteCollection("Header"))
                {
                    WriteEntity(writer, nameof(Chunk.metaChunkEntity), initialChunk->metaChunkEntity);
                    writer.WriteKeyValue(nameof(Chunk.Capacity), initialChunk->Capacity)
                    .WriteKeyValue(nameof(Chunk.Count), initialChunk->Count);

                    if (dumpChunkRawData)
                    {
                        writer.WriteFormattedBinaryData("RawData", initialChunk, Chunk.kBufferOffset);
                    }
                }

                // First pass to sort by component type
                var entitiesByChunkIndex   = new Dictionary <int, Entity>();
                var componentDataList      = new List <int>();
                var chunkComponentDataList = new List <int>();
                var chunkTypes             = archetype->Types;
                for (int typeI = 0; typeI < archetype->TypesCount; typeI++)
                {
                    var componentType = &chunkTypes[typeI];
                    var type          = TypeManager.GetType(componentType->TypeIndex);
                    var typeInfo      = TypeManager.GetTypeInfo(componentType->TypeIndex);

                    if (componentType->IsChunkComponent)
                    {
                        chunkComponentDataList.Add(typeI);
                    }

                    // Is it a Component Data ?
                    else if (typeof(IComponentData).IsAssignableFrom(type) || typeof(Entity).IsAssignableFrom(type) || typeof(IBufferElementData).IsAssignableFrom(type))
                    {
                        // Ignore Tag Component, no data to dump
                        if (typeInfo.IsZeroSized)
                        {
                            continue;
                        }

                        if (typeof(Entity).IsAssignableFrom(type))
                        {
                            componentDataList.Insert(0, typeI);

                            for (int i = 0; i < initialChunk->Count;)
                            {
                                var entity = (Entity)Marshal.PtrToStructure((IntPtr)initialChunk->Buffer + archetype->SizeOfs[0] * i, type);
                                if (entityManager.Exists(entity))
                                {
                                    entitiesByChunkIndex.Add(i, entity);
                                    i++;
                                }
                            }
                        }
                        else
                        {
                            componentDataList.Add(typeI);
                        }
                    }
                }

                // Parse the Component Data for this chunk and store them
                using (writer.WriteCollection(k_ComponentDataCollectionTag))
                {
                    foreach (var typeI in componentDataList)
                    {
                        var componentTypeInArchetype = &chunkTypes[typeI];
                        var componentType            = TypeManager.GetType(componentTypeInArchetype->TypeIndex);
                        var componentTypeInfo        = TypeManager.GetTypeInfo(componentTypeInArchetype->TypeIndex);
                        var componentExtractedInfo   = TypeDataExtractor.GetTypeExtractedInfo(componentType);

                        using (writer.WriteCollection(k_ComponentDataTag))
                        {
                            writer.WriteInlineMap("info", new[]
                            {
                                new KeyValuePair <object, object>(nameof(Type), componentType.Name),
                                new KeyValuePair <object, object>(nameof(TypeManager.TypeInfo.SizeInChunk), componentTypeInfo.SizeInChunk)
                            });

                            using (writer.WriteCollection("Entities"))
                            {
                                var indexInTypeArray       = ChunkDataUtility.GetIndexInTypeArray(archetype, componentTypeInArchetype->TypeIndex);
                                var componentOffsetInChunk = archetype->Offsets[indexInTypeArray];
                                var componentSize          = archetype->SizeOfs[indexInTypeArray];
                                var componentsBuffer       = initialChunk->Buffer + componentOffsetInChunk;
                                var entityData             = new Dictionary <string, string>();

                                // Dump all entities in this chunk
                                foreach (var kvp in entitiesByChunkIndex)
                                {
                                    var entity = kvp.Value;
                                    entityData.Clear();

                                    // Get the location of the component data
                                    var compData = componentsBuffer + kvp.Key * componentSize;

                                    // If the component we are dumping is a Dynamic Buffer
                                    if (typeof(IBufferElementData).IsAssignableFrom(componentType))
                                    {
                                        var header = (BufferHeader *)compData;
                                        var begin  = BufferHeader.GetElementPointer(header);
                                        var size   = Marshal.SizeOf(componentType);

                                        using (writer.WriteCollection(entity.ToString()))
                                        {
                                            for (var it = 0; it < header->Length; it++)
                                            {
                                                var item = begin + (size * it);
                                                entityData.Clear();

                                                // Dump each field of the current entity's component data
                                                foreach (var componentFieldInfo in componentExtractedInfo.Fields)
                                                {
                                                    var compDataObject = Marshal.PtrToStructure((IntPtr)item + componentFieldInfo.Offset, componentFieldInfo.Type);
                                                    entityData.Add(componentFieldInfo.Name, compDataObject.ToString());
                                                }
                                                writer.WriteInlineMap($"{it:0000}", entityData);
                                            }
                                        }
                                    }

                                    // If it's a Component Data
                                    else
                                    {
                                        // Dump each field of the current entity's component data
                                        foreach (var componentFieldInfo in componentExtractedInfo.Fields)
                                        {
                                            var compDataObject = Marshal.PtrToStructure((IntPtr)compData + componentFieldInfo.Offset, componentFieldInfo.Type);
                                            entityData.Add(componentFieldInfo.Name, compDataObject.ToString());
                                        }
                                        writer.WriteInlineMap(entity.ToString(), entityData);
                                    }
                                }
                                if (dumpChunkRawData)
                                {
                                    var csize = EntityComponentStore.GetComponentArraySize(componentSize, archetype->ChunkCapacity);
                                    writer.WriteFormattedBinaryData("RawData", componentsBuffer, csize, componentOffsetInChunk + Chunk.kBufferOffset);
                                }
                            }
                        }
                    }
                }
            }
        }
 public object[] GetManagedObjectRange(Chunk *chunk, int type, out int rangeStart, out int rangeLength)
 {
     rangeStart  = chunk->Archetype->ManagedArrayOffset[type] * chunk->Capacity;
     rangeLength = chunk->Count;
     return(m_ManagedArrays[chunk->ManagedArrayIndex].ManagedArray);
 }
Example #11
0
 public void AddToChunkListWithEmptySlots(Chunk *chunk)
 {
     chunk->ListWithEmptySlotsIndex = ChunksWithEmptySlots.Count;
     ChunksWithEmptySlotsUnsafePtrList.Add(chunk);
 }
        int InstantiateEntitiesOne(Entity srcEntity, Entity *outputEntities, int instanceCount, InstantiateRemapChunk *remapChunks, int remapChunksCount)
        {
            var src          = GetEntityInChunk(srcEntity);
            var srcArchetype = src.Chunk->Archetype;
            var dstArchetype = srcArchetype->InstantiableArchetype;

            var archetypeChunkFilter = new ArchetypeChunkFilter();

            archetypeChunkFilter.Archetype = dstArchetype;

            if (RequiresBuildingResidueSharedComponentIndices(srcArchetype, dstArchetype))
            {
                BuildResidueSharedComponentIndices(srcArchetype, dstArchetype, src.Chunk->SharedComponentValues, archetypeChunkFilter.SharedComponentValues);
            }
            else
            {
                // Always copy shared component indices since GetChunkWithEmptySlots might reallocate the storage of SharedComponentValues
                src.Chunk->SharedComponentValues.CopyTo(archetypeChunkFilter.SharedComponentValues, 0, dstArchetype->NumSharedComponents);
            }

            Chunk *chunk = null;

            int instanceBeginIndex = 0;

            while (instanceBeginIndex != instanceCount)
            {
                chunk = GetChunkWithEmptySlots(ref archetypeChunkFilter);

                int indexInChunk;
                var allocatedCount = AllocateIntoChunk(chunk, instanceCount - instanceBeginIndex, out indexInChunk);

                ChunkDataUtility.ReplicateComponents(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount);
                AllocateEntities(dstArchetype, chunk, indexInChunk, allocatedCount,
                                 outputEntities + instanceBeginIndex);

                if (srcArchetype->NumManagedArrays > 0)
                {
                    ManagedChangesTracker.ReplicateManagedObjects(src.Chunk, src.IndexInChunk, chunk, indexInChunk, allocatedCount, srcEntity, outputEntities + instanceBeginIndex);
                }

                chunk->SetAllChangeVersions(GlobalSystemVersion);

#if UNITY_EDITOR
                for (var i = 0; i < allocatedCount; ++i)
                {
                    CopyName(outputEntities[i + instanceBeginIndex], srcEntity);
                }
#endif

                if (remapChunks != null)
                {
                    remapChunks[remapChunksCount].Chunk              = chunk;
                    remapChunks[remapChunksCount].IndexInChunk       = indexInChunk;
                    remapChunks[remapChunksCount].AllocatedCount     = allocatedCount;
                    remapChunks[remapChunksCount].InstanceBeginIndex = instanceBeginIndex;
                    remapChunksCount++;
                }


                instanceBeginIndex += allocatedCount;
            }

            if (chunk != null)
            {
                ManagedChangesTracker.IncrementComponentOrderVersion(dstArchetype,
                                                                     chunk->SharedComponentValues);
                IncrementComponentTypeOrderVersion(dstArchetype);
            }

            return(remapChunksCount);
        }
 public void AddNoResize(Chunk *value)
 {
     Writer.AddNoResize(value);
 }
 public bool Contains(Chunk *value)
 {
     return(IndexOf(value) != -1);
 }
 public void Add(Chunk *value)
 {
     this.ListData().Add(value);
 }
        public Chunk *GetChunkWithEmptySlots(Archetype *archetype, int *sharedComponentDataIndices)
        {
            if (archetype->NumSharedComponents == 0)
            {
                if (!archetype->ChunkListWithEmptySlots.IsEmpty)
                {
                    var chunk = GetChunkFromEmptySlotNode(archetype->ChunkListWithEmptySlots.Begin);
                    Assert.AreNotEqual(chunk->Count, chunk->Capacity);
                    return(chunk);
                }
            }
            else
            {
                var chunk = archetype->FreeChunksBySharedComponents.GetChunkWithEmptySlots(sharedComponentDataIndices,
                                                                                           archetype->NumSharedComponents);
                if (chunk != null)
                {
                    return(chunk);
                }
            }

            // Try existing archetype chunks
            if (!archetype->ChunkListWithEmptySlots.IsEmpty)
            {
                if (lastChunkWithSharedComponentsAllocatedInto != null &&
                    lastChunkWithSharedComponentsAllocatedInto->Archetype == archetype &&
                    lastChunkWithSharedComponentsAllocatedInto->Count < lastChunkWithSharedComponentsAllocatedInto->Capacity)
                {
                    if (ChunkHasSharedComponents(lastChunkWithSharedComponentsAllocatedInto, sharedComponentDataIndices))
                    {
                        return(lastChunkWithSharedComponentsAllocatedInto);
                    }
                }

                if (archetype->NumSharedComponents == 0)
                {
                    var chunk = GetChunkFromEmptySlotNode(archetype->ChunkListWithEmptySlots.Begin);
                    Assert.AreNotEqual(chunk->Count, chunk->Capacity);
                    return(chunk);
                }
            }

            Chunk *newChunk;

            // Try empty chunk pool
            if (m_EmptyChunkPool->IsEmpty)
            {
                // Allocate new chunk
                newChunk = (Chunk *)UnsafeUtility.Malloc(Chunk.kChunkSize, 64, Allocator.Persistent);
            }
            else
            {
                newChunk = (Chunk *)m_EmptyChunkPool->Begin;
                newChunk->ChunkListNode.Remove();
            }

            ConstructChunk(archetype, newChunk, sharedComponentDataIndices);

            if (archetype->NumSharedComponents > 0)
            {
                lastChunkWithSharedComponentsAllocatedInto = newChunk;
            }
            return(newChunk);
        }
        internal object GetManagedObject(Chunk *chunk, int type, int index)
        {
            var managedStart = chunk->Archetype->ManagedArrayOffset[type] * chunk->Capacity;

            return(m_ManagedArrays[chunk->ManagedArrayIndex].ManagedArray[index + managedStart]);
        }
        public static void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex)
        {
            var srcArch = srcChunk->Archetype;
            var dstArch = dstChunk->Archetype;

            //Debug.Log($"Convert {EntityManager.EntityManagerDebug.GetArchetypeDebugString(srcArch)} to {EntityManager.EntityManagerDebug.GetArchetypeDebugString(dstArch)}");

            var srcI = 0;
            var dstI = 0;

            while (srcI < srcArch->TypesCount && dstI < dstArch->TypesCount)
            {
                var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcArch->SizeOfs[srcI];
                var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstArch->SizeOfs[dstI];

                if (srcArch->Types[srcI] < dstArch->Types[dstI])
                {
                    // Clear any buffers we're not going to keep.
                    if (srcArch->Types[srcI].IsBuffer)
                    {
                        BufferHeader.Destroy((BufferHeader *)src);
                    }

                    ++srcI;
                }
                else if (srcArch->Types[srcI] > dstArch->Types[dstI])
                {
                    // Clear components in the destination that aren't copied

                    if (dstArch->Types[dstI].IsBuffer)
                    {
                        BufferHeader.Initialize((BufferHeader *)dst, dstArch->Types[dstI].BufferCapacity);
                    }
                    else
                    {
                        UnsafeUtility.MemClear(dst, dstArch->SizeOfs[dstI]);
                    }

                    ++dstI;
                }
                else
                {
                    UnsafeUtility.MemCpy(dst, src, srcArch->SizeOfs[srcI]);

                    // Poison source buffer to make sure there is no aliasing.
                    if (srcArch->Types[srcI].IsBuffer)
                    {
                        BufferHeader.Initialize((BufferHeader *)src, srcArch->Types[srcI].BufferCapacity);
                    }

                    ++srcI;
                    ++dstI;
                }
            }

            // Handle remaining components in the source that aren't copied
            for (; srcI < srcArch->TypesCount; ++srcI)
            {
                var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcArch->SizeOfs[srcI];
                if (srcArch->Types[srcI].IsBuffer)
                {
                    BufferHeader.Destroy((BufferHeader *)src);
                }
            }

            // Clear remaining components in the destination that aren't copied
            for (; dstI < dstArch->TypesCount; ++dstI)
            {
                var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstArch->SizeOfs[dstI];
                if (dstArch->Types[dstI].IsBuffer)
                {
                    BufferHeader.Initialize((BufferHeader *)dst, dstArch->Types[dstI].BufferCapacity);
                }
                else
                {
                    UnsafeUtility.MemClear(dst, dstArch->SizeOfs[dstI]);
                }
            }
        }
        public void SetManagedObject(Chunk *chunk, int type, int index, object val)
        {
            var managedStart = chunk->Archetype->ManagedArrayOffset[type] * chunk->Capacity;

            m_ManagedArrays[chunk->ManagedArrayIndex].ManagedArray[index + managedStart] = val;
        }
Example #20
0
        public static Chunk *AllocateChunk()
        {
            Chunk *chunk = (Chunk *)MemoryUtility.Malloc(Chunk.ChunkSize);

            return(chunk);
        }
Example #21
0
        public void UpdateCacheResolvedIndex(int index, out ComponentChunkCache cache, bool isWriting)
        {
            Assert.IsTrue(-1 != IndexInComponentGroup);

            if (!m_Filter.RequiresMatchesFilter)
            {
                if (index < m_CurrentArchetypeIndex)
                {
                    m_CurrentMatchingArchetype = m_FirstMatchingArchetype;
                    m_CurrentArchetypeIndex    = 0;
                    m_CurrentChunk             = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    // m_CurrentChunk might point to an invalid chunk if the first matching archetype has no chunks
                    // the while loop below will move to the first archetype that has any entities
                    m_CurrentChunkIndex = 0;
                }

                while (index >= m_CurrentArchetypeIndex + m_CurrentMatchingArchetype->Archetype->EntityCount)
                {
                    m_CurrentArchetypeIndex   += m_CurrentMatchingArchetype->Archetype->EntityCount;
                    m_CurrentMatchingArchetype = m_CurrentMatchingArchetype->Next;
                    m_CurrentChunk             = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex        = 0;
                }

                index -= m_CurrentArchetypeIndex;
                if (index < m_CurrentChunkIndex)
                {
                    m_CurrentChunk      = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.Begin;
                    m_CurrentChunkIndex = 0;
                }

                while (index >= m_CurrentChunkIndex + m_CurrentChunk->Count)
                {
                    m_CurrentChunkIndex += m_CurrentChunk->Count;
                    m_CurrentChunk       = (Chunk *)m_CurrentChunk->ChunkListNode.Next;
                }
            }
            else
            {
                if (index < m_CurrentArchetypeIndex + m_CurrentChunkIndex)
                {
                    if (index < m_CurrentArchetypeIndex)
                    {
                        m_CurrentMatchingArchetype = m_FirstMatchingArchetype;
                        m_CurrentArchetypeIndex    = 0;
                    }

                    m_CurrentChunk = (Chunk *)m_CurrentMatchingArchetype->Archetype->ChunkList.End;
                    // m_CurrentChunk now points to an invalid chunk but since the chunk list is circular
                    // it effectively points to the chunk before the first
                    // MoveToNextMatchingChunk will move it to a valid chunk if any exists
                    m_CurrentChunkIndex = 0;
                    MoveToNextMatchingChunk();
                }

                while (index >= m_CurrentArchetypeIndex + m_CurrentChunkIndex + m_CurrentChunk->Count)
                {
                    m_CurrentChunkIndex += m_CurrentChunk->Count;
                    MoveToNextMatchingChunk();
                }
            }

            var archetype            = m_CurrentMatchingArchetype->Archetype;
            var typeIndexInArchetype = m_CurrentMatchingArchetype->TypeIndexInArchetypeArray[IndexInComponentGroup];

            cache.CachedBeginIndex = m_CurrentChunkIndex + m_CurrentArchetypeIndex;
            cache.CachedEndIndex   = cache.CachedBeginIndex + m_CurrentChunk->Count;
            cache.CachedSizeOf     = archetype->SizeOfs[typeIndexInArchetype];
            cache.CachedPtr        = m_CurrentChunk->Buffer + archetype->Offsets[typeIndexInArchetype] -
                                     cache.CachedBeginIndex * cache.CachedSizeOf;

            if (isWriting)
            {
                m_CurrentChunk->ChangeVersion[typeIndexInArchetype] = m_GlobalSystemVersion;
            }
        }
Example #22
0
 public static void ConstructChunk(Chunk *chunk, Archetype *archetype)
 {
     chunk->archetype = archetype;
     chunk->count     = 0;
     chunk->capacity  = archetype->chunkCapacity;
 }
Example #23
0
        public static void FreeDataEntitiesInChunk(EntityDataManager *entityDataManager, Chunk *chunk, int count)
        {
            var freeIndex   = entityDataManager->m_EntitiesFreeIndex;
            var entityDatas = entityDataManager->m_Entities;

            var chunkEntities = (Entity *)chunk->Buffer;

            for (var i = 0; i != count; i++)
            {
                var entityIndex = chunkEntities[i].Index;
                var data        = entityDatas + entityIndex;

                data->Chunk = null;
                data->Version++;
                data->IndexInChunk = freeIndex;
                freeIndex          = entityIndex;
            }

            entityDataManager->m_EntitiesFreeIndex = freeIndex;
        }
Example #24
0
        public static Span <Entity> GetEntities(Chunk *chunk)
        {
            Entity *buffer = (Entity *)chunk->buffer;

            return(new Span <Entity>(buffer, chunk->count));
        }
Example #25
0
        public static unsafe void DeserializeWorld(ExclusiveEntityTransaction manager, BinaryReader reader, int numSharedComponents)
        {
            int num2;

            if (manager.ArchetypeManager.CountEntities() != 0)
            {
                throw new ArgumentException("DeserializeWorld can only be used on completely empty EntityManager. Please create a new empty World and use EntityManager.MoveEntitiesFrom to move the loaded entities into the destination world instead.");
            }
            int num = reader.ReadInt();

            if (num != CurrentFileFormatVersion)
            {
                throw new ArgumentException($"Attempting to read a entity scene stored in an old file format version (stored version : {num}, current version : {CurrentFileFormatVersion})");
            }
            NativeArray <int>             types  = ReadTypeArray(reader);
            NativeArray <EntityArchetype> array2 = ReadArchetypes(reader, types, manager, out num2);

            manager.AllocateConsecutiveEntitiesForLoading(num2);
            int num3 = reader.ReadInt();
            int num4 = 0;

            while (true)
            {
                if (num4 >= num3)
                {
                    array2.Dispose();
                    return;
                }
                Chunk *chunk = (Chunk *)UnsafeUtility.Malloc(0x3f00L, 0x40, Allocator.Persistent);
                reader.ReadBytes((void *)chunk, 0x3f00);
                chunk->Archetype = array2[(int)chunk->Archetype].Archetype;
                chunk->SharedComponentValueArray = (int *)(chunk + Chunk.GetSharedComponentOffset(chunk->Archetype.NumSharedComponents));
                int num5  = chunk->Archetype.NumSharedComponents;
                int index = 0;
                while (true)
                {
                    if (index >= num5)
                    {
                        chunk->ChangeVersion = (uint *)(chunk + Chunk.GetChangedComponentOffset(chunk->Archetype.TypesCount, chunk->Archetype.NumSharedComponents));
                        int length = reader.ReadInt();
                        if (length > 0)
                        {
                            NativeArray <BufferPatchRecord> elements = new NativeArray <BufferPatchRecord>(length, Allocator.Temp, NativeArrayOptions.ClearMemory);
                            reader.ReadArray <BufferPatchRecord>(elements, elements.Length);
                            int num8 = 0;
                            while (true)
                            {
                                if (num8 >= length)
                                {
                                    elements.Dispose();
                                    break;
                                }
                                BufferHeader *headerPtr = (BufferHeader *)ref OffsetFromPointer((void *)&chunk->Buffer.FixedElementField, elements[num8].ChunkOffset);
                                headerPtr->Pointer = (byte *)UnsafeUtility.Malloc((long)elements[num8].AllocSizeBytes, 8, Allocator.Persistent);
                                reader.ReadBytes((void *)headerPtr->Pointer, elements[num8].AllocSizeBytes);
                                num8++;
                            }
                        }
                        manager.AddExistingChunk(chunk);
                        num4++;
                        break;
                    }
                    if (chunk->SharedComponentValueArray[index] > numSharedComponents)
                    {
                        throw new ArgumentException($"Archetype uses shared component at index {chunk->SharedComponentValueArray[index]} but only {numSharedComponents} are available, check if the shared scene has been properly loaded.");
                    }
                    index++;
                }
            }
        }
Example #26
0
 public static void AssignSequenceNumber(Chunk *chunk, ulong value)
 {
     chunk->sequenceNumber = value;
 }
        public static unsafe byte *GetComponentDataRO(Chunk *chunk, int index, int indexInTypeArray)
        {
            int num = chunk.Archetype.Offsets[indexInTypeArray];

            return(&chunk.Buffer.FixedElementField + (num + (chunk.Archetype.SizeOfs[indexInTypeArray] * index)));
        }
Example #28
0
        public static byte[] GenerateChunkImage(Chunk *chunk)
        {
            const int  TGA_HEADER_SIZE      = 18;
            const int  TGA_CHANNELS         = 3;
            const byte TGA_RGB_UNCOMPRESSED = 2;
            const byte TGA_CHANNEL_BITS     = 24;

            var size = (int)Math.Sqrt(Chunk.ChunkSize);
            var tga  = new byte[TGA_HEADER_SIZE + size * size * TGA_CHANNELS];

            tga[2]  = TGA_RGB_UNCOMPRESSED;
            tga[12] = (byte)(255 & size);
            tga[13] = (byte)(255 & (size >> 8));
            tga[14] = (byte)(255 & size);
            tga[15] = (byte)(255 & (size >> 8));
            tga[16] = TGA_CHANNEL_BITS;
            // tga[17] = 32; // TODO

            var pixels = tga.AsSpan().Slice(TGA_HEADER_SIZE);

            var archetype = chunk->archetype;
            var index     = 0;

            for (int i = 0; i < Chunk.HeaderSize; ++i)
            {
                pixels[index++] = 0;
                pixels[index++] = 0;
                pixels[index++] = 255;
            }

            for (int i = 0; i < chunk->count; ++i)
            {
                var contrast = 55 * (i % 2);

                for (int j = 0; j < sizeof(Entity); ++j)
                {
                    pixels[index++] = (byte)(255 - contrast);
                    pixels[index++] = 0;
                    pixels[index++] = 0;
                }
            }

            index = Chunk.HeaderSize * TGA_CHANNELS;

            for (int c = 0; c < archetype->componentCount; ++c)
            {
                var color  = (byte)(55 + (float)(200f / (float)archetype->componentCount) * c);
                var offset = index + (archetype->componentOffsets[c] * TGA_CHANNELS);

                for (int i = 0; i < chunk->count; ++i)
                {
                    var contrast = 20 * (i % 2);
                    var grey     = (byte)(color - contrast);

                    for (int j = 0; j < archetype->componentSizes[c]; ++j)
                    {
                        pixels[offset++] = grey;
                        pixels[offset++] = grey;
                        pixels[offset++] = grey;
                    }
                }
            }

            return(tga);
        }
Example #29
0
 public void AddToChunkListWithEmptySlots(Chunk *chunk)
 {
     chunk->ListWithEmptySlotsIndex = ChunksWithEmptySlots.Length;
     ChunksWithEmptySlots.Add(chunk);
 }
Example #30
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;
                        }
                    }
                }
            }
        }