From 354ccd1b232a9ec252e5307c61db766a89687b22 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 23 Aug 2020 20:10:42 -0500 Subject: [PATCH] ZwinderStateManager - when considering evicting from recent to reserved, don't assume the reserved is linear or has all gaps covered. Instead check for "nearby" states. This fixes the problem that any state prior to the first used marker would never get an "ancient" state. Technicalyl this will mean that a state can be _ancientInterval * 2 - 1 frames away from its nearest neighbor, but this should be close enough the desired behavior --- .../movie/tasproj/ZwinderStateManager.cs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs index b4b620b900..6465d9950a 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs @@ -252,12 +252,10 @@ namespace BizHawk.Client.Common var state2 = _recent.GetState(index2); StateCache.Remove(state2.Frame); - var from = _reserved.Count > 0 ? _reserved.Max(kvp => kvp.Key) : 0; - var isReserved = _reserveCallback(state2.Frame); // Add to reserved if reserved, or if it matches an "ancient" state consideration - if (isReserved || state2.Frame - from >= _ancientInterval) + if (isReserved || !HasNearByReserved(state2.Frame)) { AddToReserved(state2); } @@ -266,6 +264,30 @@ namespace BizHawk.Client.Common force); } + // Returns whether or not a frame has a reserved state within the frame interval on either side of it + private bool HasNearByReserved(int frame) + { + // An easy optimization, we know frame 0 always exists + if (frame < _ancientInterval) + { + return true; + } + + // Has nearby before + if (_reserved.Any(kvp => kvp.Key < frame && kvp.Key > frame - _ancientInterval)) + { + return true; + } + + // Has nearby after + if (_reserved.Any(kvp => kvp.Key > frame && kvp.Key < frame + _ancientInterval)) + { + return true; + } + + return false; + } + private void CaptureGap(int frame, IStatable source) { _gapFiller.Capture(