public bool Rewind(int frameToAvoid) { if (!Active || Count == 0) { return(false); } var index = Count - 1; var state = _buffer.GetState(index); if (state.Frame == frameToAvoid) { if (Count > 1) { state = _buffer.GetState(index - 1); } _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); _buffer.InvalidateEnd(index); } else { // The emulator will frame advance without giving us a chance to // re-capture this frame, so we shouldn't invalidate this state just yet. _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); } return(true); }
public void Clear() { _current.InvalidateEnd(0); _recent.InvalidateEnd(0); _highPriority.InvalidateEnd(0); _ancient.Clear(); }
public void Clear() { Sync(); _buffer.InvalidateEnd(0); _count = 0; _masterFrame = -1; }
public void Clear() { _current.InvalidateEnd(0); _recent.InvalidateEnd(0); _gapFiller.InvalidateEnd(0); StateCache.Clear(); AddStateCache(0); _reserved = _reserved .Where(kvp => kvp.Key == 0) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); }
public bool Rewind() { if (!Active || Count == 0) { return(false); } var index = Count - 1; var state = _buffer.GetState(index); _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); _buffer.InvalidateEnd(index); return(true); }
private void CaptureGap(int frame, IStatable source) { // We need to do this here for the following scenario // We are currently far enough in the game that there is a large "ancient interval" section // The user navigates to a frame after ancient interval 2, replay happens and we start filling gaps // Then the user, still without having made an edit, navigates to a frame before ancient interval 2, but after ancient interval 1 // Without this logic, we end up with out of order states // We cannot use InvalidateGaps because that does not address the state cache or check for reserved states. for (int i = _gapFiller.Count - 1; i >= 0; i--) { var lastGap = _gapFiller.GetState(i); if (lastGap.Frame < frame) { break; } if (_reserveCallback(lastGap.Frame)) { AddToReserved(lastGap); } else { StateCache.Remove(lastGap.Frame); } _gapFiller.InvalidateEnd(i); } _gapFiller.Capture( frame, s => { AddStateCache(frame); source.SaveStateBinary(new BinaryWriter(s)); }, index => { var state = _gapFiller.GetState(index); StateCache.Remove(state.Frame); if (_reserveCallback(state.Frame)) { AddToReserved(state); return; } }); }
public bool Rewind(int frameToAvoid) { if (!Active || Count == 0) { return(false); } var index = Count - 1; var state = _buffer.GetState(index); if (state.Frame == frameToAvoid && Count > 1) { // Do not decrement index again. We will "head" this state and not pop it since it will be advanced past // without an opportunity to capture. This is a bit hackish. state = _buffer.GetState(index - 1); } _stateSource.LoadStateBinary(new BinaryReader(state.GetReadStream())); _buffer.InvalidateEnd(index); return(true); }
public void Clear() { Sync(); _buffer.InvalidateEnd(0); }