Example #1
0
    public unsafe int Serialize(int serializer, ArchetypeChunk chunk, int startIndex, uint currentTick,
                                Entity *currentSnapshotEntity, void *currentSnapshotData,
                                GhostSystemStateComponent *ghosts, NativeArray <Entity> ghostEntities,
                                NativeArray <int> baselinePerEntity, NativeList <SnapshotBaseline> availableBaselines,
                                DataStreamWriter dataStream, NetworkCompressionModel compressionModel)
    {
        switch (serializer)
        {
        case 0:
        {
            return(GhostSendSystem <GhostSerializerCollection> .InvokeSerialize(m_CubeGhostSerializer, serializer,
                                                                                chunk, startIndex, currentTick, currentSnapshotEntity, (CubeSnapshotData *)currentSnapshotData,
                                                                                ghosts, ghostEntities, baselinePerEntity, availableBaselines,
                                                                                dataStream, compressionModel));
        }

        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
Example #2
0
        public static unsafe int InvokeSerialize <TSerializer, TSnapshotData>(TSerializer serializer, int ghostType, ArchetypeChunk chunk, int startIndex, uint currentTick,
                                                                              Entity *currentSnapshotEntity, TSnapshotData *currentSnapshotData,
                                                                              GhostSystemStateComponent *ghosts, NativeArray <Entity> ghostEntities,
                                                                              NativeArray <int> baselinePerEntity, NativeList <SnapshotBaseline> availableBaselines,
                                                                              DataStreamWriter dataStream, NetworkCompressionModel compressionModel)
            where TSnapshotData : unmanaged, ISnapshotData <TSnapshotData>
            where TSerializer : struct, IGhostSerializer <TSnapshotData>
        {
            int ent;
            int sameBaselineCount = 0;

            for (ent = startIndex; ent < chunk.Count && dataStream.Length < TargetPacketSize; ++ent)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (ghosts[ent].ghostTypeIndex != ghostType)
                {
                    // FIXME: what needs to happen to support this case? Should it be treated as a respawn?
                    throw new InvalidOperationException("A ghost changed type, ghost must keep the same serializer type throughout their lifetime");
                }
#endif

                int baseline0 = baselinePerEntity[ent * 3];
                int baseline1 = baselinePerEntity[ent * 3 + 1];
                int baseline2 = baselinePerEntity[ent * 3 + 2];
                if (sameBaselineCount == 0)
                {
                    // Count how many entities will use the same baselines as this one, send baselines + count
                    uint baselineTick0 = currentTick;
                    uint baselineTick1 = currentTick;
                    uint baselineTick2 = currentTick;
                    if (baseline0 >= 0)
                    {
                        baselineTick0 = availableBaselines[baseline0].tick;
                    }
                    if (baseline1 >= 0)
                    {
                        baselineTick1 = availableBaselines[baseline1].tick;
                    }
                    if (baseline2 >= 0)
                    {
                        baselineTick2 = availableBaselines[baseline2].tick;
                    }
                    for (sameBaselineCount = 1; ent + sameBaselineCount < chunk.Count; ++sameBaselineCount)
                    {
                        if (baselinePerEntity[(ent + sameBaselineCount) * 3] != baseline0 ||
                            baselinePerEntity[(ent + sameBaselineCount) * 3 + 1] != baseline1 ||
                            baselinePerEntity[(ent + sameBaselineCount) * 3 + 2] != baseline2)
                        {
                            break;
                        }
                    }

                    uint baseDiff0 = currentTick - baselineTick0;
                    uint baseDiff1 = currentTick - baselineTick1;
                    uint baseDiff2 = currentTick - baselineTick2;
                    dataStream.WritePackedUInt(baseDiff0, compressionModel);
                    dataStream.WritePackedUInt(baseDiff1, compressionModel);
                    dataStream.WritePackedUInt(baseDiff2, compressionModel);
                    dataStream.WritePackedUInt((uint)sameBaselineCount, compressionModel);
                }

                --sameBaselineCount;
                TSnapshotData *baselineSnapshotData0 = null;
                if (baseline0 >= 0)
                {
                    baselineSnapshotData0 = ((TSnapshotData *)availableBaselines[baseline0].snapshot) + ent;
                }
                TSnapshotData *baselineSnapshotData1 = null;
                TSnapshotData *baselineSnapshotData2 = null;
                if (baseline2 >= 0)
                {
                    baselineSnapshotData1 = ((TSnapshotData *)availableBaselines[baseline1].snapshot) + ent;
                    baselineSnapshotData2 = ((TSnapshotData *)availableBaselines[baseline2].snapshot) + ent;
                }


                dataStream.WritePackedUInt((uint)ghosts[ent].ghostId, compressionModel);

                TSnapshotData *snapshot;
                var            snapshotData = default(TSnapshotData);
                if (currentSnapshotData == null)
                {
                    snapshot = &snapshotData;
                }
                else
                {
                    snapshot = currentSnapshotData + ent;
                }
                serializer.CopyToSnapshot(chunk, ent, currentTick, ref *snapshot);
                var            baselineData = default(TSnapshotData);
                TSnapshotData *baseline     = &baselineData;
                if (baselineSnapshotData2 != null)
                {
                    baselineData = *baselineSnapshotData0;
                    baselineData.PredictDelta(currentTick, ref *baselineSnapshotData1, ref *baselineSnapshotData2);
                }
                else if (baselineSnapshotData0 != null)
                {
                    baseline = baselineSnapshotData0;
                }

                snapshot->Serialize(ref *baseline, dataStream, compressionModel);

                if (currentSnapshotData != null)
                {
                    currentSnapshotEntity[ent] = ghostEntities[ent];
                }
            }

            return(ent);
        }