public static ZwinderStateManager Create(BinaryReader br, ZwinderStateManagerSettings settings, Func <int, bool> reserveCallback)
        {
            // Initial format had no version number, but I think it's a safe bet no valid file has buffer size 2^56 or more so this should work.
            int version = br.ReadByte();

            var current = ZwinderBuffer.Create(br, settings.Current(), version == 0);
            var recent  = ZwinderBuffer.Create(br, settings.Recent());
            var gaps    = ZwinderBuffer.Create(br, settings.GapFiller());

            if (version == 0)
            {
                settings.AncientStateInterval = br.ReadInt32();
            }

            var ret = new ZwinderStateManager(current, recent, gaps, reserveCallback, settings);

            var ancientCount = br.ReadInt32();

            for (var i = 0; i < ancientCount; i++)
            {
                var key    = br.ReadInt32();
                var length = br.ReadInt32();
                var data   = br.ReadBytes(length);
                ret._reserved.Add(key, data);
            }

            ret.RebuildStateCache();

            return(ret);
        }
예제 #2
0
        public static ZwinderStateManager Create(BinaryReader br, ZwinderStateManagerSettings settings, Func <int, bool> reserveCallback)
        {
            var current = ZwinderBuffer.Create(br);
            var recent  = ZwinderBuffer.Create(br);
            var gaps    = ZwinderBuffer.Create(br);

            var ancientInterval = br.ReadInt32();

            var ret = new ZwinderStateManager(current, recent, gaps, ancientInterval, reserveCallback)
            {
                Settings = settings
            };

            var ancientCount = br.ReadInt32();

            for (var i = 0; i < ancientCount; i++)
            {
                var key    = br.ReadInt32();
                var length = br.ReadInt32();
                var data   = br.ReadBytes(length);
                ret._reserved.Add(key, data);
            }

            ret.RebuildStateCache();

            return(ret);
        }
예제 #3
0
        public static ZwinderStateManager Create(BinaryReader br, ZwinderStateManagerSettings settings)
        {
            var current      = ZwinderBuffer.Create(br);
            var recent       = ZwinderBuffer.Create(br);
            var highPriority = ZwinderBuffer.Create(br);

            var original = br.ReadBytes(br.ReadInt32());

            var ancientInterval = br.ReadInt32();

            var ret = new ZwinderStateManager(current, recent, highPriority, original, ancientInterval)
            {
                Settings = settings
            };

            var ancientCount = br.ReadInt32();

            for (var i = 0; i < ancientCount; i++)
            {
                var key    = br.ReadInt32();
                var length = br.ReadInt32();
                var data   = br.ReadBytes(length);
                ret._ancient.Add(new KeyValuePair <int, byte[]>(key, data));
            }

            return(ret);
        }
예제 #4
0
        public ZwinderStateManager(ZwinderStateManagerSettings settings)
        {
            Settings = settings;

            _current = new ZwinderBuffer(new RewindConfig
            {
                UseCompression    = settings.CurrentUseCompression,
                BufferSize        = settings.CurrentBufferSize,
                TargetFrameLength = settings.CurrentTargetFrameLength
            });
            _recent = new ZwinderBuffer(new RewindConfig
            {
                UseCompression    = settings.RecentUseCompression,
                BufferSize        = settings.RecentBufferSize,
                TargetFrameLength = settings.RecentTargetFrameLength
            });

            _highPriority = new ZwinderBuffer(new RewindConfig
            {
                UseCompression    = settings.PriorityUseCompression,
                BufferSize        = settings.PriorityBufferSize,
                TargetFrameLength = settings.PriorityTargetFrameLength
            });

            _ancientInterval = settings.AncientStateInterval;
            _originalState   = NonState;
        }
예제 #5
0
 private ZwinderStateManager(ZwinderBuffer current, ZwinderBuffer recent, ZwinderBuffer gapFiller, int ancientInterval, Func <int, bool> reserveCallback)
 {
     _current         = current;
     _recent          = recent;
     _gapFiller       = gapFiller;
     _ancientInterval = ancientInterval;
     _reserveCallback = reserveCallback;
 }
예제 #6
0
 private ZwinderStateManager(ZwinderBuffer current, ZwinderBuffer recent, ZwinderBuffer highPriority, byte[] frameZeroState, int ancientInterval)
 {
     _originalState   = (byte[])frameZeroState.Clone();
     _current         = current;
     _recent          = recent;
     _highPriority    = highPriority;
     _ancientInterval = ancientInterval;
 }
        public void Dispose()
        {
            _current?.Dispose();
            _current = null;

            _recent?.Dispose();
            _recent = null;

            _gapFiller?.Dispose();
            _gapFiller = null;
        }
 private ZwinderStateManager(ZwinderBuffer current, ZwinderBuffer recent, ZwinderBuffer gapFiller, Func <int, bool> reserveCallback, ZwinderStateManagerSettings settings)
 {
     _current         = current;
     _recent          = recent;
     _gapFiller       = gapFiller;
     _reserveCallback = reserveCallback;
     Settings         = settings;
     _ancientInterval = settings.AncientStateInterval;
     // init the reserved dictionary
     RebuildReserved();
 }
예제 #9
0
        public void UpdateSettings(ZwinderStateManagerSettings settings, bool keepOldStates = false)
        {
            Settings = settings;

            _current   = UpdateBuffer(_current, settings.Current(), keepOldStates);
            _recent    = UpdateBuffer(_recent, settings.Recent(), keepOldStates);
            _gapFiller = UpdateBuffer(_gapFiller, settings.GapFiller(), keepOldStates);

            if (keepOldStates)
            {
                // For ancients ... lets just make sure we aren't keeping states with a gap below the new interval
                if (settings.AncientStateInterval > _ancientInterval)
                {
                    int        lastReserved   = 0;
                    List <int> framesToRemove = new List <int>();
                    foreach (int f in _reserved.Keys)
                    {
                        if (!_reserveCallback(f) && f - lastReserved < settings.AncientStateInterval)
                        {
                            framesToRemove.Add(f);
                        }
                        else
                        {
                            lastReserved = f;
                        }
                    }
                    foreach (int f in framesToRemove)
                    {
                        if (f != 0)
                        {
                            EvictReserved(f);
                        }
                    }
                }
            }
            else
            {
                List <int> framesToRemove = new List <int>();
                foreach (int f in _reserved.Keys)
                {
                    if (f != 0 && !_reserveCallback(f))
                    {
                        framesToRemove.Add(f);
                    }
                }
                foreach (int f in framesToRemove)
                {
                    EvictReserved(f);
                }
            }

            _ancientInterval = settings.AncientStateInterval;
            RebuildStateCache();
        }
예제 #10
0
        public static ZwinderBuffer Create(BinaryReader reader)
        {
            var size              = reader.ReadInt64();
            var sizeMask          = reader.ReadInt64();
            var targetFrameLength = reader.ReadInt32();
            var useCompression    = reader.ReadBoolean();
            var ret = new ZwinderBuffer(new RewindConfig
            {
                BufferSize        = (int)(size >> 20),
                TargetFrameLength = targetFrameLength,
                UseCompression    = useCompression
            });

            if (ret.Size != size || ret._sizeMask != sizeMask)
            {
                throw new InvalidOperationException("Bad format");
            }
            ret.LoadStateBodyBinary(reader);
            return(ret);
        }
예제 #11
0
        public static ZwinderBuffer Create(BinaryReader reader, RewindConfig rewindConfig, bool hackyV0 = false)
        {
            ZwinderBuffer ret;

            // Initial format had no version number, but I think it's a safe bet no valid file has buffer size 2^56 or more so this should work.
            int version = hackyV0 ? 0 : reader.ReadByte();

            if (version == 0)
            {
                byte[] sizeArr = new byte[8];
                reader.Read(sizeArr, 1, 7);
                var size              = BitConverter.ToInt64(sizeArr, 0);
                var sizeMask          = reader.ReadInt64();
                var targetFrameLength = reader.ReadInt32();
                var useCompression    = reader.ReadBoolean();
                ret = new ZwinderBuffer(new RewindConfig
                {
                    BufferSize             = (int)(size >> 20),
                    UseFixedRewindInterval = false,
                    TargetFrameLength      = targetFrameLength,
                    TargetRewindInterval   = 5,
                    AllowOutOfOrderStates  = false,
                    UseCompression         = useCompression
                });
                if (ret.Size != size || ret._sizeMask != sizeMask)
                {
                    throw new InvalidOperationException("Bad format");
                }
            }
            else if (version == 1)
            {
                ret = new ZwinderBuffer(rewindConfig);
            }
            else
            {
                throw new InvalidOperationException("Bad format");
            }

            ret.LoadStateBodyBinary(reader);
            return(ret);
        }
 private ZwinderBuffer UpdateBuffer(ZwinderBuffer buffer, RewindConfig newConfig, bool keepOldStates)
 {
     if (buffer == null)             // just make a new one, plain and simple
     {
         buffer = new ZwinderBuffer(newConfig);
     }
     else if (!buffer.MatchesSettings(newConfig))             // no need to do anything if these settings are already in use
     {
         if (keepOldStates)
         {
             // force capture all the old states, let the buffer handle decay if they don't all fit
             ZwinderBuffer old = buffer;
             buffer = new ZwinderBuffer(newConfig);
             for (int i = 0; i < old.Count; i++)
             {
                 ZwinderBuffer.StateInformation si = old.GetState(i);
                 // don't allow states that should be reserved to decay here, where we don't attempt re-capture
                 if (_reserveCallback(si.Frame))
                 {
                     AddToReserved(si);
                 }
                 else
                 {
                     buffer.Capture(si.Frame, s => si.GetReadStream().CopyTo(s), null, true);
                 }
             }
             old.Dispose();
         }
         else
         {
             buffer.Dispose();
             buffer = new ZwinderBuffer(newConfig);
         }
     }
     return(buffer);
 }
예제 #13
0
파일: Zwinder.cs 프로젝트: gocha/BizHawk
 public Zwinder(IStatable stateSource, IRewindSettings settings)
 {
     _buffer      = new ZwinderBuffer(settings);
     _stateSource = stateSource;
     Active       = true;
 }
예제 #14
0
 internal StateInformation(ZwinderBuffer parent, int index)
 {
     _index  = index;
     _parent = parent;
 }