diff --git a/assets/locales.json b/assets/locales.json index 8899bf692..afb2ecf11 100644 --- a/assets/locales.json +++ b/assets/locales.json @@ -13717,6 +13717,56 @@ "zh_TW": "警告" } }, + { + "ID": "DialogDeleteAllCaches", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "You are about to clear all caches for all games.\n\nAre you sure you want to proceed?", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "DialogDeleteAllCachesErrorMessage", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Failed to purge some caches, check log file.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "DialogPPTCDeletionMessage", "Translations": { @@ -24217,6 +24267,81 @@ "zh_TW": "在執行首項指令前暫停應用程式,以便從最早的點開始偵錯。" } }, + { + "ID": "SettingsTabDebugPurgeAllCaches", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Purge All Caches", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabDebugPurgeAllCachesSuccessTitle", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "All Shader & CPU caches deleted", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabDebugPurgeAllCachesSuccessText", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Destroyed the caches of {0} applications.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "LdnGameListOpen", "Translations": { @@ -24843,4 +24968,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 233c30bad..071d83f86 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -4,11 +4,13 @@ using Avalonia.Media.Imaging; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using DynamicData.Binding; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL3; using Ryujinx.Audio.Backends.SoundIo; using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Systems.Configuration.UI; @@ -19,6 +21,7 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Helper; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; @@ -912,7 +915,13 @@ namespace Ryujinx.Ava.UI.ViewModels CloseWindow?.Invoke(); } - [ObservableProperty] private bool _wantsToReset; + public void CancelButton() + { + RevertIfNotSaved(); + CloseWindow?.Invoke(); + } + + [ObservableProperty] public partial bool WantsToReset { get; set; } public AsyncRelayCommand ResetButton => Commands.Create(async () => { @@ -932,10 +941,62 @@ namespace Ryujinx.Ava.UI.ViewModels "Configuration Reset"); }); - public void CancelButton() + public AsyncRelayCommand PurgeAllCaches => Commands.Create(async () => { - RevertIfNotSaved(); - CloseWindow?.Invoke(); - } + ObservableCollectionExtended appList = RyujinxApp.MainWindow.ViewModel.Applications; + + if (appList.Count == 0) + { + return; + } + + UserResult result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogWarning], + LocaleManager.Instance[LocaleKeys.DialogDeleteAllCaches], + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + + bool hasErrors = false; + + if (result != UserResult.Yes) + { + return; + } + + foreach (ApplicationData application in appList) + { + DirectoryInfo cacheDir = new(Path.Combine(AppDataManager.GamesDirPath, application.IdString, "cache")); + + if (!cacheDir.Exists) + { + continue; + } + + foreach (DirectoryInfo dInfo in cacheDir.EnumerateDirectories()) + { + try + { + dInfo.Delete(recursive: true); + } + catch (Exception ex) + { + Logger.Error?.PrintMsg(LogClass.Application, $"Failed to purge shader cache for {application.Name} ({application.IdString}): {ex}"); + hasErrors = true; + } + } + } + + if (hasErrors) + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogDeleteAllCachesErrorMessage]); + } + else + { + NotificationHelper.ShowSuccess( + title: LocaleManager.Instance[LocaleKeys.SettingsTabDebugPurgeAllCachesSuccessTitle], + text: LocaleManager.GetFormatted(LocaleKeys.SettingsTabDebugPurgeAllCachesSuccessText, appList.Count)); + } + }); } } diff --git a/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml index f491dda24..56a049d46 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml @@ -53,12 +53,17 @@ + diff --git a/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml.cs index 14a65b8b2..d68a2444c 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsDebugView.axaml.cs @@ -10,4 +10,3 @@ namespace Ryujinx.Ava.UI.Views.Settings } } } -