Example #1
0
        public void RequestControlUpdate(RailEntityClient entity, RailStateDelta delta)
        {
            // Can't infer anything if the delta is an empty frozen update
            if (delta.IsFrozen)
            {
                return;
            }

            if (delta.IsRemoving)
            {
                if (entity.Controller != null)
                {
                    localPeer.RevokeControlInternal(entity);
                }
            }
            else if (delta.HasControllerData)
            {
                if (entity.Controller == null)
                {
                    localPeer.GrantControlInternal(entity);
                }
            }
            else
            {
                if (entity.Controller != null)
                {
                    localPeer.RevokeControlInternal(entity);
                }
            }
        }
Example #2
0
        public static RailCommandUpdate Create(
            IRailCommandConstruction commandCreator,
            RailEntityClient entity,
            IEnumerable <RailCommand> commands)
        {
            RailCommandUpdate update = commandCreator.CreateCommandUpdate();

            update.Initialize(entity.Id, commands);
            update.Entity = entity;
            return(update);
        }
Example #3
0
        /// <summary>
        ///     Updates the room a number of ticks. If we have entities waiting to be
        ///     added, this function will check them and add them if applicable.
        /// </summary>
        public void ClientUpdate(Tick localTick, Tick estimatedServerTick)
        {
            Tick = estimatedServerTick;
            UpdatePendingEntities(estimatedServerTick);
            OnPreRoomUpdate(Tick);

            // Collect the entities in the priority order and
            // separate them out for either update or removal
            foreach (RailEntityBase railEntityBase in Entities)
            {
                RailEntityClient entity = (RailEntityClient)railEntityBase;
                if (entity.ShouldRemove)
                {
                    ToRemove.Add(entity);
                }
                else
                {
                    ToUpdate.Add(entity);
                }
            }

            // Wave 0: Remove all sunsetted entities
            ToRemove.ForEach(RemoveEntity);

            // Wave 1: Start/initialize all entities
            ToUpdate.ForEach(e => e.PreUpdate());

            // Wave 2: Update all entities
            ToUpdate.ForEach(e => e.ClientUpdate(localTick));

            // Wave 3: Post-update all entities
            ToUpdate.ForEach(e => e.PostUpdate());

            ToRemove.Clear();
            ToUpdate.Clear();
            OnPostRoomUpdate(Tick);
        }
Example #4
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);
        }