예제 #1
0
        private void ProduceScoped(Tick serverTick, IEnumerable <RailEntityServer> activeEntities)
        {
            // TODO: should be doable without the copy using a LINQ expression.
            entryList.Clear();

            foreach (RailEntityServer entity in activeEntities)
            {
                if (entity.IsRemoving)
                {
                }
                // Controlled entities are always in scope to their controller
                else if (entity.Controller == owner)
                {
                    entryList.Add(new KeyValuePair <float, RailEntityBase>(float.MinValue, entity));
                }
                else if (GetPriority(entity, serverTick, out float priority))
                {
                    entryList.Add(new KeyValuePair <float, RailEntityBase>(priority, entity));
                }
                else if (RailEntityBase.CanFreeze)
                {
                    // We only want to send a freeze state if we aren't already frozen
                    RailViewEntry latest = ackedByClient.GetLatest(entity.Id);
                    if (latest.IsFrozen == false)
                    {
                        frozenList.Add(
                            RailStateDelta.CreateFrozen(stateCreator, serverTick, entity.Id));
                    }
                }
            }

            entryList.Sort(priorityComparer);
            foreach (KeyValuePair <float, RailEntityBase> entry in entryList)
            {
                RailViewEntry    latest = ackedByClient.GetLatest(entry.Value.Id);
                RailEntityServer entity = entry.Value as RailEntityServer;

                // Force a complete update if the entity is frozen so it unfreezes
                // TODO: Currently if we're unfreezing we force the server to send a
                //       delta with the FULL mutable dataset. There is probably a
                //       less wasteful option, like having clients send back
                //       what tick they last received a non-frozen packetToClient on.
                //       However, this would cause some tedious tick comparison.
                //       Should investigate a smarter way to handle this later.
                RailStateDelta delta = entity.ProduceDelta(
                    stateCreator,
                    latest.LastReceivedTick,
                    owner,
                    latest.IsFrozen);

                if (delta != null)
                {
                    activeList.Add(delta);
                }
            }
        }
예제 #2
0
        private void ProduceRemoved(
            RailController target,
            IEnumerable <RailEntityServer> removedEntities)
        {
            foreach (RailEntityServer entity in removedEntities)
            {
                RailViewEntry latest = ackedByClient.GetLatest(entity.Id);

                // Note: Because the removed tick is valid, this should force-create
                if (latest.IsValid && latest.LastReceivedTick < entity.RemovedTick)
                {
                    removedList.Add(
                        entity.ProduceDelta(stateCreator, latest.LastReceivedTick, target, false));
                }
            }
        }
예제 #3
0
        private bool GetPriority(RailEntityBase entity, Tick current, out float priority)
        {
            RailViewEntry lastSent  = this.lastSent.GetLatest(entity.Id);
            RailViewEntry lastAcked = ackedByClient.GetLatest(entity.Id);

            int ticksSinceSend = int.MaxValue;
            int ticksSinceAck  = int.MaxValue;

            if (lastSent.IsValid)
            {
                ticksSinceSend = current - lastSent.LastReceivedTick;
            }
            if (lastAcked.IsValid)
            {
                ticksSinceAck = current - lastAcked.LastReceivedTick;
            }

            return(EvaluateEntity(entity, ticksSinceSend, ticksSinceAck, out priority));
        }