From fdabc5ed1343bf9402af28dfafed3b9d6e9ddea8 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Fri, 16 Aug 2024 22:49:00 +1000 Subject: [PATCH] (guess) Merge `IMiniWatchDetails` and `IMiniWatch` --- .../tools/RamSearchEngine/Extensions.cs | 27 +-- .../tools/RamSearchEngine/IMiniWatch.cs | 154 +++++++++------ .../RamSearchEngine/IMiniWatchDetails.cs | 183 ------------------ .../tools/RamSearchEngine/RamSearchEngine.cs | 83 ++------ .../tools/Watch/RamSearch.cs | 5 - 5 files changed, 118 insertions(+), 334 deletions(-) delete mode 100644 src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/Extensions.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/Extensions.cs index 14ff056127..d4b1f38159 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/Extensions.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/Extensions.cs @@ -7,36 +7,21 @@ namespace BizHawk.Client.Common.RamSearchEngine internal static class Extensions { public static IEnumerable ToBytes(this IEnumerable addresses, SearchEngineSettings settings) - => settings.IsDetailed() - ? addresses.ToDetailedBytes(settings.Domain) - : addresses.ToBytes(settings.Domain); + => addresses.ToDetailedBytes(settings.Domain); public static IEnumerable ToWords(this IEnumerable addresses, SearchEngineSettings settings) - => settings.IsDetailed() - ? addresses.ToDetailedWords(settings.Domain, settings.BigEndian) - : addresses.ToWords(settings.Domain, settings.BigEndian); + => addresses.ToDetailedWords(settings.Domain, settings.BigEndian); public static IEnumerable ToDWords(this IEnumerable addresses, SearchEngineSettings settings) - => settings.IsDetailed() - ? addresses.ToDetailedDWords(settings.Domain, settings.BigEndian) - : addresses.ToDWords(settings.Domain, settings.BigEndian); - - private static IEnumerable ToBytes(this IEnumerable addresses, MemoryDomain domain) - => addresses.Select(a => new MiniByteWatch(domain, a)); + => addresses.ToDetailedDWords(settings.Domain, settings.BigEndian); private static IEnumerable ToDetailedBytes(this IEnumerable addresses, MemoryDomain domain) - => addresses.Select(a => new MiniByteWatchDetailed(domain, a)); - - private static IEnumerable ToWords(this IEnumerable addresses, MemoryDomain domain, bool bigEndian) - => addresses.Select(a => new MiniWordWatch(domain, a, bigEndian)); + => addresses.Select(a => new MiniByteWatch(domain, a)); private static IEnumerable ToDetailedWords(this IEnumerable addresses, MemoryDomain domain, bool bigEndian) - => addresses.Select(a => new MiniWordWatchDetailed(domain, a, bigEndian)); - - private static IEnumerable ToDWords(this IEnumerable addresses, MemoryDomain domain, bool bigEndian) - => addresses.Select(a => new MiniDWordWatch(domain, a, bigEndian)); + => addresses.Select(a => new MiniWordWatch(domain, a, bigEndian)); private static IEnumerable ToDetailedDWords(this IEnumerable addresses, MemoryDomain domain, bool bigEndian) - => addresses.Select(a => new MiniDWordWatchDetailed(domain, a, bigEndian)); + => addresses.Select(a => new MiniDWordWatch(domain, a, bigEndian)); } } diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs index 1bd7b86966..33a37a2c93 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs @@ -4,130 +4,172 @@ namespace BizHawk.Client.Common.RamSearchEngine { /// /// Represents a Ram address for watching in the - /// With the minimal details necessary for searching /// internal interface IMiniWatch { long Address { get; } long Previous { get; } // do not store sign extended variables in here. - void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian); + long Current { get; } + int ChangeCount { get; } + void ClearChangeCount(); + void SetPreviousToCurrent(); bool IsValid(MemoryDomain domain); + void Update(PreviousType type, MemoryDomain domain, bool bigEndian); } internal sealed class MiniByteWatch : IMiniWatch { public long Address { get; } + private byte _previous; + private byte _current; public MiniByteWatch(MemoryDomain domain, long addr) { Address = addr; - _previous = GetByte(Address, domain); + _previous = _current = GetByte(domain); + } + + public void SetPreviousToCurrent() + { + _previous = _current; } public long Previous => _previous; + public long Current => _current; - public bool IsValid(MemoryDomain domain) - { - return IsValid(Address, domain); - } + public int ChangeCount { get; private set; } - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) + public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - _previous = GetByte(Address, domain); - } + var newValue = GetByte(domain); - public static bool IsValid(long address, MemoryDomain domain) - { - return address < domain.Size; - } - - public static byte GetByte(long address, MemoryDomain domain) - { - if (!IsValid(address, domain)) + if (newValue != _current) { - return 0; + ChangeCount++; + if (type == PreviousType.LastChange) + { + _previous = _current; + } } - return domain.PeekByte(address); + if (type == PreviousType.LastFrame) + _previous = _current; + + _current = newValue; + } + + public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) => Address < domain.Size; + + public byte GetByte(MemoryDomain domain) + { + return IsValid(domain) ? domain.PeekByte(Address) : (byte)0; } } internal sealed class MiniWordWatch : IMiniWatch { public long Address { get; } + private ushort _previous; + private ushort _current; public MiniWordWatch(MemoryDomain domain, long addr, bool bigEndian) { Address = addr; - _previous = GetUshort(Address, domain, bigEndian); + _previous = _current = GetUshort(domain, bigEndian); + } + + public void SetPreviousToCurrent() + { + _previous = _current; } public long Previous => _previous; + public long Current => _current; - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) - { - _previous = GetUshort(Address, domain, bigEndian); - } + public int ChangeCount { get; private set; } - public bool IsValid(MemoryDomain domain) + public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - return IsValid(Address, domain); - } + var newValue = GetUshort(domain, bigEndian); - public static bool IsValid(long address, MemoryDomain domain) - { - return address < (domain.Size - 1); - } - - public static ushort GetUshort(long address, MemoryDomain domain, bool bigEndian) - { - if (!IsValid(address, domain)) + if (newValue != _current) { - return 0; + ChangeCount++; + if (type == PreviousType.LastChange) + { + _previous = _current; + } } - return domain.PeekUshort(address, bigEndian); + if (type == PreviousType.LastFrame) + _previous = _current; + + _current = newValue; + } + + public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) => Address < domain.Size - 1; + + private ushort GetUshort(MemoryDomain domain, bool bigEndian) + { + return IsValid(domain) ? domain.PeekUshort(Address, bigEndian) : (ushort)0; } } internal sealed class MiniDWordWatch : IMiniWatch { public long Address { get; } + private uint _previous; + private uint _current; public MiniDWordWatch(MemoryDomain domain, long addr, bool bigEndian) { Address = addr; - _previous = GetUint(Address, domain, bigEndian); + _previous = _current = GetUint(domain, bigEndian); + } + + public void SetPreviousToCurrent() + { + _previous = _current; } public long Previous => _previous; + public long Current => _current; - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) - { - _previous = GetUint(Address, domain, bigEndian); - } + public int ChangeCount { get; private set; } - public bool IsValid(MemoryDomain domain) + public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - return IsValid(Address, domain); - } + var newValue = GetUint(domain, bigEndian); - public static bool IsValid(long address, MemoryDomain domain) - { - return address < (domain.Size - 3); - } - - public static uint GetUint(long address, MemoryDomain domain, bool bigEndian) - { - if (!IsValid(address, domain)) + if (newValue != _current) { - return 0; + ChangeCount++; + if (type == PreviousType.LastChange) + { + _previous = _current; + } } - return domain.PeekUint(address, bigEndian); + if (type == PreviousType.LastFrame) + _previous = _current; + + _current = newValue; + } + + public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) => Address < domain.Size - 3; + + private uint GetUint(MemoryDomain domain, bool bigEndian) + { + return IsValid(domain) ? domain.PeekUint(Address, bigEndian) : 0; } } } diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs deleted file mode 100644 index 024eae8d78..0000000000 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs +++ /dev/null @@ -1,183 +0,0 @@ -using BizHawk.Emulation.Common; - -namespace BizHawk.Client.Common.RamSearchEngine -{ - /// - /// Represents a but with added details - /// to do change tracking. These types add more information but at a cost of - /// having to poll the ram address on every update - /// - internal interface IMiniWatchDetails : IMiniWatch - { - int ChangeCount { get; } - - void ClearChangeCount(); - void Update(PreviousType type, MemoryDomain domain, bool bigEndian); - } - - internal sealed class MiniByteWatchDetailed : IMiniWatchDetails - { - public long Address { get; } - - private byte _previous; - private byte _prevFrame; - - public MiniByteWatchDetailed(MemoryDomain domain, long addr) - { - Address = addr; - SetPreviousToCurrent(domain, false); - } - - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) - { - _previous = _prevFrame = MiniByteWatch.GetByte(Address, domain); - } - - public long Previous => _previous; - - public int ChangeCount { get; private set; } - - public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) - { - var value = MiniByteWatch.GetByte(Address, domain); - - if (value != _prevFrame) - { - ChangeCount++; - } - - switch (type) - { - case PreviousType.Original: - case PreviousType.LastSearch: - break; - case PreviousType.LastFrame: - _previous = _prevFrame; - break; - case PreviousType.LastChange: - if (_prevFrame != value) - { - _previous = _prevFrame; - } - - break; - } - - _prevFrame = value; - } - - public void ClearChangeCount() => ChangeCount = 0; - - public bool IsValid(MemoryDomain domain) => MiniByteWatch.IsValid(Address, domain); - } - - internal sealed class MiniWordWatchDetailed : IMiniWatchDetails - { - public long Address { get; } - - private ushort _previous; - private ushort _prevFrame; - - public MiniWordWatchDetailed(MemoryDomain domain, long addr, bool bigEndian) - { - Address = addr; - SetPreviousToCurrent(domain, bigEndian); - } - - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) - { - _previous = _prevFrame = MiniWordWatch.GetUshort(Address, domain, bigEndian); - } - - public long Previous => _previous; - - public int ChangeCount { get; private set; } - - public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) - { - var value = MiniWordWatch.GetUshort(Address, domain, bigEndian); - if (value != Previous) - { - ChangeCount++; - } - - switch (type) - { - case PreviousType.Original: - case PreviousType.LastSearch: - break; - case PreviousType.LastFrame: - _previous = _prevFrame; - break; - case PreviousType.LastChange: - if (_prevFrame != value) - { - _previous = _prevFrame; - } - - break; - } - - _prevFrame = value; - } - - public void ClearChangeCount() => ChangeCount = 0; - - public bool IsValid(MemoryDomain domain) => MiniWordWatch.IsValid(Address, domain); - } - - internal sealed class MiniDWordWatchDetailed : IMiniWatchDetails - { - public long Address { get; } - - private uint _previous; - private uint _prevFrame; - - public MiniDWordWatchDetailed(MemoryDomain domain, long addr, bool bigEndian) - { - Address = addr; - SetPreviousToCurrent(domain, bigEndian); - } - - public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) - { - _previous = _prevFrame = MiniDWordWatch.GetUint(Address, domain, bigEndian); - } - - public long Previous => (int)_previous; - - public int ChangeCount { get; private set; } - - public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) - { - var value = MiniDWordWatch.GetUint(Address, domain, bigEndian); - if (value != Previous) - { - ChangeCount++; - } - - switch (type) - { - case PreviousType.Original: - case PreviousType.LastSearch: - break; - case PreviousType.LastFrame: - _previous = _prevFrame; - break; - case PreviousType.LastChange: - if (_prevFrame != value) - { - _previous = _prevFrame; - } - - break; - } - - _prevFrame = value; - } - - public void ClearChangeCount() => ChangeCount = 0; - - public bool IsValid(MemoryDomain domain) => MiniDWordWatch.IsValid(Address, domain); - } -} diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs index c5139a033e..b1dffd3fa3 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs @@ -64,46 +64,13 @@ namespace BizHawk.Client.Common.RamSearchEngine { default: case WatchSize.Byte: - if (_settings.IsDetailed()) - { - for (var i = 0; i < _watchList.Length; i++) _watchList[i] = new MiniByteWatchDetailed(domain, i); - } - else - { - for (var i = 0; i < _watchList.Length; i++) _watchList[i] = new MiniByteWatch(domain, i); - } + for (var i = 0; i < _watchList.Length; i++) _watchList[i] = new MiniByteWatch(domain, i); break; case WatchSize.Word: - if (_settings.IsDetailed()) - { - for (var i = 0; i < _watchList.Length; i++) - { - _watchList[i] = new MiniWordWatchDetailed(domain, i * stepSize, _settings.BigEndian); - } - } - else - { - for (var i = 0; i < _watchList.Length; i++) - { - _watchList[i] = new MiniWordWatch(domain, i * stepSize, _settings.BigEndian); - } - } + for (var i = 0; i < _watchList.Length; i++) _watchList[i] = new MiniWordWatch(domain, i * stepSize, _settings.BigEndian); break; case WatchSize.DWord: - if (_settings.IsDetailed()) - { - for (var i = 0; i < _watchList.Length; i++) - { - _watchList[i] = new MiniDWordWatchDetailed(domain, i * stepSize, _settings.BigEndian); - } - } - else - { - for (var i = 0; i < _watchList.Length; i++) - { - _watchList[i] = new MiniDWordWatch(domain, i * stepSize, _settings.BigEndian); - } - } + for (var i = 0; i < _watchList.Length; i++) _watchList[i] = new MiniDWordWatch(domain, i * stepSize, _settings.BigEndian); break; } } @@ -121,7 +88,7 @@ namespace BizHawk.Client.Common.RamSearchEngine "", 0, _watchList[index].Previous, - _settings.IsDetailed() ? ((IMiniWatchDetails)_watchList[index]).ChangeCount : 0); + _settings.IsDetailed() ? _watchList[index].ChangeCount : 0); public int DoSearch() { @@ -205,9 +172,8 @@ namespace BizHawk.Client.Common.RamSearchEngine public void Update() { - if (!_settings.IsDetailed()) return; using var @lock = _settings.Domain.EnterExit(); - foreach (IMiniWatchDetails watch in _watchList) + foreach (var watch in _watchList) { watch.Update(_settings.PreviousType, _settings.Domain, _settings.BigEndian); } @@ -235,8 +201,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void ClearChangeCounts() { - if (!_settings.IsDetailed()) return; - foreach (var watch in _watchList.Cast()) + foreach (var watch in _watchList) { watch.ClearChangeCount(); } @@ -302,12 +267,7 @@ namespace BizHawk.Client.Common.RamSearchEngine _watchList = _watchList.OrderBy(w => w.Previous, reverse).ToArray(); break; case WatchList.ChangesCol: - if (!_settings.IsDetailed()) break; - _watchList = _watchList - .Cast() - .OrderBy(w => w.ChangeCount, reverse) - .Cast() - .ToArray(); + _watchList = _watchList.OrderBy(w => w.ChangeCount, reverse).ToArray(); break; case WatchList.Diff: _watchList = _watchList.OrderBy(w => GetValue(w.Address) - w.Previous, reverse).ToArray(); @@ -493,40 +453,25 @@ namespace BizHawk.Client.Common.RamSearchEngine private IEnumerable CompareChanges(IEnumerable watchList) { - if (!_settings.IsDetailed()) throw new InvalidCastException(); //TODO matches previous behaviour; was this intended to skip processing? --yoshi if (CompareValue is not long compareValue) throw new InvalidCastException(); //TODO typo for IOE? switch (Operator) { default: case ComparisonOperator.Equal: - return watchList - .Cast() - .Where(w => w.ChangeCount == compareValue); + return watchList.Where(w => w.ChangeCount == compareValue); case ComparisonOperator.NotEqual: - return watchList - .Cast() - .Where(w => w.ChangeCount != compareValue); + return watchList.Where(w => w.ChangeCount != compareValue); case ComparisonOperator.GreaterThan: - return watchList - .Cast() - .Where(w => w.ChangeCount > compareValue); + return watchList.Where(w => w.ChangeCount > compareValue); case ComparisonOperator.GreaterThanEqual: - return watchList - .Cast() - .Where(w => w.ChangeCount >= compareValue); + return watchList.Where(w => w.ChangeCount >= compareValue); case ComparisonOperator.LessThan: - return watchList - .Cast() - .Where(w => w.ChangeCount < compareValue); + return watchList.Where(w => w.ChangeCount < compareValue); case ComparisonOperator.LessThanEqual: - return watchList - .Cast() - .Where(w => w.ChangeCount <= compareValue); + return watchList.Where(w => w.ChangeCount <= compareValue); case ComparisonOperator.DifferentBy: if (DifferentBy is not int differentBy) throw new InvalidOperationException(); - return watchList - .Cast() - .Where(w => Math.Abs(w.ChangeCount - compareValue) == differentBy); + return watchList.Where(w => Math.Abs(w.ChangeCount - compareValue) == differentBy); } } diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index a466b9fff3..1bd1e0d5de 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -1105,9 +1105,6 @@ namespace BizHawk.Client.EmuHawk Previous_LastChangeMenuItem.Checked = true; break; } - - PreviousFrameMenuItem.Enabled = _settings.IsDetailed(); - Previous_LastChangeMenuItem.Enabled = _settings.IsDetailed(); } private void DetailedMenuItem_Click(object sender, EventArgs e) @@ -1169,8 +1166,6 @@ namespace BizHawk.Client.EmuHawk private void SearchSubMenu_DropDownOpened(object sender, EventArgs e) { - ClearChangeCountsMenuItem.Enabled = _settings.IsDetailed(); - RemoveMenuItem.Enabled = AddToRamWatchMenuItem.Enabled = WatchListView.AnyRowsSelected;