Esempio n. 1
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var concurrentFreeQueue = freeNetworkIds.AsParallelWriter();

            inputDeps = m_Driver.ScheduleUpdate(inputDeps);
            if (m_DriverListening)
            {
                // Schedule accept job
                var acceptJob = new ConnectionAcceptJob();
                acceptJob.driver        = m_Driver;
                acceptJob.commandBuffer = m_Barrier.CreateCommandBuffer();
                inputDeps = acceptJob.Schedule(inputDeps);

                // Schedule job to assign network ids to new connections
                var assignJob = new AssignNetworkIdJob();
                assignJob.commandBuffer  = m_Barrier.CreateCommandBuffer();
                assignJob.numNetworkId   = numNetworkIds;
                assignJob.freeNetworkIds = freeNetworkIds;
                assignJob.rpcQueue       = rpcQueue;
                assignJob.rpcBuffer      = GetBufferFromEntity <OutgoingRpcDataStreamBufferComponent>();
                inputDeps = assignJob.ScheduleSingle(this, inputDeps);
            }
            else
            {
                freeNetworkIds.Clear();
            }
            // Schedule parallel update job
            var recvJob = new ConnectionReceiveJob();

            recvJob.commandBuffer  = m_Barrier.CreateCommandBuffer().ToConcurrent();
            recvJob.driver         = m_ConcurrentDriver;
            recvJob.freeNetworkIds = concurrentFreeQueue;
            recvJob.networkId      = GetComponentDataFromEntity <NetworkIdComponent>();
            recvJob.rpcBuffer      = GetBufferFromEntity <IncomingRpcDataStreamBufferComponent>();
            recvJob.cmdBuffer      = GetBufferFromEntity <IncomingCommandDataStreamBufferComponent>();
            recvJob.snapshotBuffer = GetBufferFromEntity <IncomingSnapshotDataStreamBufferComponent>();
            recvJob.localTime      = NetworkTimeSystem.TimestampMS;
            // FIXME: because it uses buffer from entity
            var handle = recvJob.ScheduleSingle(this, inputDeps);

            m_Barrier.AddJobHandleForProducer(handle);
            return(handle);
        }
Esempio n. 2
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            m_GhostStatsCollectionSystem.AddDiscardedPackets(m_NetStats[0]);
            m_NetStats[0] = 0;
#endif
            if (!HasSingleton <NetworkProtocolVersion>())
            {
                var entity      = EntityManager.CreateEntity();
                var rpcVersion  = World.GetExistingSystem <RpcSystem>().CalculateVersionHash();
                var gameVersion = HasSingleton <GameProtocolVersion>() ? GetSingleton <GameProtocolVersion>().Version : 0;
                EntityManager.AddComponentData(entity, new NetworkProtocolVersion
                {
                    NetCodeVersion       = NetworkProtocolVersion.k_NetCodeVersion,
                    GameVersion          = gameVersion,
                    RpcCollectionVersion = rpcVersion
                });
            }
            var concurrentFreeQueue = freeNetworkIds.AsParallelWriter();
            inputDeps = m_Driver.ScheduleUpdate(inputDeps);
            if (m_DriverListening)
            {
                // Schedule accept job
                var acceptJob = new ConnectionAcceptJob();
                acceptJob.driver         = m_Driver;
                acceptJob.commandBuffer  = m_Barrier.CreateCommandBuffer();
                acceptJob.numNetworkId   = numNetworkIds;
                acceptJob.freeNetworkIds = freeNetworkIds;
                acceptJob.rpcQueue       = rpcQueue;
                acceptJob.tickRate       = default(ClientServerTickRate);
                if (HasSingleton <ClientServerTickRate>())
                {
                    acceptJob.tickRate = GetSingleton <ClientServerTickRate>();
                }
                acceptJob.tickRate.ResolveDefaults();
                acceptJob.protocolVersion = GetSingleton <NetworkProtocolVersion>();
                inputDeps = acceptJob.Schedule(inputDeps);
            }
            else
            {
                freeNetworkIds.Clear();
            }

            var completeJob = new CompleteConnectionJob
            {
                commandBuffer   = m_Barrier.CreateCommandBuffer().ToConcurrent(),
                protocolVersion = GetSingleton <NetworkProtocolVersion>()
            };
            inputDeps = completeJob.Schedule(this, inputDeps);

            inputDeps = JobHandle.CombineDependencies(inputDeps, LastDriverWriter);
            var disconnectJob = new DisconnectJob
            {
                commandBuffer = m_Barrier.CreateCommandBuffer().ToConcurrent(),
                driver        = m_Driver
            };
            inputDeps = disconnectJob.ScheduleSingle(this, inputDeps);

            // Schedule parallel update job
            var recvJob = new ConnectionReceiveJob();
            recvJob.commandBuffer  = m_Barrier.CreateCommandBuffer().ToConcurrent();
            recvJob.driver         = m_ConcurrentDriver;
            recvJob.freeNetworkIds = concurrentFreeQueue;
            recvJob.networkId      = GetComponentDataFromEntity <NetworkIdComponent>();
            recvJob.rpcBuffer      = GetBufferFromEntity <IncomingRpcDataStreamBufferComponent>();
            recvJob.cmdBuffer      = GetBufferFromEntity <IncomingCommandDataStreamBufferComponent>();
            recvJob.snapshotBuffer = GetBufferFromEntity <IncomingSnapshotDataStreamBufferComponent>();
            recvJob.localTime      = NetworkTimeSystem.TimestampMS;
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            recvJob.netStats = m_NetStats;
#endif
            // FIXME: because it uses buffer from entity
            LastDriverWriter = recvJob.ScheduleSingle(this, inputDeps);
            m_Barrier.AddJobHandleForProducer(LastDriverWriter);
            return(LastDriverWriter);
        }
        protected override void OnUpdate()
        {
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            m_GhostStatsCollectionSystem.AddDiscardedPackets(m_NetStats[0]);
            m_NetStats[0] = 0;
#endif
            var commandBuffer = m_Barrier.CreateCommandBuffer().AsParallelWriter();

            if (!HasSingleton <NetworkProtocolVersion>())
            {
                var entity            = EntityManager.CreateEntity();
                var rpcVersion        = World.GetExistingSystem <RpcSystem>().CalculateVersionHash();
                var componentsVersion = m_GhostCollectionSystem.CalculateComponentCollectionHash();
                var gameVersion       = HasSingleton <GameProtocolVersion>() ? GetSingleton <GameProtocolVersion>().Version : 0;
                EntityManager.AddComponentData(entity, new NetworkProtocolVersion
                {
                    NetCodeVersion             = NetworkProtocolVersion.k_NetCodeVersion,
                    GameVersion                = gameVersion,
                    RpcCollectionVersion       = rpcVersion,
                    ComponentCollectionVersion = componentsVersion
                });
            }
            var concurrentFreeQueue = m_FreeNetworkIds.AsParallelWriter();
            Dependency = m_Driver.ScheduleUpdate(Dependency);
            if (m_DriverListening)
            {
                // Schedule accept job
                var acceptJob = new ConnectionAcceptJob();
                acceptJob.driver          = m_Driver;
                acceptJob.commandBuffer   = m_Barrier.CreateCommandBuffer();
                acceptJob.numNetworkId    = m_NumNetworkIds;
                acceptJob.freeNetworkIds  = m_FreeNetworkIds;
                acceptJob.rpcQueue        = m_RpcQueue;
                acceptJob.ghostFromEntity = GetComponentDataFromEntity <GhostComponent>(true);
                acceptJob.tickRate        = default(ClientServerTickRate);
                if (HasSingleton <ClientServerTickRate>())
                {
                    acceptJob.tickRate = GetSingleton <ClientServerTickRate>();
                }
                acceptJob.tickRate.ResolveDefaults();
                acceptJob.protocolVersion = GetSingleton <NetworkProtocolVersion>();
                Dependency = acceptJob.Schedule(Dependency);
            }
            else
            {
                if (!HasSingleton <ClientServerTickRate>())
                {
                    var newEntity = World.EntityManager.CreateEntity();
                    var tickRate  = new ClientServerTickRate();
                    tickRate.ResolveDefaults();
                    EntityManager.AddComponentData(newEntity, tickRate);
                }
                var tickRateEntity = GetSingletonEntity <ClientServerTickRate>();
                Dependency = Entities
                             .WithNone <NetworkStreamDisconnected>()
                             .ForEach((Entity entity, int entityInQueryIndex, in ClientServerTickRateRefreshRequest req) =>
                {
                    var dataFromEntity = GetComponentDataFromEntity <ClientServerTickRate>();
                    var tickRate       = dataFromEntity[tickRateEntity];
                    tickRate.MaxSimulationStepsPerFrame = req.MaxSimulationStepsPerFrame;
                    tickRate.NetworkTickRate            = req.NetworkTickRate;
                    tickRate.SimulationTickRate         = req.SimulationTickRate;
                    dataFromEntity[tickRateEntity]      = tickRate;
                    commandBuffer.RemoveComponent <ClientServerTickRateRefreshRequest>(entityInQueryIndex, entity);
                }).Schedule(Dependency);
                m_FreeNetworkIds.Clear();
            }

            var protocolVersion = GetSingleton <NetworkProtocolVersion>();
            Entities.WithName("CompleteConnection").WithNone <OutgoingRpcDataStreamBufferComponent>().
            ForEach((Entity entity, int nativeThreadIndex, in NetworkStreamConnection con) =>
            {
                var buf = commandBuffer.AddBuffer <OutgoingRpcDataStreamBufferComponent>(nativeThreadIndex, entity);
                RpcSystem.SendProtocolVersion(buf, protocolVersion);
            }).ScheduleParallel();

            Dependency = JobHandle.CombineDependencies(Dependency, LastDriverWriter);

            var driver = m_Driver;
            Entities.ForEach((Entity entity, int nativeThreadIndex, ref NetworkStreamConnection connection, in NetworkStreamRequestDisconnect disconnect) =>
            {
                driver.Disconnect(connection.Value);
                commandBuffer.AddComponent(nativeThreadIndex, entity, new NetworkStreamDisconnected {
                    Reason = disconnect.Reason
                });
                commandBuffer.RemoveComponent <NetworkStreamRequestDisconnect>(nativeThreadIndex, entity);
            }).Schedule();

            // Schedule parallel update job
            var concurrentDriver = m_ConcurrentDriver;
            var freeNetworkIds   = concurrentFreeQueue;
            var networkId        = GetComponentDataFromEntity <NetworkIdComponent>();
            var rpcBuffer        = GetBufferFromEntity <IncomingRpcDataStreamBufferComponent>();
            var cmdBuffer        = GetBufferFromEntity <IncomingCommandDataStreamBufferComponent>();
            var snapshotBuffer   = GetBufferFromEntity <IncomingSnapshotDataStreamBufferComponent>();
            var localTime        = NetworkTimeSystem.TimestampMS;
#if UNITY_EDITOR || DEVELOPMENT_BUILD
            var netStats = m_NetStats;
#endif
            // FIXME: because it uses buffer from entity
            Entities.WithNone <NetworkStreamDisconnected>().WithReadOnly(networkId).
            ForEach((Entity entity, int nativeThreadIndex, ref NetworkStreamConnection connection,
                     ref NetworkSnapshotAckComponent snapshotAck) =>
            {
                if (!connection.Value.IsCreated)
                {
                    return;
                }
                DataStreamReader reader;
                NetworkEvent.Type evt;
                while ((evt = concurrentDriver.PopEventForConnection(connection.Value, out reader)) !=
                       NetworkEvent.Type.Empty)
                {
                    switch (evt)
                    {
                    case NetworkEvent.Type.Connect:
                        break;

                    case NetworkEvent.Type.Disconnect:
                        // Flag the connection as lost, it will be deleted in a separate system, giving user code one frame to detect and respond to lost connection
                        commandBuffer.AddComponent(nativeThreadIndex, entity, new NetworkStreamDisconnected
                        {
                            Reason = NetworkStreamDisconnectReason.ConnectionClose
                        });
                        rpcBuffer[entity].Clear();
                        cmdBuffer[entity].Clear();
                        connection.Value = default(NetworkConnection);
                        if (networkId.HasComponent(entity))
                        {
                            freeNetworkIds.Enqueue(networkId[entity].Value);
                        }
                        return;

                    case NetworkEvent.Type.Data:
                        // FIXME: do something with the data
                        switch ((NetworkStreamProtocol)reader.ReadByte())
                        {
                        case NetworkStreamProtocol.Command:
                            {
                                var buffer = cmdBuffer[entity];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                                if (buffer.Length > 0)
                                {
                                    netStats[0] = netStats[0] + 1;
                                }
#endif
                                // FIXME: should be handle by a custom command stream system
                                uint snapshot     = reader.ReadUInt();
                                uint snapshotMask = reader.ReadUInt();
                                snapshotAck.UpdateReceivedByRemote(snapshot, snapshotMask);
                                uint remoteTime         = reader.ReadUInt();
                                uint localTimeMinusRTT  = reader.ReadUInt();
                                uint interpolationDelay = reader.ReadUInt();
                                snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime,
                                                             interpolationDelay);

                                buffer.Clear();
                                buffer.Add(ref reader);
                                break;
                            }

                        case NetworkStreamProtocol.Snapshot:
                            {
                                uint remoteTime              = reader.ReadUInt();
                                uint localTimeMinusRTT       = reader.ReadUInt();
                                snapshotAck.ServerCommandAge = reader.ReadInt();
                                snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime, 0);

                                var buffer = snapshotBuffer[entity];
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                                if (buffer.Length > 0)
                                {
                                    netStats[0] = netStats[0] + 1;
                                }
#endif
                                buffer.Clear();
                                buffer.Add(ref reader);
                                break;
                            }

                        case NetworkStreamProtocol.Rpc:
                            {
                                var buffer = rpcBuffer[entity];
                                buffer.Add(ref reader);
                                break;
                            }

                        default:
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            throw new InvalidOperationException("Received unknown message type");
#else
                            break;
#endif
                        }

                        break;

                    default:
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        PrintEventError(evt);
                        throw new InvalidOperationException("Received unknown network event");
#else
                        break;
#endif
                    }
                }
            }).Schedule();
            LastDriverWriter = Dependency;
            m_Barrier.AddJobHandleForProducer(Dependency);
        }