Migrate Network to SettingsNetworkViewModel

This commit is contained in:
Isaac Marovitz 2024-04-19 16:47:31 -04:00
parent 2d399b6d26
commit 65ec957c4c
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
5 changed files with 120 additions and 88 deletions

View file

@ -0,0 +1,104 @@
using Avalonia.Collections;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.UI.Common.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.ViewModels.Settings
{
public class SettingsNetworkViewModel : BaseModel
{
public event Action DirtyEvent;
private readonly Dictionary<string, string> _networkInterfaces = new();
public AvaloniaList<string> NetworkInterfaceList
{
get => new(_networkInterfaces.Keys);
}
private bool _enableInternetAccess;
public bool EnableInternetAccess
{
get => _enableInternetAccess;
set
{
_enableInternetAccess = value;
DirtyEvent?.Invoke();
}
}
private int _networkInterfaceIndex;
public int NetworkInterfaceIndex
{
get => _networkInterfaceIndex;
set
{
_networkInterfaceIndex = value != -1 ? value : 0;
OnPropertyChanged();
DirtyEvent?.Invoke();
}
}
private int _multiplayerModeIndex;
public int MultiplayerModeIndex
{
get => _multiplayerModeIndex;
set
{
_multiplayerModeIndex = value;
DirtyEvent?.Invoke();
}
}
public SettingsNetworkViewModel()
{
ConfigurationState config = ConfigurationState.Instance;
Task.Run(PopulateNetworkInterfaces);
// LAN interface index is loaded asynchronously in PopulateNetworkInterfaces()
EnableInternetAccess = config.System.EnableInternetAccess;
MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value;
}
private async Task PopulateNetworkInterfaces()
{
_networkInterfaces.Clear();
_networkInterfaces.Add(LocaleManager.Instance[LocaleKeys.NetworkInterfaceDefault], "0");
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
_networkInterfaces.Add(networkInterface.Name, networkInterface.Id);
});
}
// Network interface index needs to be loaded during the async method, or it will always return 0.
NetworkInterfaceIndex = _networkInterfaces.Values.ToList().IndexOf(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value);
}
public bool CheckIfModified(ConfigurationState config)
{
bool isDirty = false;
isDirty |= config.System.EnableInternetAccess.Value != EnableInternetAccess;
isDirty |= config.Multiplayer.LanInterfaceId.Value != _networkInterfaces[NetworkInterfaceList[NetworkInterfaceIndex]];
isDirty |= config.Multiplayer.Mode.Value != (MultiplayerMode)MultiplayerModeIndex;
return isDirty;
}
public void Save(ConfigurationState config)
{
config.System.EnableInternetAccess.Value = EnableInternetAccess;
config.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[NetworkInterfaceIndex]];
config.Multiplayer.Mode.Value = (MultiplayerMode)MultiplayerModeIndex;
}
}
}

View file

@ -25,13 +25,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
private TimeZoneContentManager _timeZoneContentManager; private TimeZoneContentManager _timeZoneContentManager;
private readonly List<string> _validTzRegions; private readonly List<string> _validTzRegions;
private readonly Dictionary<string, string> _networkInterfaces;
private bool _directoryChanged; private bool _directoryChanged;
private int _networkInterfaceIndex;
private int _multiplayerModeIndex;
private bool _isModified; private bool _isModified;
@ -117,17 +112,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
} }
} }
private bool _enableInternetAccess;
public bool EnableInternetAccess
{
get => _enableInternetAccess;
set
{
_enableInternetAccess = value;
CheckIfModified();
}
}
private bool _enableFsIntegrityChecks; private bool _enableFsIntegrityChecks;
public bool EnableFsIntegrityChecks public bool EnableFsIntegrityChecks
{ {
@ -172,6 +156,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
private readonly SettingsHotkeysViewModel _hotkeysViewModel; private readonly SettingsHotkeysViewModel _hotkeysViewModel;
private readonly SettingsInputViewModel _inputViewModel; private readonly SettingsInputViewModel _inputViewModel;
private readonly SettingsLoggingViewModel _loggingViewModel; private readonly SettingsLoggingViewModel _loggingViewModel;
private readonly SettingsNetworkViewModel _networkViewModel;
public DateTimeOffset CurrentDate { get; set; } public DateTimeOffset CurrentDate { get; set; }
public TimeSpan CurrentTime { get; set; } public TimeSpan CurrentTime { get; set; }
@ -179,31 +164,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
internal AvaloniaList<TimeZone> TimeZones { get; set; } internal AvaloniaList<TimeZone> TimeZones { get; set; }
public AvaloniaList<string> GameDirectories { get; set; } public AvaloniaList<string> GameDirectories { get; set; }
public AvaloniaList<string> NetworkInterfaceList
{
get => new(_networkInterfaces.Keys);
}
public int NetworkInterfaceIndex
{
get => _networkInterfaceIndex;
set
{
_networkInterfaceIndex = value != -1 ? value : 0;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]];
}
}
public int MultiplayerModeIndex
{
get => _multiplayerModeIndex;
set
{
_multiplayerModeIndex = value;
ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex;
}
}
public SettingsViewModel( public SettingsViewModel(
VirtualFileSystem virtualFileSystem, VirtualFileSystem virtualFileSystem,
ContentManager contentManager, ContentManager contentManager,
@ -212,7 +172,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
SettingsGraphicsViewModel graphicsViewModel, SettingsGraphicsViewModel graphicsViewModel,
SettingsHotkeysViewModel hotkeysViewModel, SettingsHotkeysViewModel hotkeysViewModel,
SettingsInputViewModel inputViewModel, SettingsInputViewModel inputViewModel,
SettingsLoggingViewModel loggingViewModel) : this() SettingsLoggingViewModel loggingViewModel,
SettingsNetworkViewModel networkViewModel) : this()
{ {
_virtualFileSystem = virtualFileSystem; _virtualFileSystem = virtualFileSystem;
_contentManager = contentManager; _contentManager = contentManager;
@ -223,6 +184,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_hotkeysViewModel = hotkeysViewModel; _hotkeysViewModel = hotkeysViewModel;
_inputViewModel = inputViewModel; _inputViewModel = inputViewModel;
_loggingViewModel = loggingViewModel; _loggingViewModel = loggingViewModel;
_networkViewModel = networkViewModel;
_audioViewModel.DirtyEvent += CheckIfModified; _audioViewModel.DirtyEvent += CheckIfModified;
_cpuViewModel.DirtyEvent += CheckIfModified; _cpuViewModel.DirtyEvent += CheckIfModified;
@ -230,6 +192,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_hotkeysViewModel.DirtyEvent += CheckIfModified; _hotkeysViewModel.DirtyEvent += CheckIfModified;
_inputViewModel.DirtyEvent += CheckIfModified; _inputViewModel.DirtyEvent += CheckIfModified;
_loggingViewModel.DirtyEvent += CheckIfModified; _loggingViewModel.DirtyEvent += CheckIfModified;
_networkViewModel.DirtyEvent += CheckIfModified;
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
{ {
@ -242,9 +205,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
GameDirectories = new AvaloniaList<string>(); GameDirectories = new AvaloniaList<string>();
TimeZones = new AvaloniaList<TimeZone>(); TimeZones = new AvaloniaList<TimeZone>();
_validTzRegions = new List<string>(); _validTzRegions = new List<string>();
_networkInterfaces = new Dictionary<string, string>();
Task.Run(PopulateNetworkInterfaces);
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
{ {
@ -291,14 +251,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
isDirty |= _hotkeysViewModel?.CheckIfModified(config) ?? false; isDirty |= _hotkeysViewModel?.CheckIfModified(config) ?? false;
// TODO: IMPLEMENT THIS!! // TODO: IMPLEMENT THIS!!
// isDirty |= _inputViewModel?.CheckIfModified(config) ?? false; // isDirty |= _inputViewModel?.CheckIfModified(config) ?? false;
// Network
isDirty |= config.System.EnableInternetAccess.Value != EnableInternetAccess;
isDirty |= _loggingViewModel?.CheckIfModified(config) ?? false; isDirty |= _loggingViewModel?.CheckIfModified(config) ?? false;
isDirty |= _networkViewModel?.CheckIfModified(config) ?? false;
isDirty |= config.Multiplayer.LanInterfaceId.Value != _networkInterfaces[NetworkInterfaceList[NetworkInterfaceIndex]];
isDirty |= config.Multiplayer.Mode.Value != (MultiplayerMode)MultiplayerModeIndex;
IsModified = isDirty; IsModified = isDirty;
} }
@ -327,25 +281,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(TimeZone))); Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(TimeZone)));
} }
private async Task PopulateNetworkInterfaces()
{
_networkInterfaces.Clear();
_networkInterfaces.Add(LocaleManager.Instance[LocaleKeys.NetworkInterfaceDefault], "0");
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
_networkInterfaces.Add(networkInterface.Name, networkInterface.Id);
});
}
// Network interface index needs to be loaded during the async method or it will always return 0.
NetworkInterfaceIndex = _networkInterfaces.Values.ToList().IndexOf(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value);
Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(NetworkInterfaceIndex)));
}
public void ValidateAndSetTimeZone(string location) public void ValidateAndSetTimeZone(string location)
{ {
if (_validTzRegions.Contains(location)) if (_validTzRegions.Contains(location))
@ -383,12 +318,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
ExpandDramSize = config.System.ExpandRam; ExpandDramSize = config.System.ExpandRam;
IgnoreMissingServices = config.System.IgnoreMissingServices; IgnoreMissingServices = config.System.IgnoreMissingServices;
// Network
EnableInternetAccess = config.System.EnableInternetAccess;
// LAN interface index is loaded asynchronously in PopulateNetworkInterfaces()
MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value;
} }
public void SaveSettings() public void SaveSettings()
@ -430,14 +359,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_graphicsViewModel?.Save(config); _graphicsViewModel?.Save(config);
_hotkeysViewModel?.Save(config); _hotkeysViewModel?.Save(config);
_inputViewModel?.Save(config); _inputViewModel?.Save(config);
// Network
config.System.EnableInternetAccess.Value = EnableInternetAccess;
_loggingViewModel?.Save(config); _loggingViewModel?.Save(config);
_networkViewModel?.Save(config);
config.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[NetworkInterfaceIndex]];
config.Multiplayer.Mode.Value = (MultiplayerMode)MultiplayerModeIndex;
config.ToFileFormat().SaveConfig(Program.ConfigurationPath); config.ToFileFormat().SaveConfig(Program.ConfigurationPath);

View file

@ -7,9 +7,9 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Settings" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Settings"
mc:Ignorable="d" mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsNetworkViewModel">
<Design.DataContext> <Design.DataContext>
<viewModels:SettingsViewModel /> <viewModels:SettingsNetworkViewModel />
</Design.DataContext> </Design.DataContext>
<ScrollViewer <ScrollViewer
Name="NetworkPage" Name="NetworkPage"

View file

@ -1,11 +1,15 @@
using Avalonia.Controls; using Avalonia.Controls;
using Ryujinx.Ava.UI.ViewModels.Settings;
namespace Ryujinx.Ava.UI.Views.Settings namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsNetworkView : UserControl public partial class SettingsNetworkView : UserControl
{ {
public SettingsNetworkViewModel ViewModel;
public SettingsNetworkView() public SettingsNetworkView()
{ {
DataContext = ViewModel = new SettingsNetworkViewModel();
InitializeComponent(); InitializeComponent();
} }
} }

View file

@ -35,6 +35,7 @@ namespace Ryujinx.Ava.UI.Windows
HotkeysPage = new SettingsHotkeysView(); HotkeysPage = new SettingsHotkeysView();
InputPage = new SettingsInputView(); InputPage = new SettingsInputView();
LoggingPage = new SettingsLoggingView(); LoggingPage = new SettingsLoggingView();
NetworkPage = new SettingsNetworkView();
ViewModel = new SettingsViewModel( ViewModel = new SettingsViewModel(
virtualFileSystem, virtualFileSystem,
@ -44,11 +45,11 @@ namespace Ryujinx.Ava.UI.Windows
GraphicsPage.ViewModel, GraphicsPage.ViewModel,
HotkeysPage.ViewModel, HotkeysPage.ViewModel,
InputPage.ViewModel, InputPage.ViewModel,
LoggingPage.ViewModel); LoggingPage.ViewModel,
NetworkPage.ViewModel);
UiPage = new SettingsUiView(ViewModel); UiPage = new SettingsUiView(ViewModel);
SystemPage = new SettingsSystemView(ViewModel); SystemPage = new SettingsSystemView(ViewModel);
NetworkPage = new SettingsNetworkView();
DataContext = ViewModel; DataContext = ViewModel;