public void Execute(DynamicComponentTypeHandle *ghostChunkComponentTypesPtr,
                                int ghostChunkComponentTypesLength)
            {
                for (int i = 0; i < GhostChunks.Length; i++)
                {
                    ArchetypeChunk chunk    = GhostChunks[i];
                    var            entities = chunk.GetNativeArray(EntityTypeHandle);
                    var            buffers  = chunk.GetBufferAccessor(SnapshotBufferTypeHandle);
                    var            datas    = chunk.GetNativeArray(SnapshotComponentTypeHandle);
                    var            ghosts   = chunk.GetNativeArray(GhostComponentTypeHandle);

                    for (int ent = 0; ent < entities.Length; ent++)
                    {
                        GhostComponent ghostComponent = ghosts[ent];
                        var            typeState      = GhostTypeCollection[ghostComponent.GhostType];

                        SnapshotData snapshotData = datas[ent];
                        DynamicBuffer <SnapshotDataBuffer> snapshotDataBuffer = buffers[ent];

                        if (snapshotData.SnapshotSize == 0)
                        {
                            continue;
                        }

                        bool isGet = snapshotData.GetDataAtTick(snapshotDataBuffer, InterpolatedTargetTick,
                                                                InterpolatedTargetTickFraction,
                                                                out var dataAtTick);

                        int baseOffset        = typeState.FirstComponent;
                        int numBaseComponents = typeState.NumComponents;

                        // 跳过Tick
                        int offset = GlobalConstants.TickSize;

                        for (int j = 0; j < numBaseComponents; j++)
                        {
                            int compIdx = ComponentIndex[baseOffset + j].ComponentIndex;
                            GhostComponentSerializer   serializer  = ComponentSerializers[compIdx];
                            DynamicComponentTypeHandle dynamicType =
                                ghostChunkComponentTypesPtr[compIdx];

                            if (chunk.Has(dynamicType))
                            {
                                IntPtr compPtr = (IntPtr)chunk
                                                 .GetDynamicComponentDataArrayReinterpret <byte>(dynamicType,
                                                                                                 serializer.ComponentSize).GetUnsafePtr();

                                if (isGet)
                                {
                                    serializer.CopyFromSnapshot.Ptr.Invoke(
                                        compPtr + serializer.ComponentSize * ent,
                                        (IntPtr)(&dataAtTick), offset);
                                }
                            }

                            offset += serializer.DataSize;
                        }
                    }
                }
            }
        public void Distribute(DynamicComponentTypeHandle typeHandle, ArchetypeChunk chunk, Dictionary <uint, byte[]> objects)
        {
            NativeArray <PhysicsColliderBlob> components  = chunk.GetDynamicComponentDataArrayReinterpret <PhysicsColliderBlob>(typeHandle, PhysicsColliderBlob.TYPE_SIZE);
            NativeArray <SimAssetId>          simAssetIds = chunk.Has(_simAssetIdsHandle) ? chunk.GetNativeArray(_simAssetIdsHandle) : default;

            for (int i = 0; i < components.Length; i++)
            {
                uint id = ushort.MaxValue + 1;

                if (simAssetIds.IsCreated)
                {
                    id = simAssetIds[i].Value;
                }

                if (objects.TryGetValue(id, out byte[] data))
        public void Collect(DynamicComponentTypeHandle typeHandle, ArchetypeChunk chunk, Dictionary <uint, byte[]> outResult)
        {
            NativeArray <PhysicsColliderBlob> components  = chunk.GetDynamicComponentDataArrayReinterpret <PhysicsColliderBlob>(typeHandle, PhysicsColliderBlob.TYPE_SIZE);
            NativeArray <SimAssetId>          simAssetIds = chunk.Has(_simAssetIdsHandle) ? chunk.GetNativeArray(_simAssetIdsHandle) : default;

            for (int i = 0; i < components.Length; i++)
            {
                if (components[i].Collider.IsCreated)
                {
                    byte[] data;
                    IntPtr ptr;

                    unsafe
                    {
                        ptr = new IntPtr(components[i].Collider.GetUnsafePtr());
                    }

                    if (!_cachedColliders.TryGetValue(ptr, out data))
                    {
                        using (var writer = new MemoryBinaryWriter())
                        {
                            writer.Write(components[i].Collider);
                            data = writer.GetDataArray();
                        }

                        _cachedColliders[ptr] = data;
                    }

                    if (simAssetIds.IsCreated)
                    {
                        outResult[simAssetIds[i].Value] = data;
                    }
                    else
                    {
#if SAFETY && UNITY_EDITOR
                        if (!chunk.Has(_tileColliderTagHandle))
                        {
                            Log.Error($"Error in collider collection: An entity ({string.Join(", ", chunk.Archetype.GetComponentTypes().Select(c => c.ToString()))}) " +
                                      $"has a collider but no SimAssetId");
                            continue;
                        }
#endif
                        outResult[ushort.MaxValue + 1] = data;
                    }
                }
            }
        }
        public unsafe bool GetByTypeIndex(int typeIndex, out DynamicComponentTypeHandle typeHandle)
        {
            Debug.Assert(typeIndex != 0);
            for (int i = 0; i < m_Length; i++)
            {
                DynamicComponentTypeHandle element = UnsafeUtility.ReadArrayElement <DynamicComponentTypeHandle>(m_Buffer, i);
                if (element.GetTypeIndex() == typeIndex)
                {
                    typeHandle = element;
                    return(true);
                }
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            throw new ArgumentException("There was no DynamicComponentTypeHandle found with the type index you provided.", nameof(typeIndex));
#else
            typeHandle = default;
            return(false);
#endif
        }
            public void Execute(DynamicComponentTypeHandle *ghostChunkComponentTypesPtr,
                                int ghostChunkComponentTypesLength)
            {
                for (int i = 0; i < GhostChunks.Length; i++)
                {
                    ArchetypeChunk chunk    = GhostChunks[i];
                    var            entities = chunk.GetNativeArray(EntityTypeHandle);
                    var            buffers  = chunk.GetBufferAccessor(SnapshotBufferTypeHandle);
                    var            datas    = chunk.GetNativeArray(SnapshotComponentTypeHandle);
                    var            ghosts   = chunk.GetNativeArray(GhostComponentTypeHandle);

                    for (int ent = 0; ent < entities.Length; ent++)
                    {
                        GhostComponent ghostComponent = ghosts[ent];

                        var typeState = GhostTypeCollection[ghostComponent.GhostType];

                        SnapshotData snapshotData = datas[ent];
                        DynamicBuffer <SnapshotDataBuffer> snapshotDataBuffer = buffers[ent];

                        if (snapshotData.SnapshotSize == 0)
                        {
                            continue;
                        }

                        IntPtr latestSnapshot = snapshotData.GetLatest(snapshotDataBuffer);

                        int baseOffset        = typeState.FirstComponent;
                        int numBaseComponents = typeState.NumComponents;

                        // 跳过Tick
                        int offset = GlobalConstants.TickSize;
                        for (int j = 0; j < numBaseComponents; j++)
                        {
                            int cmpIdx     = ComponentIndex[baseOffset + j].ComponentIndex;
                            var serializer = ComponentSerializers[cmpIdx];


                            DynamicComponentTypeHandle dynamicType =
                                ghostChunkComponentTypesPtr[cmpIdx];
                            if (chunk.Has(dynamicType))
                            {
                                IntPtr compPtr = (IntPtr)chunk
                                                 .GetDynamicComponentDataArrayReinterpret <byte>(dynamicType,
                                                                                                 serializer.ComponentSize).GetUnsafePtr();

                                // 不回滚只更新值
                                if (serializer.IsUpdateValue)
                                {
                                    var dataAtTick = new SnapshotData.DataAtTick
                                    {
                                        Tick = snapshotData.GetLatestTick(snapshotDataBuffer),
                                        InterpolationFactor = 1,
                                        SnapshotAfter       = latestSnapshot,
                                        SnapshotBefore      = latestSnapshot
                                    };

                                    serializer.CopyFromSnapshot.Ptr.Invoke(
                                        compPtr + serializer.ComponentSize * ent,
                                        (IntPtr)(&dataAtTick), offset);
                                }
                                else
                                {
                                    serializer.RestoreFromBackup.Ptr.Invoke(
                                        compPtr + serializer.ComponentSize * ent,
                                        latestSnapshot + offset);
                                }
                            }

                            offset += serializer.DataSize;
                        }
                    }
                }
            }