/// <summary> /// Produces deltas for all non-acked destroyed entities. /// </summary> private void ProduceDestroyed( IRailController target, IEnumerable <RailEntity> destroyedEntities) { foreach (RailEntity entity in destroyedEntities) { RailViewEntry latest = this.ackedByClient.GetLatest(entity.Id); if (latest.IsValid && (latest.Tick < entity.RemovedTick)) { // Note: Because the removed tick is valid, this should force-create this.destroyedList.Add(entity.ProduceDelta(latest.Tick, target)); } } }
internal void PopulateDeltas( IRailController target, Tick serverTick, RailServerPacket packet, IEnumerable <RailEntity> activeEntities, IEnumerable <RailEntity> destroyedEntities) { this.ProduceScoped(target, serverTick, activeEntities); this.ProduceDestroyed(target, destroyedEntities); packet.Populate(this.activeList, this.frozenList, this.destroyedList); this.destroyedList.Clear(); this.frozenList.Clear(); this.activeList.Clear(); }
/// <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); } } }
internal RailStateDelta ProduceDelta( Tick basisTick, IRailController destination) { RailStateRecord basis = null; if (basisTick.IsValid) { basis = this.outgoingStates.LatestAt(basisTick); } // Flags for special data modes bool includeControllerData = (destination == this.Controller); bool includeImmutableData = (basisTick.IsValid == false); return(RailState.CreateDelta( this.Id, this.StateBase, basis, includeControllerData, includeImmutableData, this.commandAck, this.RemovedTick)); }
protected internal virtual void Invoke(RailRoom room, IRailController sender, RailEntity entity) { }
internal void AssignController(IRailController controller) { this.Controller = controller; this.ClearCommands(); this.deferNotifyControllerChanged = true; }