diff --git a/Ryujinx.sln.DotSettings b/Ryujinx.sln.DotSettings index ed7f3e911..018aa1331 100644 --- a/Ryujinx.sln.DotSettings +++ b/Ryujinx.sln.DotSettings @@ -3,9 +3,13 @@ WARNING UseExplicitType UseExplicitType - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy> + GL + SDL + OS + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy> <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></Policy> True + True True True True @@ -20,4 +24,4 @@ True True True - \ No newline at end of file + diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs index deaa03def..0b1740ba2 100644 --- a/src/Ryujinx.Common/Configuration/AppDataManager.cs +++ b/src/Ryujinx.Common/Configuration/AppDataManager.cs @@ -98,7 +98,7 @@ namespace Ryujinx.Common.Configuration if (IsPathSymlink(BaseDirPath)) { - Logger.Warning?.Print(LogClass.Application, $"Application data directory is a symlink. This may be unintended."); + Logger.Warning?.Print(LogClass.Application, "Application data directory is a symlink. This may be unintended."); } SetupBasePaths(); diff --git a/src/Ryujinx.Common/Logging/Logger.cs b/src/Ryujinx.Common/Logging/Logger.cs index b689ccbde..8dcf1a7cf 100644 --- a/src/Ryujinx.Common/Logging/Logger.cs +++ b/src/Ryujinx.Common/Logging/Logger.cs @@ -212,9 +212,7 @@ namespace Ryujinx.Common.Logging foreach (var log in logs) { if (log.HasValue) - { levels.Add(log.Value.Level); - } } return levels; @@ -233,6 +231,7 @@ namespace Ryujinx.Common.Logging case LogLevel.AccessLog : AccessLog = enabled ? new Log(LogLevel.AccessLog) : new Log?(); break; case LogLevel.Stub : Stub = enabled ? new Log(LogLevel.Stub) : new Log?(); break; case LogLevel.Trace : Trace = enabled ? new Log(LogLevel.Trace) : new Log?(); break; + case LogLevel.Notice : break; default: throw new ArgumentException("Unknown Log Level", nameof(logLevel)); #pragma warning restore IDE0055 } diff --git a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs index 501109b86..95200a7dc 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs @@ -469,7 +469,7 @@ namespace Ryujinx.Cpu.Jit { if (size == 0) { - return Enumerable.Empty(); + return []; } return GetPhysicalRegionsImpl(va, size); diff --git a/src/Ryujinx/App.axaml b/src/Ryujinx/App.axaml index eab318b7b..5a603509c 100644 --- a/src/Ryujinx/App.axaml +++ b/src/Ryujinx/App.axaml @@ -12,6 +12,6 @@ - + - \ No newline at end of file + diff --git a/src/Ryujinx/App.axaml.cs b/src/Ryujinx/App.axaml.cs index c834004e2..522cf2bcb 100644 --- a/src/Ryujinx/App.axaml.cs +++ b/src/Ryujinx/App.axaml.cs @@ -66,11 +66,6 @@ namespace Ryujinx.Ava } } - private void CustomThemeChanged_Event(object sender, ReactiveEventArgs e) - { - ApplyConfiguredTheme(); - } - private void ShowRestartDialog() { _ = Dispatcher.UIThread.InvokeAsync(async () => @@ -93,11 +88,10 @@ namespace Ryujinx.Ava } }); } + + private void CustomThemeChanged_Event(object _, ReactiveEventArgs __) => ApplyConfiguredTheme(); - private void ThemeChanged_Event(object sender, ReactiveEventArgs e) - { - ApplyConfiguredTheme(); - } + private void ThemeChanged_Event(object _, ReactiveEventArgs __) => ApplyConfiguredTheme(); public void ApplyConfiguredTheme() { diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 242b4b37d..9c9898a87 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -57,7 +57,6 @@ using Key = Ryujinx.Input.Key; using MouseButton = Ryujinx.Input.MouseButton; using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter; using Size = Avalonia.Size; -using Switch = Ryujinx.HLE.Switch; namespace Ryujinx.Ava { @@ -130,7 +129,7 @@ namespace Ryujinx.Ava public ContentManager ContentManager { get; } public NpadManager NpadManager { get; } public TouchScreenManager TouchScreenManager { get; } - public Switch Device { get; set; } + public HLE.Switch Device { get; set; } public int Width { get; private set; } public int Height { get; private set; } @@ -849,7 +848,7 @@ namespace Ryujinx.Ava // Initialize Configuration. var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; - Device = new Switch(new HLEConfiguration( + Device = new HLE.Switch(new HLEConfiguration( VirtualFileSystem, _viewModel.LibHacHorizonManager, ContentManager, diff --git a/src/Ryujinx/Common/Locale/LocaleManager.cs b/src/Ryujinx/Common/Locale/LocaleManager.cs index 5cd2428a8..3247a55f8 100644 --- a/src/Ryujinx/Common/Locale/LocaleManager.cs +++ b/src/Ryujinx/Common/Locale/LocaleManager.cs @@ -99,6 +99,9 @@ namespace Ryujinx.Ava.Common.Locale _ => false }; + public static string FormatDynamicValue(LocaleKeys key, params object[] values) + => Instance.UpdateAndGetDynamicValue(key, values); + public string UpdateAndGetDynamicValue(LocaleKeys key, params object[] values) { _dynamicValues[key] = values; @@ -127,9 +130,9 @@ namespace Ryujinx.Ava.Common.Locale _localeLanguageCode = languageCode; } - foreach (var item in locale) + foreach ((LocaleKeys key, string val) in locale) { - _localeStrings[item.Key] = item.Value; + _localeStrings[key] = val; } OnPropertyChanged("Item"); @@ -150,11 +153,11 @@ namespace Ryujinx.Ava.Common.Locale var strings = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary); - foreach (var item in strings) + foreach ((string key, string val) in strings) { - if (Enum.TryParse(item.Key, out var key)) + if (Enum.TryParse(key, out var localeKey)) { - localeStrings[key] = item.Value; + localeStrings[localeKey] = val; } } diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index b77e05c12..47b37c9fa 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -1,7 +1,7 @@ -using ARMeilleure; using Avalonia; using Avalonia.Threading; using DiscordRPC; +using Gommon; using Projektanker.Icons.Avalonia; using Projektanker.Icons.Avalonia.FontAwesome; using Projektanker.Icons.Avalonia.MaterialDesign; @@ -23,6 +23,7 @@ using Ryujinx.UI.Common.Helper; using Ryujinx.UI.Common.SystemInfo; using System; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -103,8 +104,9 @@ namespace Ryujinx.Ava Console.Title = $"Ryujinx Console {Version}"; // Hook unhandled exception and process exit events. - AppDomain.CurrentDomain.UnhandledException += (sender, e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); - AppDomain.CurrentDomain.ProcessExit += (sender, e) => Exit(); + AppDomain.CurrentDomain.UnhandledException += (sender, e) + => ProcessUnhandledException(sender, e.ExceptionObject as Exception, e.IsTerminating); + AppDomain.CurrentDomain.ProcessExit += (_, _) => Exit(); // Setup base data directory. AppDataManager.Initialize(CommandLineState.BaseDirPathArg); @@ -189,7 +191,7 @@ namespace Ryujinx.Ava } } - UseHardwareAcceleration = ConfigurationState.Instance.EnableHardwareAcceleration.Value; + UseHardwareAcceleration = ConfigurationState.Instance.EnableHardwareAcceleration; // Check if graphics backend was overridden if (CommandLineState.OverrideGraphicsBackend is not null) @@ -226,7 +228,13 @@ namespace Ryujinx.Ava Logger.Notice.Print(LogClass.Application, $"Ryujinx Version: {Version}"); SystemInfo.Gather().Print(); - Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(Logger.GetEnabledLevels().Count == 0 ? "" : string.Join(", ", Logger.GetEnabledLevels()))}"); + var enabledLogLevels = Logger.GetEnabledLevels().ToArray(); + + Logger.Notice.Print(LogClass.Application, $"Logs Enabled: { + (enabledLogLevels.Length is 0 + ? "" + : enabledLogLevels.JoinToString(", ")) + }"); Logger.Notice.Print(LogClass.Application, AppDataManager.Mode == AppDataManager.LaunchMode.Custom @@ -234,21 +242,19 @@ namespace Ryujinx.Ava : $"Launch Mode: {AppDataManager.Mode}"); } - private static void ProcessUnhandledException(Exception ex, bool isTerminating) + private static void ProcessUnhandledException(object sender, Exception ex, bool isTerminating) { + Logger.Log log = Logger.Error ?? Logger.Notice; string message = $"Unhandled exception caught: {ex}"; - - Logger.Error?.PrintMsg(LogClass.Application, message); - - if (Logger.Error == null) - { - Logger.Notice.PrintMsg(LogClass.Application, message); - } - + + // ReSharper disable once ConstantConditionalAccessQualifier + if (sender?.GetType()?.AsPrettyString() is {} senderName) + log.Print(LogClass.Application, message, senderName); + else + log.PrintMsg(LogClass.Application, message); + if (isTerminating) - { Exit(); - } } public static void Exit() diff --git a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs index 064a2f75a..d5c910629 100644 --- a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs @@ -31,15 +31,11 @@ namespace Ryujinx.Ava.UI.Applet public bool DisplayMessageDialog(ControllerAppletUIArgs args) { ManualResetEvent dialogCloseEvent = new(false); - - bool ignoreApplet = ConfigurationState.Instance.IgnoreApplet; + bool okPressed = false; - if (ignoreApplet) - { - + if (ConfigurationState.Instance.IgnoreApplet) return false; - } Dispatcher.UIThread.InvokeAsync(async () => { @@ -74,9 +70,9 @@ namespace Ryujinx.Ava.UI.Applet UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent, title, message, - "", + string.Empty, LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel], - "", + string.Empty, LocaleManager.Instance[LocaleKeys.SettingsButtonClose], (int)Symbol.Important, deferEvent, @@ -179,12 +175,12 @@ namespace Ryujinx.Ava.UI.Applet { Title = title, WindowStartupLocation = WindowStartupLocation.CenterScreen, - Width = 400, + Width = 400 }; object response = await msgDialog.Run(); - if (response != null && buttons != null && buttons.Length > 1 && (int)response != buttons.Length - 1) + if (response != null && buttons is { Length: > 1 } && (int)response != buttons.Length - 1) { showDetails = true; } diff --git a/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs index 1fc3c9c3c..5ec7737ed 100644 --- a/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs @@ -24,10 +24,13 @@ namespace Ryujinx.Ava.UI.Applet public AvaloniaDynamicTextInputHandler(MainWindow parent) { _parent = parent; - - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput; + + if (_parent.InputManager.KeyboardDriver is AvaloniaKeyboardDriver avaloniaKeyboardDriver) + { + avaloniaKeyboardDriver.KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed; + avaloniaKeyboardDriver.KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease; + avaloniaKeyboardDriver.TextInput += AvaloniaDynamicTextInputHandler_TextInput; + } _hiddenTextBox = _parent.HiddenTextBox; @@ -44,7 +47,7 @@ namespace Ryujinx.Ava.UI.Applet TextChangedEvent?.Invoke(text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, false); } - private void SelectionChanged(int selection) + private void SelectionChanged(int _) { TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, false); } @@ -112,10 +115,13 @@ namespace Ryujinx.Ava.UI.Applet public void Dispose() { - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput; - + if (_parent.InputManager.KeyboardDriver is AvaloniaKeyboardDriver avaloniaKeyboardDriver) + { + avaloniaKeyboardDriver.KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed; + avaloniaKeyboardDriver.KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease; + avaloniaKeyboardDriver.TextInput -= AvaloniaDynamicTextInputHandler_TextInput; + } + _textChangedSubscription?.Dispose(); _selectionStartChangedSubscription?.Dispose(); _selectionEndtextChangedSubscription?.Dispose(); diff --git a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs index 869656669..1c70a80ec 100644 --- a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs +++ b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs @@ -47,42 +47,37 @@ namespace Ryujinx.Ava.UI.Controls LoadProfiles(); if (contentManager.GetCurrentFirmwareVersion() != null) - { - Task.Run(() => - { - UserFirmwareAvatarSelectorViewModel.PreloadAvatars(contentManager, virtualFileSystem); - }); - } + Task.Run(() => UserFirmwareAvatarSelectorViewModel.PreloadAvatars(contentManager, virtualFileSystem)); + InitializeComponent(); } public void GoBack() { if (ContentFrame.BackStack.Count > 0) - { ContentFrame.GoBack(); - } LoadProfiles(); } - public void Navigate(Type sourcePageType, object parameter) - { - ContentFrame.Navigate(sourcePageType, parameter); - } + public void Navigate(Type sourcePageType, object parameter) + => ContentFrame.Navigate(sourcePageType, parameter); - public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager, - VirtualFileSystem ownerVirtualFileSystem, HorizonClient ownerHorizonClient) + public static async Task Show( + AccountManager ownerAccountManager, + ContentManager ownerContentManager, + VirtualFileSystem ownerVirtualFileSystem, + HorizonClient ownerHorizonClient) { var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient); ContentDialog contentDialog = new() { Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle], - PrimaryButtonText = "", - SecondaryButtonText = "", - CloseButtonText = "", + PrimaryButtonText = string.Empty, + SecondaryButtonText = string.Empty, + CloseButtonText = string.Empty, Content = content, - Padding = new Thickness(0), + Padding = new Thickness(0) }; contentDialog.Closed += (_, _) => content.ViewModel.Dispose(); @@ -160,14 +155,14 @@ namespace Ryujinx.Ava.UI.Controls if (profile == null) { + Dispatcher.UIThread.Post(Action); + + return; + static async void Action() { await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionWarningMessage]); } - - Dispatcher.UIThread.Post(Action); - - return; } AccountManager.OpenUser(profile.UserId); diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs index 19dd3fd33..a2c40c5b0 100644 --- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs @@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Helpers PrimaryButtonCommand = MiniCommand.Create(() => { result = primaryButtonResult; - }), + }) }; contentDialog.SecondaryButtonCommand = MiniCommand.Create(() => diff --git a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs index fc7145410..7982c17a6 100644 --- a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs +++ b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs @@ -1,5 +1,6 @@ using Avalonia.Logging; using Avalonia.Utilities; +using Gommon; using Ryujinx.Common.Logging; using System; using System.Text; @@ -90,7 +91,7 @@ namespace Ryujinx.Ava.UI.Helpers if (source != null) { result.Append(" ("); - result.Append(source.GetType().Name); + result.Append(source.GetType().AsFullNamePrettyString()); result.Append(" #"); result.Append(source.GetHashCode()); result.Append(')'); diff --git a/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs b/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs index dd736037e..dd9698918 100644 --- a/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs +++ b/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs @@ -35,7 +35,7 @@ namespace Ryujinx.Ava.UI.Helpers { Text = text, Source = this, - RoutedEvent = TextInputEvent, + RoutedEvent = TextInputEvent }); } } diff --git a/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs b/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs index 876d51f71..5edc6482e 100644 --- a/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs +++ b/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs @@ -9,20 +9,12 @@ namespace Ryujinx.Ava.UI.Helpers { public static TimeZoneConverter Instance = new(); - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value == null) - { - return null; - } + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + => value is TimeZone timeZone + ? $"{timeZone.UtcDifference} {timeZone.Location} {timeZone.Abbreviation}" + : null; - var timeZone = (TimeZone)value; - return string.Format("{0} {1} {2}", timeZone.UtcDifference, timeZone.Location, timeZone.Abbreviation); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => throw new NotImplementedException(); } } diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index e31b5f13a..0e6be4c37 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -3,12 +3,12 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Media; +using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; using Avalonia.Threading; using DynamicData; using DynamicData.Binding; using FluentAvalonia.UI.Controls; -using Gommon; using LibHac.Common; using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; @@ -41,6 +41,7 @@ using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Key = Ryujinx.Input.Key; @@ -113,6 +114,9 @@ namespace Ryujinx.Ava.UI.ViewModels public ApplicationData ListSelectedApplication; public ApplicationData GridSelectedApplication; + public static readonly Bitmap IconBitmap = + new(Assembly.GetAssembly(typeof(ConfigurationState))!.GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx.png")!); + public MainWindow Window { get; init; } internal AppHost AppHost { get; set; } @@ -179,18 +183,16 @@ namespace Ryujinx.Ava.UI.ViewModels _searchTimer?.Dispose(); - _searchTimer = new Timer(TimerCallback, null, 1000, 0); + _searchTimer = new Timer(_ => + { + RefreshView(); + + _searchTimer.Dispose(); + _searchTimer = null; + }, null, 1000, 0); } } - private void TimerCallback(object obj) - { - RefreshView(); - - _searchTimer.Dispose(); - _searchTimer = null; - } - public bool CanUpdate { get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate(false); @@ -978,29 +980,26 @@ namespace Ryujinx.Ava.UI.ViewModels #region PrivateMethods - private IComparer GetComparer() - { - return SortMode switch + private static IComparer CreateComparer(bool ascending, Func selector) => + ascending + ? SortExpressionComparer.Ascending(selector) + : SortExpressionComparer.Descending(selector); + + private IComparer GetComparer() + => SortMode switch { #pragma warning disable IDE0055 // Disable formatting - ApplicationSort.Title => IsAscending ? SortExpressionComparer.Ascending(app => app.Name) - : SortExpressionComparer.Descending(app => app.Name), - ApplicationSort.Developer => IsAscending ? SortExpressionComparer.Ascending(app => app.Developer) - : SortExpressionComparer.Descending(app => app.Developer), + ApplicationSort.Title => CreateComparer(IsAscending, app => app.Name), + ApplicationSort.Developer => CreateComparer(IsAscending, app => app.Developer), ApplicationSort.LastPlayed => new LastPlayedSortComparer(IsAscending), ApplicationSort.TotalTimePlayed => new TimePlayedSortComparer(IsAscending), - ApplicationSort.FileType => IsAscending ? SortExpressionComparer.Ascending(app => app.FileExtension) - : SortExpressionComparer.Descending(app => app.FileExtension), - ApplicationSort.FileSize => IsAscending ? SortExpressionComparer.Ascending(app => app.FileSize) - : SortExpressionComparer.Descending(app => app.FileSize), - ApplicationSort.Path => IsAscending ? SortExpressionComparer.Ascending(app => app.Path) - : SortExpressionComparer.Descending(app => app.Path), - ApplicationSort.Favorite => IsAscending ? SortExpressionComparer.Ascending(app => new AppListFavoriteComparable(app)) - : SortExpressionComparer.Descending(app => new AppListFavoriteComparable(app)), + ApplicationSort.FileType => CreateComparer(IsAscending, app => app.FileExtension), + ApplicationSort.FileSize => CreateComparer(IsAscending, app => app.FileSize), + ApplicationSort.Path => CreateComparer(IsAscending, app => app.Path), + ApplicationSort.Favorite => CreateComparer(IsAscending, app => new AppListFavoriteComparable(app)), _ => null, #pragma warning restore IDE0055 }; - } public void RefreshView() { @@ -1125,7 +1124,7 @@ namespace Ryujinx.Ava.UI.ViewModels } catch (MissingKeyException ex) { - if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime) { Logger.Error?.Print(LogClass.Application, ex.ToString()); @@ -1260,8 +1259,10 @@ namespace Ryujinx.Ava.UI.ViewModels GameStatusText = args.GameStatus; VolumeStatusText = args.VolumeStatus; FifoStatusText = args.FifoStatus; - ShaderCountText = args.ShaderCount > 0 ? $"Compiling shaders: {args.ShaderCount}" : string.Empty; - ShowRightmostSeparator = !ShaderCountText.IsNullOrEmpty(); + + ShaderCountText = (ShowRightmostSeparator = args.ShaderCount > 0) + ? $"{LocaleManager.Instance[LocaleKeys.CompilingShaders]}: {args.ShaderCount}" + : string.Empty; ShowStatusSeparator = true; }); @@ -1641,8 +1642,7 @@ namespace Ryujinx.Ava.UI.ViewModels gameThread.Start(); } - public void SwitchToRenderer(bool startFullscreen) - { + public void SwitchToRenderer(bool startFullscreen) => Dispatcher.UIThread.Post(() => { SwitchToGameControl(startFullscreen); @@ -1651,15 +1651,9 @@ namespace Ryujinx.Ava.UI.ViewModels RendererHostControl.Focus(); }); - } - public static void UpdateGameMetadata(string titleId) - { - ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => - { - appMetadata.UpdatePostGame(); - }); - } + public static void UpdateGameMetadata(string titleId) + => ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame()); public void RefreshFirmwareStatus() { diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index a1f92d072..ce024784e 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -287,11 +287,11 @@ namespace Ryujinx.Ava.UI.ViewModels public SettingsViewModel() { - GameDirectories = new AvaloniaList(); - AutoloadDirectories = new AvaloniaList(); - TimeZones = new AvaloniaList(); - AvailableGpus = new ObservableCollection(); - _validTzRegions = new List(); + GameDirectories = []; + AutoloadDirectories = []; + TimeZones = []; + AvailableGpus = []; + _validTzRegions = []; _networkInterfaces = new Dictionary(); Task.Run(CheckSoundBackends); diff --git a/src/Ryujinx/UI/Windows/IconColorPicker.cs b/src/Ryujinx/UI/Windows/IconColorPicker.cs index 088ab5116..bfa33eb43 100644 --- a/src/Ryujinx/UI/Windows/IconColorPicker.cs +++ b/src/Ryujinx/UI/Windows/IconColorPicker.cs @@ -21,10 +21,10 @@ namespace Ryujinx.Ava.UI.Windows private readonly struct PaletteColor(int qck, byte r, byte g, byte b) { - public int Qck { get; } = qck; - public byte R { get; } = r; - public byte G { get; } = g; - public byte B { get; } = b; + public int Qck => qck; + public byte R => r; + public byte G => g; + public byte B => b; } public static SKColor GetFilteredColor(SKBitmap image) @@ -54,15 +54,6 @@ namespace Ryujinx.Ava.UI.Windows var buffer = GetBuffer(image); - int w = image.Width; - int w8 = w << 8; - int h8 = image.Height << 8; - -#pragma warning disable IDE0059 // Unnecessary assignment - int xStep = w8 / ColorsPerLine; - int yStep = h8 / ColorsPerLine; -#pragma warning restore IDE0059 - int i = 0; int maxHitCount = 0;