Пример #1
0
        void AddToDestroyList(Chunk *chunk, int indexInChunk, int batchCount, int inputDestroyCount,
                              ref UnsafeList entitiesList, ref int minBufferLength, ref int maxBufferLength)
        {
            int indexInArchetype = ChunkDataUtility.GetIndexInTypeArray(chunk->Archetype, m_LinkedGroupType);

            if (indexInArchetype != -1)
            {
                var baseHeader = ChunkDataUtility.GetComponentDataWithTypeRO(chunk, indexInChunk, m_LinkedGroupType);
                var stride     = chunk->Archetype->SizeOfs[indexInArchetype];
                for (int i = 0; i != batchCount; i++)
                {
                    var header = (BufferHeader *)(baseHeader + stride * i);

                    var entityGroupCount = header->Length - 1;
                    if (entityGroupCount <= 0)
                    {
                        continue;
                    }

                    var entityGroupArray = (Entity *)BufferHeader.GetElementPointer(header) + 1;

                    if (entitiesList.Capacity == 0)
                    {
                        entitiesList.SetCapacity <Entity>(inputDestroyCount * entityGroupCount /*, Allocator.TempJob*/);
                    }
                    entitiesList.AddRange <Entity>(entityGroupArray, entityGroupCount /*, Allocator.TempJob*/);

                    minBufferLength = math.min(minBufferLength, entityGroupCount);
                    maxBufferLength = math.max(maxBufferLength, entityGroupCount);
                }
            }
        }
Пример #2
0
        internal unsafe void CalculateDependents(NativeArray <int> instanceIds, NativeHashSet <int> outDependents)
        {
            var toBeProcessed = new UnsafeList <int>(0, Allocator.Temp);

            toBeProcessed.AddRange(instanceIds.GetUnsafeReadOnlyPtr(), instanceIds.Length);
            while (toBeProcessed.Length != 0)
            {
                var instance = toBeProcessed.Ptr[toBeProcessed.Length - 1];
                toBeProcessed.RemoveAtSwapBack(toBeProcessed.Length - 1);
                if (outDependents.Add(instance))
                {
                    var dependentIds = _dependentsByInstanceId.GetValuesForKey(instance);
                    while (dependentIds.MoveNext())
                    {
                        if (!outDependents.Contains(dependentIds.Current))
                        {
                            toBeProcessed.Add(dependentIds.Current);
                        }
                    }
                }
            }
        }
            public void Execute(int index)
            {
                var chunk            = Chunks[index].m_Chunk;
                var archetype        = chunk->Archetype;
                var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);

                if (indexInTypeArray == -1) // Archetype doesn't match required component
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.Version))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedEntities.IsCreated)
                    {
                        changesForChunk->Chunk           = chunk;
                        changesForChunk->AddedEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedEntities = new UnsafeList(Allocator.TempJob);
                    }

                    var entityDataPtr = (Entity *)(chunk->Buffer + archetype->Offsets[0]);
                    var currentCount  = chunk->Count;
                    var previousCount = shadow.EntityCount;
                    var i             = 0;
                    for (; i < currentCount && i < previousCount; i++)
                    {
                        var currentEntity  = entityDataPtr[i];
                        var previousEntity = shadow.EntityDataBuffer[i];

                        if (currentEntity != previousEntity)
                        {
                            // CHANGED ENTITY!
                            changesForChunk->RemovedEntities.Add(previousEntity);
                            changesForChunk->AddedEntities.Add(currentEntity);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW ENTITY!
                        changesForChunk->AddedEntities.Add(entityDataPtr[i]);
                    }

                    for (; i < previousCount; i++)
                    {
                        // REMOVED ENTITY!
                        changesForChunk->RemovedEntities.Add(shadow.EntityDataBuffer[i]);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedEntities = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);
                    var entityDataPtr = chunk->Buffer + archetype->Offsets[0];
                    addedEntities.AddRange <Entity>(entityDataPtr, chunk->Count);
                    changesForChunk->Chunk         = chunk;
                    changesForChunk->AddedEntities = addedEntities;
                }
            }
Пример #4
0
            public void Execute(int index)
            {
                var chunk     = Chunks[index].m_Chunk;
                var archetype = chunk->Archetype;

                if (!archetype->CompareMask(QueryMask)) // Archetype doesn't match required query
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.Version))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedEntities.IsCreated)
                    {
                        changesForChunk->AddedEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedEntities = new UnsafeList(Allocator.TempJob);
                    }

                    var currentEntity    = (Entity *)(chunk->Buffer + archetype->Offsets[0]);
                    var entityFromShadow = (Entity *)shadow.EntityBuffer;

                    var currentCount = chunk->Count;
                    var shadowCount  = shadow.Count;

                    var i = 0;

                    for (; i < currentCount && i < shadowCount; i++)
                    {
                        if (currentEntity[i] == entityFromShadow[i])
                        {
                            continue;
                        }

                        // Was a valid entity but version was incremented, thus destroyed
                        if (entityFromShadow[i].Version != 0)
                        {
                            changesForChunk->RemovedEntities.Add(entityFromShadow[i]);
                            changesForChunk->AddedEntities.Add(currentEntity[i]);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW ENTITY!
                        changesForChunk->AddedEntities.Add(currentEntity[i]);
                    }

                    for (; i < shadowCount; i++)
                    {
                        // REMOVED ENTITY!
                        changesForChunk->RemovedEntities.Add(entityFromShadow[i]);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedComponentEntities = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);

                    var entityDataPtr = chunk->Buffer + archetype->Offsets[0];

                    addedComponentEntities.AddRange <Entity>(entityDataPtr, chunk->Count);

                    changesForChunk->AddedEntities = addedComponentEntities;
                }
            }
            public void Execute(int index)
            {
                var chunk            = Chunks[index].m_Chunk;
                var archetype        = chunk->Archetype;
                var indexInTypeArray = ChunkDataUtility.GetIndexInTypeArray(archetype, TypeIndex);

                if (indexInTypeArray == -1) // Archetype doesn't match required component
                {
                    return;
                }

                var changesForChunk = GatheredChanges + index;

                if (ShadowChunksBySequenceNumber.TryGetValue(chunk->SequenceNumber, out var shadow))
                {
                    if (!ChangeVersionUtility.DidChange(chunk->GetChangeVersion(indexInTypeArray), shadow.ComponentVersion) &&
                        !ChangeVersionUtility.DidChange(chunk->GetChangeVersion(0), shadow.EntityVersion))
                    {
                        return;
                    }

                    if (!changesForChunk->AddedComponentEntities.IsCreated)
                    {
                        changesForChunk->AddedComponentEntities     = new UnsafeList(Allocator.TempJob);
                        changesForChunk->AddedComponentDataBuffer   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedComponentEntities   = new UnsafeList(Allocator.TempJob);
                        changesForChunk->RemovedComponentDataBuffer = new UnsafeList(Allocator.TempJob);
                    }

                    var entityDataPtr    = chunk->Buffer + archetype->Offsets[0];
                    var componentDataPtr = chunk->Buffer + archetype->Offsets[indexInTypeArray];

                    var currentCount  = chunk->Count;
                    var previousCount = shadow.Count;

                    var i = 0;

                    for (; i < currentCount && i < previousCount; i++)
                    {
                        var currentComponentData  = componentDataPtr + ComponentSize * i;
                        var previousComponentData = shadow.ComponentDataBuffer + ComponentSize * i;

                        var entity         = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var previousEntity = *(Entity *)(shadow.EntityDataBuffer + sizeof(Entity) * i);

                        if (entity != previousEntity ||
                            UnsafeUtility.MemCmp(currentComponentData, previousComponentData, ComponentSize) != 0)
                        {
                            // CHANGED COMPONENT DATA!
                            OnRemovedComponent(changesForChunk, previousEntity, previousComponentData, ComponentSize);
                            OnNewComponent(changesForChunk, entity, currentComponentData, ComponentSize);
                        }
                    }

                    for (; i < currentCount; i++)
                    {
                        // NEW COMPONENT DATA!
                        var entity = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var currentComponentData = componentDataPtr + ComponentSize * i;
                        OnNewComponent(changesForChunk, entity, currentComponentData, ComponentSize);
                    }

                    for (; i < previousCount; i++)
                    {
                        // REMOVED COMPONENT DATA!
                        var entity = *(Entity *)(entityDataPtr + sizeof(Entity) * i);
                        var previousComponentData = shadow.ComponentDataBuffer + ComponentSize * i;
                        OnRemovedComponent(changesForChunk, entity, previousComponentData, ComponentSize);
                    }
                }
                else
                {
                    // This is a new chunk
                    var addedComponentDataBuffer = new UnsafeList(ComponentSize, 4, chunk->Count, Allocator.TempJob);
                    var addedComponentEntities   = new UnsafeList(sizeof(Entity), 4, chunk->Count, Allocator.TempJob);

                    var entityDataPtr    = chunk->Buffer + archetype->Offsets[0];
                    var componentDataPtr = chunk->Buffer + archetype->Offsets[indexInTypeArray];

                    addedComponentDataBuffer.AddRange <byte>(componentDataPtr, chunk->Count * ComponentSize);
                    addedComponentEntities.AddRange <Entity>(entityDataPtr, chunk->Count);

                    changesForChunk->AddedComponentDataBuffer = addedComponentDataBuffer;
                    changesForChunk->AddedComponentEntities   = addedComponentEntities;
                }
            }