Extract interface from `SettingsAdapter`, add alt. impl. using config

replaces hacks in `N64VideoPluginConfig` and `ProfileConfig`
This commit is contained in:
YoshiRulz 2022-05-28 19:31:03 +10:00 committed by James Groom
parent 5b403f9c2a
commit 4938f427a4
10 changed files with 105 additions and 88 deletions

View File

@ -77,18 +77,6 @@ namespace BizHawk.Client.Common
}
}
/// <summary>
/// saves the core settings for a core
/// </summary>
/// <param name="config"></param>
/// <param name="o">null to remove settings for that core instead</param>
/// <typeparam name="TCore"></typeparam>
public static void PutCoreSettings<TCore>(this Config config, object o)
where TCore : IEmulator
{
config.PutCoreSettings(o, typeof(TCore));
}
/// <summary>
/// Returns the core syncsettings for a core
/// </summary>
@ -129,18 +117,6 @@ namespace BizHawk.Client.Common
}
}
/// <summary>
/// saves the core syncsettings for a core
/// </summary>
/// <param name="config"></param>
/// <param name="o">null to remove settings for that core instead</param>
/// <typeparam name="TCore"></typeparam>
public static void PutCoreSyncSettings<TCore>(this Config config, object o)
where TCore : IEmulator
{
config.PutCoreSyncSettings(o, typeof(TCore));
}
public static void ReplaceKeysInBindings(this Config config, IReadOnlyDictionary<string, string> replMap)
{
string ReplMulti(string multiBind)

View File

@ -0,0 +1,57 @@
#nullable enable
using System;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
public sealed class ConfigSettingsAdapter<T> : ISettingsAdapter
where T : IEmulator
{
private readonly Config _config;
private readonly Type _typeS;
private readonly Type _typeSS;
public bool HasSettings { get; }
public bool HasSyncSettings { get; }
public ConfigSettingsAdapter(Config config)
{
_config = config;
var settableType = typeof(T).GetInterfaces()
.SingleOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISettable<,>));
if (settableType == null)
{
_typeS = typeof(object);
_typeSS = typeof(object);
}
else
{
var tt = settableType.GetGenericArguments();
_typeS = tt[0];
_typeSS = tt[1];
}
HasSettings = _typeS != typeof(object);
HasSyncSettings = _typeSS != typeof(object);
}
public object GetSettings()
=> _config.GetCoreSettings(typeof(T), _typeS)
?? Activator.CreateInstance(_typeS);
public object GetSyncSettings()
=> _config.GetCoreSyncSettings(typeof(T), _typeSS)
?? Activator.CreateInstance(_typeSS);
public void PutCoreSettings(object s)
=> _config.PutCoreSettings(s, typeof(T));
public void PutCoreSyncSettings(object ss)
=> _config.PutCoreSyncSettings(ss, typeof(T));
}
}

View File

@ -180,7 +180,7 @@ namespace BizHawk.Client.Common
public static void PopulateWithDefaultHeaderValues(
this IMovie movie,
IEmulator emulator,
SettingsAdapter settable,
ISettingsAdapter settable,
IGameInfo game,
FirmwareManager firmwareManager,
string author)

View File

@ -8,7 +8,10 @@ namespace BizHawk.Client.EmuHawk
public interface IMainFormForConfig : IDialogParent
{
/// <exception cref="InvalidOperationException">loaded emulator is not instance of <typeparamref name="T"/></exception>
SettingsAdapter GetSettingsAdapterForLoadedCore<T>()
ISettingsAdapter GetSettingsAdapterForLoadedCore<T>()
where T : IEmulator;
ISettingsAdapter GetSettingsAdapterFor<T>()
where T : IEmulator;
}
}

View File

@ -966,7 +966,7 @@ namespace BizHawk.Client.EmuHawk
private void ProfilesMenuItem_Click(object sender, EventArgs e)
{
using var form = new ProfileConfig(this, Emulator, Config);
using var form = new ProfileConfig(Config, this);
if (!form.ShowDialog().IsOk()) return;
AddOnScreenMessage("Profile settings saved");
@ -1779,7 +1779,7 @@ namespace BizHawk.Client.EmuHawk
private DialogResult OpenMupen64PlusGraphicsSettingsDialog()
{
using N64VideoPluginConfig form = new(this, Config, Emulator);
using N64VideoPluginConfig form = new(this);
return this.ShowDialogWithTempMute(form);
}
@ -2542,7 +2542,7 @@ namespace BizHawk.Client.EmuHawk
{
// We do not check if the user is actually setting a profile here.
// This is intentional.
using var profileForm = new ProfileConfig(this, Emulator, Config);
using var profileForm = new ProfileConfig(Config, this);
profileForm.ShowDialog();
Config.FirstBoot = false;
ProfileFirstBootLabel.Visible = false;

View File

@ -2429,7 +2429,13 @@ namespace BizHawk.Client.EmuHawk
if (dirty.HasFlag(PutSettingsDirtyBits.RebootCore)) FlagNeedsReboot();
}
public SettingsAdapter GetSettingsAdapterForLoadedCore<T>()
public ISettingsAdapter GetSettingsAdapterFor<T>()
where T : IEmulator
=> Emulator is T
? GetSettingsAdapterForLoadedCoreUntyped()
: new ConfigSettingsAdapter<T>(Config);
public ISettingsAdapter GetSettingsAdapterForLoadedCore<T>()
where T : IEmulator
{
if (Emulator is not T) throw new InvalidOperationException();

View File

@ -8,7 +8,7 @@ namespace BizHawk.Client.EmuHawk
{
public partial class GenericCoreConfig : Form
{
private readonly SettingsAdapter _settable;
private readonly ISettingsAdapter _settable;
private object _s;
private object _ss;
@ -16,14 +16,14 @@ namespace BizHawk.Client.EmuHawk
private bool _settingsChanged;
private GenericCoreConfig(
IMainFormForConfig mainForm,
ISettingsAdapter settable,
bool isMovieActive,
bool ignoreSettings = false,
bool ignoreSyncSettings = false)
{
InitializeComponent();
_settable = ((MainForm) mainForm).GetSettingsAdapterForLoadedCoreUntyped(); //HACK
_settable = settable;
if (_settable.HasSettings && !ignoreSettings) _s = _settable.GetSettings();
@ -116,7 +116,7 @@ namespace BizHawk.Client.EmuHawk
bool hideSyncSettings)
{
using var dlg = new GenericCoreConfig(
owner,
((MainForm) owner).GetSettingsAdapterForLoadedCoreUntyped(), //HACK
isMovieActive: isMovieActive,
ignoreSettings: hideSettings,
ignoreSyncSettings: hideSyncSettings)

View File

@ -5,16 +5,12 @@ using System.Windows.Forms;
using BizHawk.Common.StringExtensions;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Cores.Nintendo.N64;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class N64VideoPluginConfig : Form
{
private readonly IMainFormForConfig _mainForm;
private readonly Config _config;
private readonly IEmulator _emulator;
private readonly N64Settings _s;
private readonly N64SyncSettings _ss;
@ -41,28 +37,13 @@ namespace BizHawk.Client.EmuHawk
private readonly bool _programmaticallyChangingPluginComboBox = false;
public N64VideoPluginConfig(
IMainFormForConfig mainForm,
Config config,
IEmulator emulator)
public N64VideoPluginConfig(IMainFormForConfig mainForm)
{
_mainForm = mainForm;
_config = config;
_emulator = emulator;
// because mupen is a pile of garbage, this all needs to work even when N64 is not loaded
if (_emulator is N64 n64)
{
_s = n64.GetSettings();
_ss = n64.GetSyncSettings();
}
else
{
_s = _config.GetCoreSettings<N64, N64Settings>()
?? new N64Settings();
_ss = _config.GetCoreSyncSettings<N64, N64SyncSettings>()
?? new N64SyncSettings();
}
var settable = _mainForm.GetSettingsAdapterFor<N64>();
_s = (N64Settings) settable.GetSettings();
_ss = (N64SyncSettings) settable.GetSyncSettings();
InitializeComponent();
Icon = Properties.Resources.MonitorIcon;
@ -121,17 +102,9 @@ namespace BizHawk.Client.EmuHawk
.ToString()
.GetEnumFromDescription<N64SyncSettings.RspType>();
if (_emulator is N64)
{
var settable = _mainForm.GetSettingsAdapterForLoadedCore<N64>();
settable.PutCoreSettings(_s);
settable.PutCoreSyncSettings(_ss);
}
else
{
_config.PutCoreSettings<N64>(_s);
_config.PutCoreSyncSettings<N64>(_ss);
}
var settable = _mainForm.GetSettingsAdapterFor<N64>();
settable.PutCoreSettings(_s);
settable.PutCoreSyncSettings(_ss);
}
private void N64VideoPluginConfig_Load(object sender, EventArgs e)

View File

@ -16,16 +16,12 @@ namespace BizHawk.Client.EmuHawk
public partial class ProfileConfig : Form
{
private readonly IMainFormForConfig _mainForm;
private readonly IEmulator _emulator;
private readonly Config _config;
public ProfileConfig(
IMainFormForConfig mainForm,
IEmulator emulator,
Config config)
public ProfileConfig(Config config, IMainFormForConfig mainForm)
{
_mainForm = mainForm;
_emulator = emulator;
_config = config;
InitializeComponent();
Icon = Properties.Resources.ProfileIcon;
@ -241,7 +237,7 @@ namespace BizHawk.Client.EmuHawk
where TEmulator : IEmulator
{
object fromCore = null;
var settable = ((MainForm) _mainForm).GetSettingsAdapterForLoadedCoreUntyped(); //HACK
var settable = _mainForm.GetSettingsAdapterFor<TEmulator>();
if (settable.HasSyncSettings)
{
fromCore = settable.GetSyncSettings();
@ -254,15 +250,6 @@ namespace BizHawk.Client.EmuHawk
private void PutSyncSettings<TEmulator>(object o)
where TEmulator : IEmulator
{
if (_emulator is TEmulator)
{
_mainForm.GetSettingsAdapterForLoadedCore<TEmulator>().PutCoreSyncSettings(o);
}
else
{
_config.PutCoreSyncSettings<TEmulator>(o);
}
}
=> _mainForm.GetSettingsAdapterFor<TEmulator>().PutCoreSyncSettings(o);
}
}

View File

@ -66,10 +66,27 @@ namespace BizHawk.Emulation.Common
ScreenLayoutChanged = 2,
}
public interface ISettingsAdapter
{
bool HasSettings { get; }
bool HasSyncSettings { get; }
/// <exception cref="InvalidOperationException">does not have non-sync settings</exception>
object GetSettings();
/// <exception cref="InvalidOperationException">does not have sync settings</exception>
object GetSyncSettings();
void PutCoreSettings(object s);
void PutCoreSyncSettings(object ss);
}
/// <summary>
/// serves as a shim between strongly typed ISettable and consumers
/// </summary>
public class SettingsAdapter
public sealed class SettingsAdapter : ISettingsAdapter
{
private readonly Action<PutSettingsDirtyBits> _handlePutCoreSettings;
@ -135,7 +152,6 @@ namespace BizHawk.Emulation.Common
private readonly MethodInfo _getss;
private readonly MethodInfo _putss;
/// <exception cref="InvalidOperationException">does not have non-sync settings</exception>
public object GetSettings()
{
if (!HasSettings)
@ -146,7 +162,6 @@ namespace BizHawk.Emulation.Common
return _gets.Invoke(_settable, Empty);
}
/// <exception cref="InvalidOperationException">does not have sync settings</exception>
public object GetSyncSettings()
{
if (!HasSyncSettings)