SaveManager.axaml.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using Avalonia.Controls;
  2. using DynamicData;
  3. using DynamicData.Binding;
  4. using LibHac;
  5. using LibHac.Common;
  6. using LibHac.Fs;
  7. using LibHac.Fs.Shim;
  8. using Ryujinx.Ava.Common;
  9. using Ryujinx.Ava.Common.Locale;
  10. using Ryujinx.Ava.Ui.Models;
  11. using Ryujinx.HLE.FileSystem;
  12. using Ryujinx.Ui.App.Common;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Collections.ObjectModel;
  16. using System.Threading.Tasks;
  17. using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
  18. namespace Ryujinx.Ava.Ui.Controls
  19. {
  20. public partial class SaveManager : UserControl
  21. {
  22. private readonly UserProfile _userProfile;
  23. private readonly HorizonClient _horizonClient;
  24. private readonly VirtualFileSystem _virtualFileSystem;
  25. private int _sortIndex;
  26. private int _orderIndex;
  27. private ObservableCollection<SaveModel> _view = new ObservableCollection<SaveModel>();
  28. private string _search;
  29. public ObservableCollection<SaveModel> Saves { get; set; } = new ObservableCollection<SaveModel>();
  30. public ObservableCollection<SaveModel> View
  31. {
  32. get => _view;
  33. set => _view = value;
  34. }
  35. public int SortIndex
  36. {
  37. get => _sortIndex;
  38. set
  39. {
  40. _sortIndex = value;
  41. Sort();
  42. }
  43. }
  44. public int OrderIndex
  45. {
  46. get => _orderIndex;
  47. set
  48. {
  49. _orderIndex = value;
  50. Sort();
  51. }
  52. }
  53. public string Search
  54. {
  55. get => _search;
  56. set
  57. {
  58. _search = value;
  59. Sort();
  60. }
  61. }
  62. public SaveManager()
  63. {
  64. InitializeComponent();
  65. }
  66. public SaveManager(UserProfile userProfile, HorizonClient horizonClient, VirtualFileSystem virtualFileSystem)
  67. {
  68. _userProfile = userProfile;
  69. _horizonClient = horizonClient;
  70. _virtualFileSystem = virtualFileSystem;
  71. InitializeComponent();
  72. DataContext = this;
  73. Task.Run(LoadSaves);
  74. }
  75. public void LoadSaves()
  76. {
  77. Saves.Clear();
  78. var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account,
  79. new UserId((ulong)_userProfile.UserId.High, (ulong)_userProfile.UserId.Low), saveDataId: default, index: default);
  80. using var saveDataIterator = new UniqueRef<SaveDataIterator>();
  81. _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref(), SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
  82. Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
  83. while (true)
  84. {
  85. saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
  86. if (readCount == 0)
  87. {
  88. break;
  89. }
  90. for (int i = 0; i < readCount; i++)
  91. {
  92. var save = saveDataInfo[i];
  93. if (save.ProgramId.Value != 0)
  94. {
  95. var saveModel = new SaveModel(save, _horizonClient, _virtualFileSystem);
  96. Saves.Add(saveModel);
  97. saveModel.DeleteAction = () => { Saves.Remove(saveModel); };
  98. }
  99. Sort();
  100. }
  101. }
  102. }
  103. private void Sort()
  104. {
  105. Saves.AsObservableChangeSet()
  106. .Filter(Filter)
  107. .Sort(GetComparer())
  108. .Bind(out var view).AsObservableList();
  109. _view.Clear();
  110. _view.AddRange(view);
  111. }
  112. private IComparer<SaveModel> GetComparer()
  113. {
  114. switch (SortIndex)
  115. {
  116. case 0:
  117. return OrderIndex == 0
  118. ? SortExpressionComparer<SaveModel>.Ascending(save => save.Title)
  119. : SortExpressionComparer<SaveModel>.Descending(save => save.Title);
  120. case 1:
  121. return OrderIndex == 0
  122. ? SortExpressionComparer<SaveModel>.Ascending(save => save.Size)
  123. : SortExpressionComparer<SaveModel>.Descending(save => save.Size);
  124. default:
  125. return null;
  126. }
  127. }
  128. private bool Filter(object arg)
  129. {
  130. if (arg is SaveModel save)
  131. {
  132. return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
  133. }
  134. return false;
  135. }
  136. }
  137. }