예제 #1
0
        public void CopyFrom(DynamicBufferUnsafe <T> v)
        {
            ResizeUninitialized(v.Length);

            UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(m_Buffer),
                                 BufferHeader.GetElementPointer(v.m_Buffer), Length * UnsafeUtility.SizeOf <T>());
        }
예제 #2
0
        public void RemoveRange(int index, int count)
        {
            CheckBounds(index + count - 1);

            int   elemSize = UnsafeUtility.SizeOf <T>();
            byte *basePtr  = BufferHeader.GetElementPointer(m_Buffer);

            UnsafeUtility.MemMove(basePtr + index * elemSize, basePtr + (index + count) * elemSize, (long)elemSize * (Length - count - index));

            m_Buffer->Length -= count;
        }
예제 #3
0
        public void AddRange(NativeArray <T> newElems)
        {
            int elemSize  = UnsafeUtility.SizeOf <T>();
            int oldLength = Length;

            ResizeUninitialized(oldLength + newElems.Length);

            byte *basePtr = BufferHeader.GetElementPointer(m_Buffer);

            UnsafeUtility.MemCpy(basePtr + (long)oldLength * elemSize, newElems.GetUnsafeReadOnlyPtr <T>(), (long)elemSize * newElems.Length);
        }
예제 #4
0
        public void Insert(int index, T elem)
        {
            int length = Length;

            ResizeUninitialized(length + 1);
            CheckBounds(index); //CheckBounds after ResizeUninitialized since index == length is allowed
            int   elemSize = UnsafeUtility.SizeOf <T>();
            byte *basePtr  = BufferHeader.GetElementPointer(m_Buffer);

            UnsafeUtility.MemMove(basePtr + (index + 1) * elemSize, basePtr + index * elemSize, (long)elemSize * (length - index));
            this[index] = elem;
        }
예제 #5
0
 public T this[int index]
 {
     get
     {
         CheckBounds(index);
         return(UnsafeUtility.ReadArrayElement <T>(BufferHeader.GetElementPointer(m_Buffer), index));
     }
     set
     {
         CheckBounds(index);
         UnsafeUtility.WriteArrayElement <T>(BufferHeader.GetElementPointer(m_Buffer), index, value);
     }
 }
예제 #6
0
            protected override VisitStatus BeginContainer <TProperty, TContainer, TValue>(TProperty property, ref TContainer container,
                                                                                          ref TValue value, ref ChangeTracker changeTracker)
            {
                if (typeof(IComponentData).IsAssignableFrom(typeof(TValue)))
                {
                    var index = TypeManager.GetTypeIndex(typeof(TValue));
                    if (!TypeManager.GetTypeInfo(index).IsZeroSized)
                    {
                        Unsafe.Copy(m_EntityManager.GetComponentDataRawRW(m_TargetEntity, index), ref value);
                    }
                }

                if (typeof(ISharedComponentData).IsAssignableFrom(typeof(TValue)))
                {
                    var index = TypeManager.GetTypeIndex(typeof(TValue));
                    m_EntityManager.SetSharedComponentDataBoxed(m_TargetEntity, index, value);
                }

                if (typeof(IDynamicBufferContainer).IsAssignableFrom(typeof(TValue)) &&
                    value is IDynamicBufferContainer buffer)
                {
                    var index         = TypeManager.GetTypeIndex(buffer.ElementType);
                    var componentType = TypeManager.GetTypeInfo(index);

                    var srcBuffer =
                        (BufferHeader *)m_EntityManager.GetComponentDataRawRW(m_SourceEntity, componentType.TypeIndex);
                    var dstBuffer =
                        (BufferHeader *)m_EntityManager.GetComponentDataRawRW(m_TargetEntity, componentType.TypeIndex);

                    dstBuffer->Length = srcBuffer->Length;
                    BufferHeader.EnsureCapacity(dstBuffer, srcBuffer->Length, componentType.ElementSize, 4,
                                                BufferHeader.TrashMode.RetainOldData);

                    // Copy all blittable data
                    UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(dstBuffer),
                                         BufferHeader.GetElementPointer(srcBuffer), componentType.ElementSize * srcBuffer->Length);
                }

                return(VisitStatus.Override);
            }
예제 #7
0
        protected override void OnUpdate()
        {
            var entityComponentStore            = EntityManager.GetCheckedEntityDataAccess()->EntityComponentStore;
            var globalVersion                   = entityComponentStore->GlobalSystemVersion;
            var animatedAssetReferenceTypeIndex = m_AnimatedAssetReferenceTypeIndex;

            Dependency =
                Entities
                .WithNativeDisableUnsafePtrRestriction(entityComponentStore)
                .WithBurst(FloatMode.Fast)
                .WithAll <ApplyAnimationResultTag>()
                .WithNone <AnimationPPtrBindingRetarget>()
                .ForEach(
                    (in DynamicBuffer <AnimationPPtrBinding> bindings, in TinyAnimationTime animationTime) =>
            {
                var time = animationTime.Value;
                for (int i = 0; i < bindings.Length; ++i)
                {
                    var binding = bindings[i];
                    var result  = (int)KeyframeCurveEvaluator.Evaluate(time, binding.Curve);

                    var source = binding.SourceEntity;
                    entityComponentStore->AssertEntityHasComponent(source, animatedAssetReferenceTypeIndex);

                    var pPtrBindingSourcesBuffer = (BufferHeader *)entityComponentStore->GetComponentDataWithTypeRO(source, animatedAssetReferenceTypeIndex);
                    var pPtrBindingSource        = ((AnimationPPtrBindingSources *)BufferHeader.GetElementPointer(pPtrBindingSourcesBuffer))[result];

                    var typeIndex = binding.TargetComponentTypeIndex;

                    var entity = binding.TargetEntity;

                    entityComponentStore->AssertEntityHasComponent(entity, typeIndex);

                    var targetComponentPtr = entityComponentStore->GetComponentDataWithTypeRW(entity, typeIndex, globalVersion);
                    var targetFieldPtr     = targetComponentPtr + binding.FieldOffset;

                    UnsafeUtility.MemCpy(targetFieldPtr, UnsafeUtility.AddressOf(ref pPtrBindingSource.Value), UnsafeUtility.SizeOf <Entity>());
                }
            }).Schedule(Dependency);
        internal static NativeArray <NativeView> GetBufferViews(this ArchetypeChunk self, ChunkTypeIndex index, int elementSize, Allocator allocator)
        {
            var typeSize = self.GetTypeSize(index);
            var offset   = self.GetTypeOffset(index);

            var count = self.Count;
            var views = new NativeArray <NativeView>(count, allocator, NativeArrayOptions.UninitializedMemory);

            unsafe
            {
                var ptr = self.m_Chunk->Buffer + offset;

                for (int i = 0; i < count; i++)
                {
                    var buffer = (BufferHeader *)(ptr + i * typeSize);
                    var data   = BufferHeader.GetElementPointer(buffer);

                    views[i] = new NativeView(data, buffer->Length * elementSize);
                }
            }
            return(views);
        }
예제 #9
0
        public void CopyFrom(T[] v)
        {
            if (v == null)
            {
                throw new ArgumentNullException(nameof(v));
            }

#if NET_DOTS
            Clear();
            foreach (var d in v)
            {
                Add(d);
            }
#else
            ResizeUninitialized(v.Length);

            GCHandle gcHandle = GCHandle.Alloc((object)v, GCHandleType.Pinned);
            IntPtr   num      = gcHandle.AddrOfPinnedObject();

            UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(m_Buffer),
                                 (void *)num, Length * UnsafeUtility.SizeOf <T>());
            gcHandle.Free();
#endif
        }
예제 #10
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);
                                }
                            }
                        }
                    }
                }
            }
        }
        protected override unsafe void OnUpdate()
        {
            using (var entityGuidHashMap = new NativeHashMap <EntityGuid, Entity>(m_EntityGuidQuery.CalculateLength(), Allocator.TempJob))
            {
                var entityType = EntityManager.GetArchetypeChunkEntityType();

                new BuildEntityGuidHashMapJob
                {
                    Entity         = entityType,
                    EntityGuidType = GetArchetypeChunkComponentType <EntityGuid>(true),
                    HashMap        = entityGuidHashMap.ToConcurrent()
                }.Schedule(m_EntityGuidQuery).Complete();

                using (var chunks = m_EntityReferenceRemapQuery.CreateArchetypeChunkArray(Allocator.TempJob))
                {
                    var entityReferenceRemapType = GetArchetypeChunkBufferType <EntityReferenceRemap>(true);

                    // Run through all chunks
                    for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++)
                    {
                        var entities = chunks[chunkIndex].GetNativeArray(entityType);
                        var entityReferenceRemaps = chunks[chunkIndex].GetBufferAccessor(entityReferenceRemapType);

                        // Run through each entity of the chunk
                        for (var entityIndex = 0; entityIndex < entityReferenceRemaps.Length; entityIndex++)
                        {
                            var entity = entities[entityIndex];
                            var entityReferenceRemap = entityReferenceRemaps[entityIndex];

                            // Run through each remap for the entity
                            for (var remapIndex = 0; remapIndex < entityReferenceRemap.Length; remapIndex++)
                            {
                                var remap = entityReferenceRemap[remapIndex];

                                // Find the live entity which matches this guid
                                if (!entityGuidHashMap.TryGetValue(remap.Guid, out var target))
                                {
                                    continue;
                                }

                                // Resolve the type
                                var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(remap.TypeHash);

                                if (TypeManager.IsSharedComponent(typeIndex))
                                {
                                    // @TODO get this working in the NET_DOTS runtime

                                    /*
                                     * var type = TypeManager.GetType(typeIndex);
                                     *
                                     * // ASSUMPTION: Shared component data is blittable
                                     * if (!UnsafeUtility.IsBlittable(type))
                                     * {
                                     *  throw new Exception($"Trying to remap entity reference for a non blittable shared component Type=[{type.FullName}]");
                                     * }
                                     *
                                     * // Patch shared component reference
                                     * var sharedComponent = EntityManager.GetSharedComponentData(entity, typeIndex);
                                     *(Entity*) ((byte*) Unsafe.AsPointer(ref sharedComponent) + remap.Offset) = target;
                                     * EntityManager.SetSharedComponentDataBoxed(entity, typeIndex, sharedComponent);
                                     */
                                    continue;
                                }

                                if (TypeManager.IsBuffer(typeIndex))
                                {
                                    // Patch buffer component reference
                                    var ptr = (BufferHeader *)EntityManager.GetComponentDataRawRW(entity, typeIndex);
                                    *(Entity *)(BufferHeader.GetElementPointer(ptr) + remap.Offset) = target;
                                    continue;
                                }

                                // Patch standard component reference
                                *(Entity *)((byte *)EntityManager.GetComponentDataRawRW(entity, typeIndex) + remap.Offset) = target;
                            }
                        }
                    }
                }
            }
        }
        public static unsafe (IntPtr ptr, int length) GetBufferArrayRawRO(this Entity entity, EntityManager em, int typeIndex)
        {
            var header = (BufferHeader *)em.GetComponentDataRawRO(entity, typeIndex);

            return(new IntPtr(BufferHeader.GetElementPointer(header)), header->Length);
        }
        public static unsafe (IntPtr ptr, int length) GetBufferArrayRawRO(this ArchetypeChunk chunk, int chunkIndex, int typeIndex)
        {
            var header = (BufferHeader *)GetComponentDataWithTypeRO(chunk, chunkIndex, typeIndex);

            return(new IntPtr(BufferHeader.GetElementPointer(header)), header->Length);
        }
예제 #14
0
 public void *GetUnsafeReadOnlyPtr()
 {
     return(BufferHeader.GetElementPointer(m_Buffer));
 }
예제 #15
0
        private static unsafe Entity CopyEntity(Entity srcEntity, World srcWorld, World dstWorld)
        {
            Assert.AreNotEqual(Entity.Null, srcEntity);

            using (var entityReferences = new NativeList <EntityReferenceRemap>(8, Allocator.Temp))
                using (var componentTypes = srcWorld.EntityManager.GetComponentTypes(srcEntity))
                {
                    var archetype = dstWorld.EntityManager.CreateArchetype(componentTypes.ToArray());
                    var dstEntity = dstWorld.EntityManager.CreateEntity(archetype);

                    if (componentTypes.Any(x => x.HasEntityReferences) && !dstWorld.EntityManager.HasComponent <EntityReferenceRemap>(dstEntity))
                    {
                        dstWorld.EntityManager.AddBuffer <EntityReferenceRemap>(dstEntity);
                    }

                    foreach (var componentType in componentTypes)
                    {
                        var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex);

                        if (typeInfo.SizeInChunk == 0)
                        {
                            continue;
                        }

                        if (componentType.IsSharedComponent)
                        {
                            // @TODO For now we assume that all shared component data is blittable
                            var srcComponent = srcWorld.EntityManager.GetSharedComponentData(srcEntity, componentType.TypeIndex);

                            var ptr = Unsafe.AsPointer(ref srcComponent);

                            // Pull out all references into the `entityReferences` list
                            ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, ptr);

                            // Zero out entity references
                            ClearEntityReferences(typeInfo, ptr);

                            dstWorld.EntityManager.SetSharedComponentDataBoxed(dstEntity, componentType.TypeIndex, srcComponent);
                            continue;
                        }

                        if (componentType.IsBuffer)
                        {
                            var srcBuffer = (BufferHeader *)srcWorld.EntityManager.GetComponentDataRawRW(srcEntity, componentType.TypeIndex);
                            var dstBuffer = (BufferHeader *)dstWorld.EntityManager.GetComponentDataRawRW(dstEntity, componentType.TypeIndex);

                            dstBuffer->Length = srcBuffer->Length;
                            BufferHeader.EnsureCapacity(dstBuffer, srcBuffer->Length, typeInfo.ElementSize, 4, BufferHeader.TrashMode.RetainOldData);

                            // Copy all blittable data
                            UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(dstBuffer), BufferHeader.GetElementPointer(srcBuffer), typeInfo.ElementSize * srcBuffer->Length);

                            for (var i = 0; i < srcBuffer->Length; i++)
                            {
                                var baseOffset = i * typeInfo.ElementSize;

                                // Pull out all references into the `entityReferences` list
                                ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, BufferHeader.GetElementPointer(dstBuffer), baseOffset);

                                // Zero out entity references
                                ClearEntityReferences(typeInfo, BufferHeader.GetElementPointer(dstBuffer), baseOffset);
                            }

                            continue;
                        }

                        var componentData = srcWorld.EntityManager.GetComponentDataRawRW(srcEntity, componentType.TypeIndex);

                        // Copy all blittable data
                        dstWorld.EntityManager.SetComponentDataRaw(dstEntity, componentType.TypeIndex, componentData, typeInfo.SizeInChunk);

                        // Pull out all references into the `entityReferences` list
                        ExtractEntityReferences(entityReferences, typeInfo, srcWorld.EntityManager, componentData);

                        // Zero out entity references
                        ClearEntityReferences(typeInfo, dstWorld.EntityManager.GetComponentDataRawRW(dstEntity, componentType.TypeIndex));
                    }

                    if (entityReferences.Length > 0)
                    {
                        dstWorld.EntityManager.GetBuffer <EntityReferenceRemap>(dstEntity).AddRange(entityReferences);
                    }

                    return(dstEntity);
                }
        }