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; } } }
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); } } }
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++; } }
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); }
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; }
public static Chunk *AllocateChunk() { Chunk *chunk = (Chunk *)MemoryUtility.Malloc(Chunk.ChunkSize); return(chunk); }
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; } }
public static void ConstructChunk(Chunk *chunk, Archetype *archetype) { chunk->archetype = archetype; chunk->count = 0; chunk->capacity = archetype->chunkCapacity; }
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; }
public static Span <Entity> GetEntities(Chunk *chunk) { Entity *buffer = (Entity *)chunk->buffer; return(new Span <Entity>(buffer, chunk->count)); }
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++; } } }
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))); }
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); }
public void AddToChunkListWithEmptySlots(Chunk *chunk) { chunk->ListWithEmptySlotsIndex = ChunksWithEmptySlots.Length; ChunksWithEmptySlots.Add(chunk); }
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; } } } } }