Beispiel #1
0
        public void Update(TimeSpan frameTime)
        {
            List <object> toRemove = new List <object>();

            foreach (KeyValuePair <ISyncable, Dictionary <object, BufferedData> > fieldBuffer in
                     FieldWatcher.BufferedChanges)
            {
                ISyncable syncable = fieldBuffer.Key;
                foreach (KeyValuePair <object, BufferedData> instanceBuffer in fieldBuffer.Value)
                {
                    object instance = instanceBuffer.Key;
                    if (CheckShouldRemove(syncable, instance, instanceBuffer.Value))
                    {
                        toRemove.Add(instanceBuffer.Key);
                    }
                    else if (!instanceBuffer.Value.Sent)
                    {
                        ISyncable field = fieldBuffer.Key;
                        field.GetSyncHandler(instance)?.Invoke(instanceBuffer.Value.ToSend);
                        field.GetSyncHandler(SyncableInstance.Any)
                        ?.Invoke(instanceBuffer.Value.ToSend);
                        instanceBuffer.Value.Sent = true;
                    }
                }

                toRemove.ForEach(o => fieldBuffer.Value.Remove(o));
                toRemove.Clear();
            }

            m_RailClient.Update();
        }
Beispiel #2
0
        public void Update(TimeSpan frameTime)
        {
            List <object> toRemove = new List <object>();

            foreach (KeyValuePair <ValueAccess, Dictionary <object, ValueChangeRequest> > buffer in
                     FieldChangeBuffer.BufferedChanges)
            {
                ValueAccess access = buffer.Key;
                foreach (KeyValuePair <object, ValueChangeRequest> instanceBuffer in buffer.Value)
                {
                    object instance = instanceBuffer.Key;
                    if (CheckShouldRemove(access, instance, instanceBuffer.Value))
                    {
                        toRemove.Add(instanceBuffer.Key);
                    }
                    else if (!instanceBuffer.Value.RequestProcessed)
                    {
                        access.GetHandler(instance)?.Invoke(instanceBuffer.Value.RequestedValue);
                        instanceBuffer.Value.RequestProcessed = true;
                    }
                }

                toRemove.ForEach(o => buffer.Value.Remove(o));
                toRemove.Clear();
            }

            m_RailClient.Update();
        }
Beispiel #3
0
        private void ClientServerCommunication()
        {
            // Initialization
            CampaignTimeControlMode      expectedTimeControl = CampaignTimeControlMode.StoppablePlay;
            RailClientRoom               clientRoom          = m_Client.StartRoom();
            RailServerRoom               serverRoom          = m_Server.StartRoom();
            RailEntityServer <SomeState> entityServerSide    =
                serverRoom.AddNewEntity <RailEntityServer <SomeState> >();

            entityServerSide.State.Mode = expectedTimeControl;
            m_Server.AddClient(m_PeerServerSide.Object, "");
            m_Client.SetPeer(m_PeerClientSide.Object);
            Assert.Empty(clientRoom.Entities);
            Assert.Single(serverRoom.Entities);

            // Sync entity from server to client
            for (int i = 0; i < RailConfig.SERVER_SEND_RATE + RailConfig.CLIENT_SEND_RATE + 1; ++i)
            {
                m_ConClientSide.ExecuteSends();
                m_Server.Update();
                m_ConServerSide.ExecuteSends();
                m_Client.Update();
            }

            // The client has received the entity.
            Assert.Single(clientRoom.Entities);
            Assert.Single(serverRoom.Entities);

            // Clients representation of the entity is identical to the server
            RailEntityBase entityProxy = clientRoom.Entities.First();

            Assert.IsType <RailEntityClient <SomeState> >(entityProxy);
            RailEntityClient <SomeState> entityClientSide =
                entityProxy as RailEntityClient <SomeState>;

            Assert.NotNull(entityClientSide);
            Assert.Equal(entityServerSide.Id, entityProxy.Id);
            Assert.Equal(expectedTimeControl, entityServerSide.State.Mode);
            Assert.Equal(expectedTimeControl, entityClientSide.State.Mode);

            // Change the entity on server side and sync to the client
            expectedTimeControl         = CampaignTimeControlMode.Stop;
            entityServerSide.State.Mode = expectedTimeControl;

            // Let the server detect the change and send the packet
            bool bWasSendTick = false;

            while (!bWasSendTick)
            {
                m_Server.Update();
                bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE);
            }

            // Let the client receive & process the packet. We need to bring the client up to the same tick as the server to see the result.
            while (clientRoom.Tick < serverRoom.Tick)
            {
                m_ConServerSide.ExecuteSends();
                m_Client.Update();
            }

            Assert.Equal(expectedTimeControl, entityServerSide.State.Mode);
            Assert.Equal(expectedTimeControl, entityClientSide.State.Mode);
        }
Beispiel #4
0
        private void EntitiesAreSynchronized()
        {
            // Initialization
            RailClientRoom clientRoom       = client.StartRoom();
            RailServerRoom serverRoom       = server.StartRoom();
            EntityServer   entityServerSide = serverRoom.AddNewEntity <EntityServer>();

            server.AddClient(peerServerSide.Object, "");
            client.SetPeer(peerClientSide.Object);

            // Nothing has been sent or received yet
            peerClientSide.Verify(
                c => c.SendPayload(It.IsAny <ArraySegment <byte> >()),
                Times.Never());
            peerServerSide.Verify(
                c => c.SendPayload(It.IsAny <ArraySegment <byte> >()),
                Times.Never());
            Assert.Empty(clientRoom.Entities);
            Assert.Single(serverRoom.Entities);

            // Let the server send its update to the client
            for (int i = 0; i < RailConfig.SERVER_SEND_RATE + RailConfig.CLIENT_SEND_RATE + 1; ++i)
            {
                peerServerSide.Object.PollEvents();
                server.Update();
                peerClientSide.Object.PollEvents();
                client.Update();
            }

            // The client has received the server entity.
            Assert.Single(clientRoom.Entities);
            Assert.Single(serverRoom.Entities);

            // Clients representation of the entity is identical to the server
            RailEntityBase entityProxy = clientRoom.Entities.First();

            Assert.IsType <EntityClient>(entityProxy);
            EntityClient entityClientSide = entityProxy as EntityClient;

            Assert.NotNull(entityClientSide);
            Assert.Equal(entityServerSide.Id, entityProxy.Id);
            Assert.Equal(entityClientSide.State.PosX, entityServerSide.State.PosX);
            Assert.Equal(entityClientSide.State.PosY, entityServerSide.State.PosY);

            // Change the entity on the server side and sync it to the client
            float fExpectedPosX = 42;
            float fExpectedPosY = 106;

            entityServerSide.State.PosX = fExpectedPosX;
            entityServerSide.State.PosY = fExpectedPosY;

            // Let the server detect the change and send the packet
            server.Update();
            bool bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE);

            while (!bWasSendTick)
            {
                server.Update();
                bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE);
            }

            // Let the client receive & process the packet. We need to bring the client up to the same tick as the server to see the result.
            while (clientRoom.Tick < serverRoom.Tick)
            {
                peerClientSide.Object.PollEvents();
                client.Update();
            }

            Assert.Equal(fExpectedPosX, entityClientSide.State.PosX);
            Assert.Equal(fExpectedPosY, entityClientSide.State.PosY);
            Assert.Equal(fExpectedPosX, entityServerSide.State.PosX);
            Assert.Equal(fExpectedPosY, entityServerSide.State.PosY);
        }