From 7cfcc17763b29a39d998296f74741efe89b80201 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Tue, 11 Jun 2024 14:00:48 +0800 Subject: [PATCH] refactor --- .../Extension/EnumerableExtension.List.cs | 14 ++++ .../Inventory/MinimalPromotionDelta.cs | 65 +++++++++++++------ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs index 14cab77b..ea0d0709 100644 --- a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs +++ b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs @@ -199,6 +199,13 @@ internal static partial class EnumerableExtension return list; } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static List SortBy(this List list, Func keySelector, Comparison comparison) + { + list.Sort((left, right) => comparison(keySelector(left), keySelector(right))); + return list; + } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static List SortByDescending(this List list, Func keySelector) where TKey : IComparable @@ -213,4 +220,11 @@ internal static partial class EnumerableExtension list.Sort((left, right) => comparer.Compare(keySelector(right), keySelector(left))); return list; } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static List SortByDescending(this List list, Func keySelector, Comparison comparison) + { + list.Sort((left, right) => comparison(keySelector(right), keySelector(left))); + return list; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Inventory/MinimalPromotionDelta.cs b/src/Snap.Hutao/Snap.Hutao/Service/Inventory/MinimalPromotionDelta.cs index 329ed1a5..1b5066ac 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Inventory/MinimalPromotionDelta.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Inventory/MinimalPromotionDelta.cs @@ -3,6 +3,7 @@ using Google.OrTools.LinearSolver; using Microsoft.Extensions.Caching.Memory; +using Snap.Hutao.Core; using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Primitive; @@ -35,7 +36,13 @@ internal sealed partial class MinimalPromotionDelta .. (await metadataService.GetAvatarListAsync().ConfigureAwait(false)).Where(a => a.BeginTime <= DateTimeOffset.Now), .. (await metadataService.GetWeaponListAsync().ConfigureAwait(false)).Where(w => w.Quality >= Model.Intrinsic.QualityType.QUALITY_BLUE), ]; - return memoryCache.Set(CacheKey, GeneratePromotionDeltas(Minimize(cultivationItemsEntryList))); + + List minimal = Minimize(cultivationItemsEntryList); + + // Gurantee the order of avatar and weapon + // Make sure weapons can have avatar to attach + minimal.Sort(CultivationItemsAccessComparer.Shared); + return memoryCache.Set(CacheKey, ToPromotionDeltaList(minimal)); } private static List Minimize(List cultivationItems) @@ -82,9 +89,10 @@ internal sealed partial class MinimalPromotionDelta } } - private static List GeneratePromotionDeltas(List cultivationItems) + private static List ToPromotionDeltaList(List cultivationItems) { List deltas = []; + int currentWeaponEmptyAvatarIndex = 0; foreach (ref readonly ICultivationItemsAccess item in CollectionsMarshal.AsSpan(cultivationItems)) { @@ -103,29 +111,27 @@ internal sealed partial class MinimalPromotionDelta LevelTarget = 10, }), }); - break; - case MetadataWeapon weapon: - if (deltas.FirstOrDefault(d => d.Weapon is null) is { } delta) - { - delta.Weapon = new() - { - Id = weapon.Id, - LevelCurrent = 1, - LevelTarget = 90, - }; - break; + break; + + case MetadataWeapon weapon: + AvatarPromotionDelta delta; + if (currentWeaponEmptyAvatarIndex < deltas.Count) + { + delta = deltas[currentWeaponEmptyAvatarIndex++]; + } + else + { + delta = new(); + deltas.Add(delta); } - deltas.Add(new() + delta.Weapon = new() { - Weapon = new() - { - Id = weapon.Id, - LevelCurrent = 1, - LevelTarget = 90, - }, - }); + Id = weapon.Id, + LevelCurrent = 1, + LevelTarget = 90, + }; break; } @@ -133,4 +139,21 @@ internal sealed partial class MinimalPromotionDelta return deltas; } + + private sealed class CultivationItemsAccessComparer : IComparer + { + private static readonly LazySlim LazyShared = new(() => new()); + + public static CultivationItemsAccessComparer Shared { get => LazyShared.Value; } + + public int Compare(ICultivationItemsAccess? x, ICultivationItemsAccess? y) + { + return (x, y) switch + { + (MetadataAvatar, MetadataWeapon) => -1, + (MetadataWeapon, MetadataAvatar) => 1, + _ => 0, + }; + } + } } \ No newline at end of file