// Ensure there are at least "count" free managed component indices and // resize managed component array directly if needed public void ReserveManagedComponentIndicesDirect(int count, ref EntityComponentStore entityComponentStore) { int freeCount = entityComponentStore.ManagedComponentFreeCount; if (freeCount >= count) { return; } int newCapacity = entityComponentStore.GrowManagedComponentCapacity(count - freeCount); SetManagedComponentCapacity(newCapacity); }
public void UpdateManagedComponentValue(int *index, object value, ref EntityComponentStore entityComponentStore) { entityComponentStore.AssertNoQueuedManagedDeferredCommands(); var iManagedComponent = *index; if (value != null) { if (iManagedComponent == 0) { ReserveManagedComponentIndicesDirect(1, ref entityComponentStore); iManagedComponent = *index = entityComponentStore.AllocateManagedComponentIndex(); } } else { if (iManagedComponent == 0) { return; } *index = 0; entityComponentStore.FreeManagedComponentIndex(iManagedComponent); } m_ManagedComponentData[iManagedComponent] = value; }
public static void Convert(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstIndex, int count, ref EntityComponentStore entityComponentStore) { Assert.IsFalse(srcChunk == dstChunk); var srcArch = srcChunk->Archetype; var dstArch = dstChunk->Archetype; if (srcArch != dstArch) { Assert.IsFalse(srcArch == null); } var srcI = srcArch->NonZeroSizedTypesCount - 1; var dstI = dstArch->NonZeroSizedTypesCount - 1; var sourceTypesToDealloc = stackalloc int[srcI + 1]; int sourceTypesToDeallocCount = 0; while (dstI >= 0) { var srcType = srcArch->Types[srcI]; var dstType = dstArch->Types[dstI]; if (srcType > dstType) { //Type in source is not moved so deallocate it sourceTypesToDealloc[sourceTypesToDeallocCount++] = srcI; --srcI; continue; } var srcStride = srcArch->SizeOfs[srcI]; var dstStride = dstArch->SizeOfs[dstI]; var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; var dst = dstChunk->Buffer + dstArch->Offsets[dstI] + dstIndex * dstStride; if (srcType == dstType) { UnsafeUtility.MemCpy(dst, src, count * srcStride); --srcI; --dstI; } else { if (dstType.IsBuffer) { InitializeBuffersInChunk(dst, count, dstStride, dstArch->BufferCapacities[dstI]); } else { UnsafeUtility.MemClear(dst, count * dstStride); } --dstI; } } if (sourceTypesToDeallocCount == 0) { return; } sourceTypesToDealloc[sourceTypesToDeallocCount] = 0; int iDealloc = 0; if (sourceTypesToDealloc[iDealloc] >= srcArch->FirstManagedComponent) { var freeCommandHandle = entityComponentStore.ManagedChangesTracker.BeginFreeManagedComponentCommand(); do { srcI = sourceTypesToDealloc[iDealloc]; var srcStride = srcArch->SizeOfs[srcI]; var src = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; var a = (int *)src; for (int i = 0; i < count; i++) { var managedComponentIndex = a[i]; if (managedComponentIndex == 0) { continue; } entityComponentStore.FreeManagedComponentIndex(managedComponentIndex); entityComponentStore.ManagedChangesTracker.AddToFreeManagedComponentCommand(managedComponentIndex); } } while ((sourceTypesToDealloc[++iDealloc] >= srcArch->FirstManagedComponent)); entityComponentStore.ManagedChangesTracker.EndDeallocateManagedComponentCommand(freeCommandHandle); } while (sourceTypesToDealloc[iDealloc] >= srcArch->FirstBufferComponent) { srcI = sourceTypesToDealloc[iDealloc]; var srcStride = srcArch->SizeOfs[srcI]; var srcPtr = srcChunk->Buffer + srcArch->Offsets[srcI] + srcIndex * srcStride; for (int i = 0; i < count; i++) { BufferHeader.Destroy((BufferHeader *)srcPtr); srcPtr += srcStride; } ++iDealloc; } }
public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore) { var srcArchetype = srcChunk->Archetype; var srcBuffer = srcChunk->Buffer; var dstBuffer = dstChunk->Buffer; var dstArchetype = dstChunk->Archetype; var srcOffsets = srcArchetype->Offsets; var srcSizeOfs = srcArchetype->SizeOfs; var srcBufferCapacities = srcArchetype->BufferCapacities; var srcTypes = srcArchetype->Types; var dstTypes = dstArchetype->Types; var dstOffsets = dstArchetype->Offsets; var dstTypeIndex = 1; var nativeComponentsEnd = srcArchetype->NativeComponentsEnd; for (var srcTypeIndex = 1; srcTypeIndex != nativeComponentsEnd; srcTypeIndex++) { var srcType = srcTypes[srcTypeIndex]; var dstType = dstTypes[dstTypeIndex]; // Type does not exist in destination. Skip it. if (srcType.TypeIndex != dstType.TypeIndex) { continue; } var srcSizeOf = srcSizeOfs[srcTypeIndex]; var src = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex); var dst = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex); UnsafeUtility.MemCpyReplicate(dst, src, srcSizeOf, count); dstTypeIndex++; } dstTypeIndex = dstArchetype->FirstBufferComponent; var bufferComponentsEnd = srcArchetype->BufferComponentsEnd; for (var srcTypeIndex = srcArchetype->FirstBufferComponent; srcTypeIndex != bufferComponentsEnd; srcTypeIndex++) { var srcType = srcTypes[srcTypeIndex]; var dstType = dstTypes[dstTypeIndex]; // Type does not exist in destination. Skip it. if (srcType.TypeIndex != dstType.TypeIndex) { continue; } var srcSizeOf = srcSizeOfs[srcTypeIndex]; var src = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex); var dst = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex); var srcBufferCapacity = srcBufferCapacities[srcTypeIndex]; var alignment = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager var elementSize = TypeManager.GetTypeInfo(srcType.TypeIndex).ElementSize; for (int i = 0; i < count; ++i) { BufferHeader *srcHdr = (BufferHeader *)src; BufferHeader *dstHdr = (BufferHeader *)dst; BufferHeader.Initialize(dstHdr, srcBufferCapacity); BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, elementSize, alignment, false, 0); dst += srcSizeOf; } dstTypeIndex++; } if (dstArchetype->NumManagedComponents > 0) { ReplicateManagedComponents(srcChunk, srcIndex, dstChunk, dstBaseIndex, count, ref entityComponentStore); } }
public static void ReplicateManagedComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore) { var dstArchetype = dstChunk->Archetype; var srcArchetype = srcChunk->Archetype; var srcTypes = srcArchetype->Types; var dstTypes = dstArchetype->Types; var srcOffsets = srcArchetype->Offsets; var dstOffsets = dstArchetype->Offsets; int componentCount = dstArchetype->NumManagedComponents; int nonNullManagedComponents = 0; int nonNullHybridComponents = 0; var componentIndices = stackalloc int[componentCount]; var componentDstArrayStart = stackalloc IntPtr[componentCount]; var firstDstManagedComponent = dstArchetype->FirstManagedComponent; var dstTypeIndex = firstDstManagedComponent; var managedComponentsEnd = srcArchetype->ManagedComponentsEnd; var srcBaseAddr = srcChunk->Buffer + sizeof(int) * srcIndex; var dstBaseAddr = dstChunk->Buffer + sizeof(int) * dstBaseIndex; bool hasHybridComponents = dstArchetype->HasHybridComponents; for (var srcTypeIndex = srcArchetype->FirstManagedComponent; srcTypeIndex != managedComponentsEnd; srcTypeIndex++) { var srcType = srcTypes[srcTypeIndex]; var dstType = dstTypes[dstTypeIndex]; // Type does not exist in destination. Skip it. if (srcType.TypeIndex != dstType.TypeIndex) { continue; } int srcManagedComponentIndex = *(int *)(srcBaseAddr + srcOffsets[srcTypeIndex]); var dstArrayStart = dstBaseAddr + dstOffsets[dstTypeIndex]; if (srcManagedComponentIndex == 0) { UnsafeUtility.MemClear(dstArrayStart, sizeof(int) * count); } else { if (hasHybridComponents && TypeManager.GetTypeInfo(srcType.TypeIndex).Category == TypeManager.TypeCategory.Class) { //Hybrid component, put at end of array var index = componentCount - nonNullHybridComponents - 1; componentIndices[index] = srcManagedComponentIndex; componentDstArrayStart[index] = (IntPtr)dstArrayStart; ++nonNullHybridComponents; } else { componentIndices[nonNullManagedComponents] = srcManagedComponentIndex; componentDstArrayStart[nonNullManagedComponents] = (IntPtr)dstArrayStart; ++nonNullManagedComponents; } } dstTypeIndex++; } entityComponentStore.ReserveManagedComponentIndices(count * (nonNullManagedComponents + nonNullHybridComponents)); entityComponentStore.ManagedChangesTracker.CloneManagedComponentBegin(componentIndices, nonNullManagedComponents, count); for (int c = 0; c < nonNullManagedComponents; ++c) { var dst = (int *)(componentDstArrayStart[c]); entityComponentStore.AllocateManagedComponentIndices(dst, count); entityComponentStore.ManagedChangesTracker.CloneManagedComponentAddDstIndices(dst, count); } if (hasHybridComponents) { var companionLinkIndexInTypeArray = GetIndexInTypeArray(dstArchetype, ManagedComponentStore.CompanionLinkTypeIndex); var companionLinkIndices = (companionLinkIndexInTypeArray == -1) ? null : (int *)(dstBaseAddr + dstOffsets[companionLinkIndexInTypeArray]); var dstEntities = (Entity *)dstChunk->Buffer + dstBaseIndex; entityComponentStore.ManagedChangesTracker.CloneHybridComponentBegin( componentIndices + componentCount - nonNullHybridComponents, nonNullHybridComponents, dstEntities, count, companionLinkIndices); for (int c = componentCount - nonNullHybridComponents; c < componentCount; ++c) { var dst = (int *)(componentDstArrayStart[c]); entityComponentStore.AllocateManagedComponentIndices(dst, count); entityComponentStore.ManagedChangesTracker.CloneHybridComponentAddDstIndices(dst, count); } } }
public void ResetManagedComponentStoreForDeserialization(int managedComponentCount, ref EntityComponentStore entityComponentStore) { managedComponentCount++; // also need space for 0 index (null) UnityEngine.Assertions.Assert.AreEqual(0, entityComponentStore.ManagedComponentIndexUsedCount); entityComponentStore.m_ManagedComponentFreeIndex.Size = 0; entityComponentStore.m_ManagedComponentIndex = managedComponentCount; if (managedComponentCount > entityComponentStore.m_ManagedComponentIndexCapacity) { entityComponentStore.m_ManagedComponentIndexCapacity = managedComponentCount; SetManagedComponentCapacity(managedComponentCount); } }
public void CloneManagedComponentsFromDifferentWorld(int *indices, int count, ManagedComponentStore srcManagedComponentStore, ref EntityComponentStore dstEntityComponentStore) { dstEntityComponentStore.AssertNoQueuedManagedDeferredCommands(); ReserveManagedComponentIndicesDirect(count, ref dstEntityComponentStore); for (int i = 0; i < count; ++i) { var obj = srcManagedComponentStore.m_ManagedComponentData[indices[i]]; var clone = CloneManagedComponent(obj); int dstIndex = dstEntityComponentStore.AllocateManagedComponentIndex(); m_ManagedComponentData[dstIndex] = clone; } }