internal void ReceiveDelta(RailStateDelta delta) { bool stored = false; if (delta.IsFrozen) { // Frozen deltas have no state data, so we need to treat them // separately when doing checks based on state content stored = this.incomingStates.Store(delta); } else { if (delta.IsDestroyed) { this.RemovedTick = delta.RemovedTick; } else { stored = this.incomingStates.Store(delta); } if (delta.HasControllerData) { this.CleanCommands(delta.CommandAck); } } // We never stored it, so free the delta if (stored == false) { RailPool.Free(delta); } }
/// <summary> /// Divides the active entities into those that are in scope and those /// out of scope. If an entity is out of scope and hasn't been acked as /// such by the client, we will add it to the outgoing frozen delta list. /// Otherwise, if an entity is in scope we will add it to the sorted /// active delta list. /// </summary> private void ProduceScoped( IRailController target, Tick serverTick, IEnumerable <RailEntity> activeEntities) { this.entryList.Clear(); float priority; foreach (RailEntity entity in activeEntities) { // Controlled entities are always in scope with highest priority if (entity.Controller == target) { this.entryList.Add( new KeyValuePair <float, RailEntity>(float.MinValue, entity)); } else if (this.GetPriority(entity, serverTick, out priority)) { this.entryList.Add( new KeyValuePair <float, RailEntity>(priority, entity)); } else { // We only want to send a freeze state if we aren't already frozen RailViewEntry latest = this.ackedByClient.GetLatest(entity.Id); if (latest.IsFrozen == false) { this.frozenList.Add( RailStateDelta.CreateFrozen(serverTick, entity.Id)); } } } this.entryList.Sort(RailScope.Comparer); foreach (KeyValuePair <float, RailEntity> entry in this.entryList) { RailViewEntry latest = this.ackedByClient.GetLatest(entry.Value.Id); RailStateDelta delta = entry.Value.ProduceDelta(latest.Tick, target); if (delta != null) { this.activeList.Add(delta); } } }
private void ProcessDelta(RailStateDelta delta) { RailEntity entity; if (this.knownEntities.TryGetValue(delta.EntityId, out entity) == false) { RailDebug.Assert(delta.IsFrozen == false, "Frozen unknown entity"); if (delta.IsFrozen) { return; } entity = delta.ProduceEntity(); entity.AssignId(delta.EntityId); this.pendingEntities.Add(entity.Id, entity); this.knownEntities.Add(entity.Id, entity); } entity.ReceiveDelta(delta); this.UpdateControlStatus(entity, delta); }
private void UpdateControlStatus(RailEntity entity, RailStateDelta delta) { // Can't infer anything if the delta is an empty frozen update if (delta.IsFrozen) { return; } if (delta.HasControllerData) { if (entity.Controller == null) { this.serverPeer.GrantControl(entity); } } else { if (entity.Controller != null) { this.serverPeer.RevokeControl(entity); } } }