Skip to content
8 changes: 5 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ dotnet_diagnostic.IDE0032.severity = suggestion
# Simplify default expression
dotnet_diagnostic.IDE0034.severity = suggestion
# Use pattern matching to avoid is check followed by a cast (without variable)
dotnet_diagnostic.IDE0038.severity = warning
dotnet_diagnostic.IDE0038.severity = warning # Note that this doesn't work with `dotnet build` but does work inside Visual Studio.
# Use is null check
dotnet_diagnostic.IDE0041.severity = warning
# Deconstruct variable declaration
dotnet_diagnostic.IDE0042.severity = suggestion
# dotnet_diagnostic.IDE0049.severity = error # see SA1121
# Remove unused private member
dotnet_diagnostic.IDE0051.severity = suggestion
dotnet_diagnostic.IDE0051.severity = warning
# Remove unread private member
dotnet_diagnostic.IDE0052.severity = silent # TODO: should be warning imo, but there's too much violation currently
dotnet_diagnostic.IDE0052.severity = warning
# Use compound assignment
dotnet_diagnostic.IDE0054.severity = warning
# Use index operator
Expand All @@ -97,6 +97,8 @@ dotnet_diagnostic.IDE0071.severity = suggestion
dotnet_diagnostic.IDE0074.severity = suggestion
# Use pattern matching
dotnet_diagnostic.IDE0078.severity = suggestion
# Suppression operator has no effect and can be misinterpreted
dotnet_diagnostic.IDE0080.severity = warning
# Convert typeof to nameof
dotnet_diagnostic.IDE0082.severity = warning
# Use pattern matching (not operator)
Expand Down
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ fec63fb66afe70a22cf328eecdaf09e37c21ada5

# Remove line-end whitespace across main solution
605deb682dacec3342c650e76fb77972e5ffbe04

# Fix use of mixed spaces and tabs for indentation
1f62c65b6a9ccbe0837481a8c691ac4598868a83
1 change: 0 additions & 1 deletion src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,3 @@ public void SetVibration(int left, int right)
}
}
}

4 changes: 3 additions & 1 deletion src/BizHawk.Client.Common/cheats/GbaGameSharkDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace BizHawk.Client.Common.cheats
public static class GbaGameSharkDecoder
{
private static readonly uint[] GameSharkSeeds = { 0x09F4FBBDU, 0x9681884AU, 0x352027E9U, 0xF3DEE5A7U };
private static readonly uint[] ProActionReplaySeeds = { 0x7AA9648FU, 0x7FAE6994U, 0xC0EFAAD5U, 0x42712C57U };

private static string Decrypt(string code)
{
Expand All @@ -28,6 +27,8 @@ private static string Decrypt(string code)
}

// TODO: When to use this?
#if false
private static readonly uint[] ProActionReplaySeeds = { 0x7AA9648FU, 0x7FAE6994U, 0xC0EFAAD5U, 0x42712C57U };
private static string DecryptPro(string code)
{
var sum = 0xC6EF3720;
Expand All @@ -43,6 +44,7 @@ private static string DecryptPro(string code)

return $"{op1:X8} {op2:X8}";
}
#endif

public static IDecodeResult Decode(string code)
{
Expand Down
1 change: 1 addition & 0 deletions src/BizHawk.Client.Common/config/ConfigPersistAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace BizHawk.Client.Common
{
/// <summary>Indicates that a property is to be saved to config for persistence.</summary>
[AttributeUsage(AttributeTargets.Property)]
[Obsolete("Use interface IConfigPersist instead.")]
public sealed class ConfigPersistAttribute : Attribute
{
}
Expand Down
56 changes: 56 additions & 0 deletions src/BizHawk.Client.Common/config/IConfigPersist.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;

namespace BizHawk.Client.Common
{
public interface IConfigPersist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this new approach also suffer from #3337?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

{
public class Provider
{
private Dictionary<string, object> _data;

public Provider(Dictionary<string, object> data)
{
_data = data;
}

public bool Get<T>(string name, ref T value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't value be out? It seems that way from the call-sites.

Also call this TryGet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making it ref greatly simplifies most call sites as there's no need for an intermediate variable (with ref we can set the variable we want directly, instead of setting an out param then the caller having to assign that to the variable) and also because it makes type inference work much nicer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use out without out var if that's what you mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have mentioned, using out introduces these problems because I wanted the uses of Get (or TryGet) method to not touch value if no value is found. Since an out param must be set within the method, that is why it would require an intermediate variable.

If we do bool TryGet<T>(string name, out T value) then public string SomePersistentString; and TryGet("SomePersistentString", out SomePersistentString) then the persisted value would be assigned default which likely isn't a sensible default. So LoadConfig would be required to check the return value and if false assign a sensible default. Keeping default definitions in just one place, outside of LoadConfig, seems cleaner.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] then the persisted value would be assigned default which likely isn't a sensible default. So LoadConfig would be required to check the return value and if false assign a sensible default.

That sounds reasonable to me. The bool TryX(out T result) pattern is well-established.

I think the proper way to do fire-and-forget would be a void Get<T>(string name, ref T value) for fields and a void Get<T>(string name, Action<T> setValue) for props.

{
if (_data.TryGetValue(name, out var val))
{
if (val is string str && typeof(T) != typeof(string))
{
// if a type has a TypeConverter, and that converter can convert to string,
// that will be used in place of object markup by JSON.NET

// but that doesn't work with $type metadata, and JSON.NET fails to fall
// back on regular object serialization when needed. so try to undo a TypeConverter
// operation here
var converter = TypeDescriptor.GetConverter(typeof(T));
val = converter.ConvertFromString(null, CultureInfo.InvariantCulture, str);
}
else if (val is not bool && typeof(T).IsPrimitive)
{
// numeric constants are similarly hosed
val = Convert.ChangeType(val, typeof(T), CultureInfo.InvariantCulture);
}

value = (T)val;
return true;
}
return false;
}
}

/// <summary>
/// Load the provided configuration.
/// </summary>
void LoadConfig(Provider provider);

/// <summary>
/// Return a dictionary representing the current configuration.
/// </summary>
Dictionary<string, object> SaveConfig();
}
}
10 changes: 10 additions & 0 deletions src/BizHawk.Client.Common/config/IRestoreDefaults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace BizHawk.Client.Common
{
/// <summary>
/// When the implementing class also implements <see cref="IToolFormAutoConfig"/>, this interface's method is called when the generated <c>Restore Defaults</c> menu item is clicked.
/// </summary>
public interface IRestoreDefaults
{
void RestoreDefaults();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace BizHawk.Client.Common
/// <summary>Indicates which method of an <see cref="IToolFormAutoConfig"/> is to be called when the generated <c>Restore Defaults</c> menu item is clicked.</summary>
/// <remarks>If not present on any instance method, the menu item will do nothing. If present on multiple, the first will be called.</remarks>
[AttributeUsage(AttributeTargets.Method)]
[Obsolete("Use interface IRestoreDefaults instead.")]
public sealed class RestoreDefaultsAttribute : Attribute
{
}
Expand Down
1 change: 0 additions & 1 deletion src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ namespace BizHawk.Client.Common
{
public sealed class FirmwareManager
{
private static readonly FirmwareID NDS_FIRMWARE = new("NDS", "firmware");
private const int DSI_NAND_LENGTH = 251658240 + 64;

public static (byte[] Patched, string ActualHash) PerformPatchInMemory(byte[] @base, in FirmwarePatchOption patchOption)
Expand Down
4 changes: 4 additions & 0 deletions src/BizHawk.Client.Common/lua/CommonLibs/CommLuaLibrary.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if ENABLE_WEBSOCKETS
using System.Collections.Generic;
#endif
using System.ComponentModel;
using System.Linq;
using System.Text;
Expand All @@ -10,7 +12,9 @@ namespace BizHawk.Client.Common
[Description("A library for communicating with other programs")]
public sealed class CommLuaLibrary : LuaLibraryBase
{
#if ENABLE_WEBSOCKETS
private readonly IDictionary<Guid, ClientWebSocketWrapper> _websockets = new Dictionary<Guid, ClientWebSocketWrapper>();
#endif

public CommLuaLibrary(ILuaLibraries luaLibsImpl, ApiContainer apiContainer, Action<string> logOutputCallback)
: base(luaLibsImpl, apiContainer, logOutputCallback) {}
Expand Down
4 changes: 2 additions & 2 deletions src/BizHawk.Client.Common/lua/CommonLibs/MovieLuaLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public string Filename()
[LuaMethod("getinput", "Returns a table of buttons pressed on a given frame of the loaded movie")]
public LuaTable GetInput(int frame, int? controller = null)
=> APIs.Movie.GetInput(frame, controller) is IReadOnlyDictionary<string, object> dict
? _th.DictToTable(dict)
: null;
? _th.DictToTable(dict)
: null;

[LuaMethodExample("local stmovget = movie.getinputasmnemonic( 500 );")]
[LuaMethod("getinputasmnemonic", "Returns the input of a given frame of the loaded movie in a raw inputlog string")]
Expand Down
2 changes: 1 addition & 1 deletion src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class JmdWriter : IVideoWriter
private const int NO_COMPRESSION = 0;
private const int BEST_COMPRESSION = 9;
private const int DEFAULT_COMPRESSION = -1;
private const int BEST_SPEED = 1;
//private const int BEST_SPEED = 1;

private static CompressionLevel GetCompressionLevel(int v)
{
Expand Down
4 changes: 4 additions & 0 deletions src/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.IO;
#if false
using System.Collections.Generic;
#endif
using System.Drawing.Imaging;
using System.Text;

Expand Down Expand Up @@ -113,6 +115,7 @@ public void SetMetaData(string gameName, string authors, ulong lengthMs, ulong r

public string DesiredExtension() => "syncless.txt";

#if false
/// <summary>
/// splits the string into chunks of length s
/// </summary>
Expand All @@ -139,6 +142,7 @@ private static List<string> StringChunkSplit(string s, int len)

return output;
}
#endif

private string GetAndCreatePathForFrameNum(int index)
{
Expand Down
18 changes: 15 additions & 3 deletions src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace BizHawk.Client.EmuHawk
{
public partial class CoreFeatureAnalysis : ToolFormBase, IToolFormAutoConfig
public partial class CoreFeatureAnalysis : ToolFormBase, IToolFormAutoConfig, IConfigPersist
{
private class CoreInfo
{
Expand Down Expand Up @@ -93,8 +93,20 @@ public FunctionInfo(MethodInfo m, object service)
public static Icon ToolIcon
=> Properties.Resources.Logo;

[ConfigPersist]
private Dictionary<string, CoreInfo> KnownCores { get; set; }
private Dictionary<string, CoreInfo> KnownCores;

void IConfigPersist.LoadConfig(IConfigPersist.Provider provider)
{
provider.Get(nameof(KnownCores), ref KnownCores);
}

Dictionary<string, object> IConfigPersist.SaveConfig()
{
return new()
{
[nameof(KnownCores)] = KnownCores,
};
}

// ReSharper disable once UnusedAutoPropertyAccessor.Local
[RequiredService]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ protected override void OnMouseDown(MouseEventArgs e)
{
// do marker drag here
}
else if (ModifierKeys is Keys.Shift && CurrentCell.Column! is { Type: ColumnType.Text } col)
else if (ModifierKeys is Keys.Shift && CurrentCell.Column is { Type: ColumnType.Text } col)
{
if (_selectedItems.Count is not 0)
{
Expand Down
17 changes: 14 additions & 3 deletions src/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace BizHawk.Client.EmuHawk
{
public sealed partial class BasicBot : ToolFormBase, IToolFormAutoConfig
public sealed partial class BasicBot : ToolFormBase, IToolFormAutoConfig, IConfigPersist
{
private static readonly FilesystemFilterSet BotFilesFSFilterSet = new(new FilesystemFilter("Bot files", new[] { "bot" }));

Expand Down Expand Up @@ -69,8 +69,19 @@ private string CurrentFileName
[RequiredService]
private IMemoryDomains MemoryDomains { get; set; }

[ConfigPersist]
public BasicBotSettings Settings { get; set; }
private BasicBotSettings Settings;

void IConfigPersist.LoadConfig(IConfigPersist.Provider provider)
{
provider.Get(nameof(Settings), ref Settings);
}
Dictionary<string, object> IConfigPersist.SaveConfig()
{
return new()
{
[nameof(Settings)] = Settings,
};
}

public class BasicBotSettings
{
Expand Down
31 changes: 23 additions & 8 deletions src/BizHawk.Client.EmuHawk/tools/CDL.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
Expand All @@ -17,7 +18,7 @@
// TODO - context menu should have copy option too
namespace BizHawk.Client.EmuHawk
{
public partial class CDL : ToolFormBase, IToolFormAutoConfig
public partial class CDL : ToolFormBase, IToolFormAutoConfig, IConfigPersist
{
private static readonly FilesystemFilterSet CDLFilesFSFilterSet = new(new FilesystemFilter("Code Data Logger Files", new[] { "cdl" }));

Expand All @@ -26,21 +27,35 @@ public static Icon ToolIcon

private RecentFiles _recentFld = new RecentFiles();

[ConfigPersist]
private RecentFiles _recent
{
get => _recentFld;
set => _recentFld = value;
}

[ConfigPersist]
private bool CDLAutoSave { get; set; } = true;
private bool CDLAutoSave = true;

[ConfigPersist]
private bool CDLAutoStart { get; set; } = true;
private bool CDLAutoStart = true;

[ConfigPersist]
private bool CDLAutoResume { get; set; } = true;
private bool CDLAutoResume = true;

void IConfigPersist.LoadConfig(IConfigPersist.Provider provider)
{
provider.Get(nameof(_recentFld), ref _recentFld);
provider.Get(nameof(CDLAutoSave), ref CDLAutoSave);
provider.Get(nameof(CDLAutoStart), ref CDLAutoStart);
provider.Get(nameof(CDLAutoResume), ref CDLAutoResume);
}
Dictionary<string, object> IConfigPersist.SaveConfig()
{
return new()
{
[nameof(_recent)] = _recent,
[nameof(CDLAutoSave)] = CDLAutoSave,
[nameof(CDLAutoStart)] = CDLAutoStart,
[nameof(CDLAutoResume)] = CDLAutoResume,
};
}

private void SetCurrentFilename(string fname)
{
Expand Down
20 changes: 15 additions & 5 deletions src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace BizHawk.Client.EmuHawk
{
public partial class Cheats : ToolFormBase, IToolFormAutoConfig
public partial class Cheats : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults, IConfigPersist
{
private const string NameColumn = "NamesColumn";
private const string AddressColumn = "AddressColumn";
Expand Down Expand Up @@ -78,8 +78,19 @@ public Cheats()
[RequiredService]
private IMemoryDomains Core { get; set; }

[ConfigPersist]
public CheatsSettings Settings { get; set; }
public CheatsSettings Settings;

void IConfigPersist.LoadConfig(IConfigPersist.Provider provider)
{
provider.Get(nameof(Settings), ref Settings);
}
Dictionary<string, object> IConfigPersist.SaveConfig()
{
return new()
{
[nameof(Settings)] = Settings,
};
}

public override void Restart()
{
Expand Down Expand Up @@ -513,8 +524,7 @@ private void AutoSaveCheatsMenuItem_Click(object sender, EventArgs e)
private void CheatsOnOffLoadMenuItem_Click(object sender, EventArgs e)
=> Config.Cheats.DisableOnLoad = !Config.Cheats.DisableOnLoad;

[RestoreDefaults]
private void RestoreDefaults()
void IRestoreDefaults.RestoreDefaults()
{
Settings = new CheatsSettings();

Expand Down
Loading
Loading