diff --git a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs index c44ffac2ba..31cb2ce487 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs @@ -437,7 +437,7 @@ namespace BizHawk.Client.Common else StateCache.Remove(lastGap.Frame); - _gapFiller.InvalidateEnd(i); + _gapFiller.InvalidateLast(); } _gapFiller.Capture( @@ -461,9 +461,9 @@ namespace BizHawk.Client.Common public void Clear() { - _current.InvalidateEnd(0); - _recent.InvalidateEnd(0); - _gapFiller.InvalidateEnd(0); + _current.InvalidateAfter(-1); + _recent.InvalidateAfter(-1); + _gapFiller.InvalidateAfter(-1); StateCache.Clear(); AddStateCache(0); _reserved = _reserved.Where(static kvp => kvp.Key is 0).ToDictionary(); //TODO clone needed? @@ -485,39 +485,18 @@ namespace BizHawk.Client.Common private bool InvalidateGaps(int frame) { - for (var i = 0; i < _gapFiller.Count; i++) - { - var state = _gapFiller.GetState(i); - if (state.Frame > frame) - { - _gapFiller.InvalidateEnd(i); - return true; - } - } - return false; + return _gapFiller.InvalidateAfter(frame); } private bool InvalidateNormal(int frame) { - for (var i = 0; i < _recent.Count; i++) + if (_recent.InvalidateAfter(frame)) { - if (_recent.GetState(i).Frame > frame) - { - _recent.InvalidateEnd(i); - _current.InvalidateEnd(0); - return true; - } + _current.InvalidateAfter(-1); + return true; } - for (var i = 0; i < _current.Count; i++) - { - if (_current.GetState(i).Frame > frame) - { - _current.InvalidateEnd(i); - return true; - } - } - return false; + return _current.InvalidateAfter(frame); } private bool InvalidateReserved(int frame) diff --git a/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs b/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs index d1cc265339..ebe35d80b8 100644 --- a/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs +++ b/src/BizHawk.Client.Common/rewind/ZeldaWinder.cs @@ -84,7 +84,7 @@ namespace BizHawk.Client.Common public void Clear() { Sync(); - _buffer.InvalidateEnd(0); + _buffer.InvalidateAfter(-1); _count = 0; _masterFrame = -1; } @@ -236,7 +236,7 @@ namespace BizHawk.Client.Common { var index = _buffer.Count - 1; RefillMaster(_buffer.GetState(index)); - _buffer.InvalidateEnd(index); + _buffer.InvalidateLast(); _stateSource.LoadStateBinary(new BinaryReader(new MemoryStream(_master, 0, _masterLength, false))); } else diff --git a/src/BizHawk.Client.Common/rewind/Zwinder.cs b/src/BizHawk.Client.Common/rewind/Zwinder.cs index 056bd60dcc..bbf7afb330 100644 --- a/src/BizHawk.Client.Common/rewind/Zwinder.cs +++ b/src/BizHawk.Client.Common/rewind/Zwinder.cs @@ -74,7 +74,7 @@ namespace BizHawk.Client.Common } using var br = new BinaryReader(state.GetReadStream()); _stateSource.LoadStateBinary(br); - _buffer.InvalidateEnd(index); + _buffer.InvalidateLast(); } else { @@ -103,7 +103,7 @@ namespace BizHawk.Client.Common public void Clear() { - _buffer.InvalidateEnd(0); + _buffer.InvalidateAfter(-1); } } } diff --git a/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs b/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs index dacfcf72b5..79d9b2fe1c 100644 --- a/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs +++ b/src/BizHawk.Client.Common/rewind/ZwinderBuffer.cs @@ -284,18 +284,33 @@ namespace BizHawk.Client.Common } /// - /// Invalidate states from GetState(index) on to the end of the buffer, so that Count == index afterwards + /// Invalidate all states with frame number > frame. + /// True iff any state was invalidated, else false /// - public void InvalidateEnd(int index) + public bool InvalidateAfter(int frame) { - if ((uint) index > (uint) Count) // intentionally allows index == Count (e.g. clearing an empty buffer) + for (int i = _firstStateIndex; i != _nextStateIndex; i = (i + 1) & STATEMASK) { - throw new ArgumentOutOfRangeException(paramName: nameof(index), index, message: "index out of range"); + if (_states[i].Frame > frame) + { + _nextStateIndex = (i + _firstStateIndex) & STATEMASK; + return true; + } } - _nextStateIndex = (index + _firstStateIndex) & STATEMASK; + + return false; //Util.DebugWriteLine($"Size: {Size >> 20}MiB, Used: {Used >> 20}MiB, States: {Count}"); } + /// + /// Invalidates the last state in the buffer + /// + public void InvalidateLast() + { + if (Count != 0) + _nextStateIndex = (_nextStateIndex - 1) & STATEMASK; + } + public void SaveStateBinary(BinaryWriter writer) { // version number