public void CopyFrom(DynamicBufferUnsafe <T> v) { ResizeUninitialized(v.Length); UnsafeUtility.MemCpy(BufferHeader.GetElementPointer(m_Buffer), BufferHeader.GetElementPointer(v.m_Buffer), Length * UnsafeUtility.SizeOf <T>()); }
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; }
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); }
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; }
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); } }
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); }
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); }
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 }
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); }
public void *GetUnsafeReadOnlyPtr() { return(BufferHeader.GetElementPointer(m_Buffer)); }
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); } }