/// <summary> /// Stores a value. Will not replace a stored value with an older one. /// </summary> public bool Store(T value) { int index = this.TickToIndex(value.Tick); bool store = false; if (this.latestIdx < 0) { store = true; } else { T latest = this.data[this.latestIdx]; if (value.Tick >= latest.Tick) { store = true; } } if (store) { RailPool.SafeReplace(ref this.data[index], value); this.latestIdx = index; } return(store); }
private void ProcessCommandUpdate( RailServerPeer peer, RailCommandUpdate update) { RailEntity entity; if (this.Room.TryGet(update.EntityId, out entity)) { if (entity.Controller == peer) { foreach (RailCommand command in update.Commands) { entity.ReceiveCommand(command); } } else { // Can't send commands to that entity, so dump them foreach (RailCommand command in update.Commands) { RailPool.Free(command); } } } }
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> /// Removes any acked or expired outgoing events. /// </summary> private void CleanOutgoingEvents( SequenceId ackedEventId) { if (ackedEventId.IsValid == false) { return; } while (this.outgoingEvents.Count > 0) { RailEvent top = this.outgoingEvents.Peek(); // Stop if we hit an un-acked reliable event if (top.IsReliable) { if (top.EventId > ackedEventId) { break; } } // Stop if we hit an unreliable event with remaining attempts else { if (top.Attempts > 0) { break; } } RailPool.Free(this.outgoingEvents.Dequeue()); } }
private void Reset() { this.Room = null; this.Id = EntityId.INVALID; this.Controller = null; this.hasStarted = false; // We always notify a controller change at start this.deferNotifyControllerChanged = true; #if SERVER this.IsFrozen = false; // Entities never freeze on server this.outgoingStates.Clear(); this.incomingCommands.Clear(); #endif #if CLIENT this.LastSentCommandTick = Tick.START; this.IsFrozen = true; // Entities start frozen on client this.shouldBeFrozen = true; this.incomingStates.Clear(); RailPool.DrainQueue(this.outgoingCommands); this.authTick = Tick.START; this.nextTick = Tick.INVALID; #endif this.ResetStates(); this.OnReset(); }
/// <summary> /// Clears the buffer, freeing all contents. /// </summary> public void Clear() { for (int i = 0; i < this.data.Length; i++) { RailPool.SafeReplace(ref this.data[i], null); } this.latestIdx = -1; }
public static void DrainQueue <T>(Queue <T> queue) where T : IRailPoolable <T> { while (queue.Count > 0) { RailPool.Free(queue.Dequeue()); } }
public static void SafeReplace <T>(ref T destination, T obj) where T : IRailPoolable <T> { if (destination != null) { RailPool.Free(destination); } destination = obj; }
/// <summary> /// Clears the buffer, freeing all contents. /// </summary> public void Clear() { foreach (T val in this.data) { RailPool.Free(val); } this.data.Clear(); this.Latest = null; }
public void Store(T val) { if (this.data.Count >= this.capacity) { RailPool.Free(this.data.Dequeue()); } this.data.Enqueue(val); this.Latest = val; }
internal void ReceiveCommand(RailCommand command) { if (this.incomingCommands.Store(command)) { command.IsNewCommand = true; } else { RailPool.Free(command); } }
public void Clear() { #if CLIENT // We don't free the received values as they will be passed elsewhere this.received.Clear(); #endif #if SERVER // Everything in sent is also in pending, so only free pending foreach (T value in this.pending) { RailPool.Free(value); } this.pending.Clear(); this.sent.Clear(); #endif }
private void CleanCommands(Tick ackTick) { if (ackTick.IsValid == false) { return; } while (this.outgoingCommands.Count > 0) { RailCommand command = this.outgoingCommands.Peek(); if (command.ClientTick > ackTick) { break; } RailPool.Free(this.outgoingCommands.Dequeue()); } }
private void ResetStates() { if (this.StateBase != null) { RailPool.Free(this.StateBase); } #if CLIENT if (this.AuthStateBase != null) { RailPool.Free(this.AuthStateBase); } if (this.NextStateBase != null) { RailPool.Free(this.NextStateBase); } #endif this.StateBase = null; #if CLIENT this.AuthStateBase = null; this.NextStateBase = null; #endif }