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); } } }
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)); } } }
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)); }