From 3d1a365079e957aa75468cfba1b5f6dae794b494 Mon Sep 17 00:00:00 2001 From: goddessluboyan <739749502@qq.com> Date: Mon, 25 Mar 2024 20:37:51 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=AF=B9=E6=9D=90?= =?UTF-8?q?=E6=96=99=E7=BB=9F=E8=AE=A1=E9=A1=B5=E9=9D=A2=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E6=9D=90=E6=96=99=E5=81=9A=E5=88=9D=E6=AD=A5=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E3=80=82=20=E6=9B=B4=E7=BB=86=E8=87=B4=E7=9A=84=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E3=80=81=E5=88=86=E7=B1=BB=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E9=9B=86=E6=88=90=E8=A7=82=E6=B5=8B=E6=9E=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=89=8D=E8=83=BD=E8=BF=9B=E8=A1=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cultivation/CultivationViewModel.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs index fa7424cd..a2251ae4 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs @@ -10,6 +10,7 @@ using Snap.Hutao.Service.Navigation; using Snap.Hutao.Service.Notification; using Snap.Hutao.View.Dialog; using System.Collections.ObjectModel; +using System.Diagnostics; namespace Snap.Hutao.ViewModel.Cultivation; @@ -181,6 +182,15 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel { CultivationMetadataContext context = await metadataService.GetContextAsync().ConfigureAwait(false); statistics = await cultivationService.GetStatisticsCultivateItemCollectionAsync(SelectedProject, context, token).ConfigureAwait(false); + if (statistics is not null) + { + statistics = this.SortStatistics(statistics); + foreach (var item in statistics) + { + Debug.Print("Name: {0}, Id: {1}, Rank: {2}, Material: {3}, Item: {4}", + item.Inner.Name, item.Inner.Id.Value, item.Inner.RankLevel, item.Inner.MaterialType, item.Inner.ItemType); + } + } } catch (OperationCanceledException) { @@ -192,6 +202,35 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel } } + private ObservableCollection SortStatistics(ObservableCollection statistics) + { + return statistics.Order(new StatisticsCaltivateItemComparer()).ToObservableCollection(); + } + + private class StatisticsCaltivateItemComparer: IComparer + { + public int Compare(StatisticsCultivateItem? x, StatisticsCultivateItem? y) + { + // TODO: 理论上的最优解:先通过观测枢获取所有背包物品,然后根据filter字段依次分类,先按这个类别做排序,然后再按品质等进行排序 + // 不仅如此,以后想按照材料类型分类的话,这也是必做的。 + + // 对null做判定,防止IDE警告 + if (x is null) { return -1; } + if (y is null) { return -1; } + + // 摩拉、矿、经验书全局只出现一次,放在最前面 + if (x.Inner.Name == "摩拉") { return -1; } + if (y.Inner.Name == "摩拉") { return 1; } + if (x.Inner.Name == "精锻用魔矿") { return -1; } + if (y.Inner.Name == "精锻用魔矿") { return 1; } + if (x.Inner.Name == "大英雄的经验") { return -1; } + if (y.Inner.Name == "大英雄的经验") { return 1; } + + // 剩下的物品暂时按照id排序,更细致的排序策略以后再说 + return (int)x.Inner.Id.Value - (int)y.Inner.Id.Value; + } + } + [Command("NavigateToPageCommand")] private void NavigateToPage(string? typeString) { From 70399f7a7dadfaa12b6491723e11525ef6a1cb8d Mon Sep 17 00:00:00 2001 From: goddessluboyan <739749502@qq.com> Date: Mon, 25 Mar 2024 21:14:19 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/Cultivation/CultivationViewModel.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs index a2251ae4..36cdb993 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs @@ -10,7 +10,6 @@ using Snap.Hutao.Service.Navigation; using Snap.Hutao.Service.Notification; using Snap.Hutao.View.Dialog; using System.Collections.ObjectModel; -using System.Diagnostics; namespace Snap.Hutao.ViewModel.Cultivation; @@ -185,11 +184,6 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel if (statistics is not null) { statistics = this.SortStatistics(statistics); - foreach (var item in statistics) - { - Debug.Print("Name: {0}, Id: {1}, Rank: {2}, Material: {3}, Item: {4}", - item.Inner.Name, item.Inner.Id.Value, item.Inner.RankLevel, item.Inner.MaterialType, item.Inner.ItemType); - } } } catch (OperationCanceledException) From c4ff3599957df3ffeec634e256ee4a50a5a16d91 Mon Sep 17 00:00:00 2001 From: goddessluboyan <739749502@qq.com> Date: Mon, 25 Mar 2024 21:24:54 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/Cultivation/CultivationViewModel.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs index 36cdb993..45b30fb9 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs @@ -213,12 +213,12 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel if (y is null) { return -1; } // 摩拉、矿、经验书全局只出现一次,放在最前面 - if (x.Inner.Name == "摩拉") { return -1; } - if (y.Inner.Name == "摩拉") { return 1; } - if (x.Inner.Name == "精锻用魔矿") { return -1; } - if (y.Inner.Name == "精锻用魔矿") { return 1; } - if (x.Inner.Name == "大英雄的经验") { return -1; } - if (y.Inner.Name == "大英雄的经验") { return 1; } + if (x.Inner.Id.Value == 202U) { return -1; } // 摩拉 + if (y.Inner.Id.Value == 202U) { return 1; } + if (x.Inner.Id.Value == 104013U) { return -1; } // 精锻用魔矿 + if (y.Inner.Id.Value == 104013U) { return 1; } + if (x.Inner.Id.Value == 104003U) { return -1; } // 大英雄的经验 + if (y.Inner.Id.Value == 104003U) { return 1; } // 剩下的物品暂时按照id排序,更细致的排序策略以后再说 return (int)x.Inner.Id.Value - (int)y.Inner.Id.Value; From 089938c1c0434b2dca3abb8ddc672812a6370289 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Thu, 28 Mar 2024 13:16:40 +0800 Subject: [PATCH 4/4] code style --- .../Extension/EnumerableExtension.List.cs | 14 +++++++ .../Service/Cultivation/CultivationService.cs | 5 +-- .../Service/Cultivation/MaterialIdComparer.cs | 40 +++++++++++++++++++ .../MetadataServiceContextExtension.cs | 3 +- .../Cultivation/CultivationViewModel.cs | 33 --------------- 5 files changed, 57 insertions(+), 38 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Cultivation/MaterialIdComparer.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs index 049bc56e..40d24286 100644 --- a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs +++ b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs @@ -200,6 +200,13 @@ internal static partial class EnumerableExtension return list; } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static List SortBy(this List list, Func keySelector, IComparer comparer) + { + list.Sort((left, right) => comparer.Compare(keySelector(left), keySelector(right))); + return list; + } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static List SortByDescending(this List list, Func keySelector) where TKey : IComparable @@ -207,4 +214,11 @@ internal static partial class EnumerableExtension list.Sort((left, right) => keySelector(right).CompareTo(keySelector(left))); return list; } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static List SortByDescending(this List list, Func keySelector, IComparer comparer) + { + list.Sort((left, right) => comparer.Compare(keySelector(right), keySelector(left))); + return list; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index d3a93bfc..93cd54e5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -126,10 +126,7 @@ internal sealed partial class CultivationService : ICultivationService token.ThrowIfCancellationRequested(); - return resultItems - .OrderByDescending(i => i.TotalCount) - .ThenByDescending(i => i.Count) - .ToObservableCollection(); + return resultItems.SortBy(item => item.Inner.Id, MaterialIdComparer.Shared).ToObservableCollection(); } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/MaterialIdComparer.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/MaterialIdComparer.cs new file mode 100644 index 00000000..236e1d2a --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/MaterialIdComparer.cs @@ -0,0 +1,40 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Model.Primitive; +using Snap.Hutao.ViewModel.Cultivation; + +namespace Snap.Hutao.Service.Cultivation; + +internal sealed class MaterialIdComparer : IComparer +{ + private static readonly Lazy LazyShared = new(() => new()); + + public static MaterialIdComparer Shared { get => LazyShared.Value; } + + public int Compare(MaterialId x, MaterialId y) + { + return Transform(x).CompareTo(Transform(y)); + } + + private static uint Transform(MaterialId value) + { + return value.Value switch + { + // 摩拉 + 202U => 0U, + + // 经验 + 104001U => 1U, + 104002U => 2U, + 104003U => 3U, + + // 魔矿 + 104011U => 4U, + 104012U => 5U, + 104013U => 6U, + + _ => value, + }; + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs index f511bc7a..529fda39 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs @@ -5,6 +5,7 @@ using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Cultivation; namespace Snap.Hutao.Service.Metadata.ContextAbstraction; @@ -67,7 +68,7 @@ internal static class MetadataServiceContextExtension #pragma warning disable SH002 public static IEnumerable EnumerateInventoryMaterial(this IMetadataListMaterialSource context) { - return context.Materials.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id.Value); + return context.Materials.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id, MaterialIdComparer.Shared); } public static Avatar GetAvatar(this IMetadataDictionaryIdAvatarSource context, AvatarId id) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs index 45b30fb9..fa7424cd 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivationViewModel.cs @@ -181,10 +181,6 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel { CultivationMetadataContext context = await metadataService.GetContextAsync().ConfigureAwait(false); statistics = await cultivationService.GetStatisticsCultivateItemCollectionAsync(SelectedProject, context, token).ConfigureAwait(false); - if (statistics is not null) - { - statistics = this.SortStatistics(statistics); - } } catch (OperationCanceledException) { @@ -196,35 +192,6 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel } } - private ObservableCollection SortStatistics(ObservableCollection statistics) - { - return statistics.Order(new StatisticsCaltivateItemComparer()).ToObservableCollection(); - } - - private class StatisticsCaltivateItemComparer: IComparer - { - public int Compare(StatisticsCultivateItem? x, StatisticsCultivateItem? y) - { - // TODO: 理论上的最优解:先通过观测枢获取所有背包物品,然后根据filter字段依次分类,先按这个类别做排序,然后再按品质等进行排序 - // 不仅如此,以后想按照材料类型分类的话,这也是必做的。 - - // 对null做判定,防止IDE警告 - if (x is null) { return -1; } - if (y is null) { return -1; } - - // 摩拉、矿、经验书全局只出现一次,放在最前面 - if (x.Inner.Id.Value == 202U) { return -1; } // 摩拉 - if (y.Inner.Id.Value == 202U) { return 1; } - if (x.Inner.Id.Value == 104013U) { return -1; } // 精锻用魔矿 - if (y.Inner.Id.Value == 104013U) { return 1; } - if (x.Inner.Id.Value == 104003U) { return -1; } // 大英雄的经验 - if (y.Inner.Id.Value == 104003U) { return 1; } - - // 剩下的物品暂时按照id排序,更细致的排序策略以后再说 - return (int)x.Inner.Id.Value - (int)y.Inner.Id.Value; - } - } - [Command("NavigateToPageCommand")] private void NavigateToPage(string? typeString) {