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 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;
                        }
                    }
                }
            }