예제 #1
0
 static void WriteEntity(YamlWriter writer, string name, Entity entity)
 {
     writer.WriteInlineMap(name, new[] { new KeyValuePair <object, object>("index", entity.Index), new KeyValuePair <object, object>("version", entity.Version) });
 }
예제 #2
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }