From 6a42c36a76deec5503b72721ab41129c628dea0c Mon Sep 17 00:00:00 2001
From: Lightczx <1686188646@qq.com>
Date: Thu, 25 Apr 2024 14:44:06 +0800
Subject: [PATCH] optimization
---
.../AvatarInfo/AvatarInfoDbBulkOperation.cs | 131 +++++++-----------
.../Service/AvatarInfo/AvatarInfoService.cs | 2 +-
.../Factory/Builder/AvatarViewBuilder.cs | 6 +-
.../Builder/AvatarViewBuilderExtension.cs | 60 +++-----
.../Builder/EquipViewBuilderExtension.cs | 33 +++++
.../Factory/Builder/IAvatarViewBuilder.cs | 5 +-
.../Factory/Builder/IEquipViewBuilder.cs | 11 ++
.../Builder/INameIconDescriptionBuilder.cs | 13 ++
.../Factory/Builder/IReliquaryViewBuilder.cs | 10 ++
.../Factory/Builder/IScoreAccess.cs | 9 ++
.../Factory/Builder/IWeaponViewBuilder.cs | 5 +-
.../NameIconDescriptionBuilderExtension.cs | 33 +++++
.../Factory/Builder/ReliquaryViewBuilder.cs | 13 ++
.../Builder/ReliquaryViewBuilderExtension.cs | 66 +++++++++
.../Factory/Builder/ScoreAccessExtension.cs | 16 +++
.../Factory/Builder/WeaponViewBuilder.cs | 4 +-
.../Builder/WeaponViewBuilderExtension.cs | 29 ++--
.../Factory/SummaryAvatarFactory.cs | 6 +-
.../AvatarInfo/Factory/SummaryHelper.cs | 3 -
.../Factory/SummaryReliquaryFactory.cs | 114 +++++++--------
...culateAvatarDetailAvatarInfoTransformer.cs | 2 +-
...ameRecordCharacterAvatarInfoTransformer.cs | 2 +-
.../Transformer/IAvatarInfoTransformer.cs | 2 +-
.../Snap.Hutao/View/Control/SkillPivot.xaml | 4 +-
.../Snap.Hutao/View/Guide/GuideView.xaml | 2 +-
.../View/Page/AvatarPropertyPage.xaml | 4 +-
.../ViewModel/AvatarProperty/AvatarView.cs | 9 +-
27 files changed, 374 insertions(+), 220 deletions(-)
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/EquipViewBuilderExtension.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/IEquipViewBuilder.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/INameIconDescriptionBuilder.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/IReliquaryViewBuilder.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/IScoreAccess.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/NameIconDescriptionBuilderExtension.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/ReliquaryViewBuilder.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/ReliquaryViewBuilderExtension.cs
create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/ScoreAccessExtension.cs
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
index 50750d87..626a2d3c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
@@ -12,7 +12,9 @@ using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar;
using Snap.Hutao.Web.Response;
+using System.Reflection.Emit;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using CalculateAvatar = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Avatar;
using EnkaAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo;
using EntityAvatarInfo = Snap.Hutao.Model.Entity.AvatarInfo;
@@ -21,9 +23,6 @@ using RecordPlayerInfo = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.PlayerInfo;
namespace Snap.Hutao.Service.AvatarInfo;
-///
-/// 角色信息数据库操作
-///
[HighQuality]
[ConstructorGenerated]
[Injection(InjectAs.Singleton)]
@@ -32,18 +31,10 @@ internal sealed partial class AvatarInfoDbBulkOperation
private readonly IServiceProvider serviceProvider;
private readonly IAvatarInfoDbService avatarInfoDbService;
- ///
- /// 更新数据库角色信息
- ///
- /// uid
- /// Enka信息
- /// 取消令牌
- /// 角色列表
- public List UpdateDbAvatarInfosByShowcase(string uid, IEnumerable webInfos, CancellationToken token)
+ public async ValueTask> UpdateDbAvatarInfosByShowcaseAsync(string uid, IEnumerable webInfos, CancellationToken token)
{
- token.ThrowIfCancellationRequested();
- List dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
- EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
+ List dbInfos = await avatarInfoDbService.GetAvatarInfoListByUidAsync(uid).ConfigureAwait(false);
+ EnsureItemsAvatarIdUnique(ref dbInfos, uid, out Dictionary dbInfoMap);
using (IServiceScope scope = serviceProvider.CreateScope())
{
@@ -56,28 +47,19 @@ internal sealed partial class AvatarInfoDbBulkOperation
continue;
}
- token.ThrowIfCancellationRequested();
- EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == webInfo.AvatarId);
+ EntityAvatarInfo? entity = dbInfoMap.GetValueOrDefault(webInfo.AvatarId);
AddOrUpdateAvatarInfo(entity, uid, appDbContext, webInfo);
}
- token.ThrowIfCancellationRequested();
- return avatarInfoDbService.GetAvatarInfoListByUid(uid);
+ return await avatarInfoDbService.GetAvatarInfoListByUidAsync(uid).ConfigureAwait(false);
}
}
- ///
- /// 米游社我的角色方式 更新数据库角色信息
- ///
- /// 用户与角色
- /// 取消令牌
- /// 角色列表
public async ValueTask> UpdateDbAvatarInfosByGameRecordCharacterAsync(UserAndUid userAndUid, CancellationToken token)
{
- token.ThrowIfCancellationRequested();
string uid = userAndUid.Uid.Value;
List dbInfos = await avatarInfoDbService.GetAvatarInfoListByUidAsync(uid).ConfigureAwait(false);
- EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
+ EnsureItemsAvatarIdUnique(ref dbInfos, uid, out Dictionary dbInfoMap);
using (IServiceScope scope = serviceProvider.CreateScope())
{
@@ -90,51 +72,47 @@ internal sealed partial class AvatarInfoDbBulkOperation
.GetPlayerInfoAsync(userAndUid, token)
.ConfigureAwait(false);
- if (playerInfoResponse.IsOk())
+ if (!playerInfoResponse.IsOk())
{
- Response charactersResponse = await gameRecordClient
- .GetCharactersAsync(userAndUid, playerInfoResponse.Data, token)
- .ConfigureAwait(false);
+ goto Return;
+ }
- token.ThrowIfCancellationRequested();
+ Response charactersResponse = await gameRecordClient
+ .GetCharactersAsync(userAndUid, playerInfoResponse.Data, token)
+ .ConfigureAwait(false);
- if (charactersResponse.IsOk())
+ if (!charactersResponse.IsOk())
+ {
+ goto Return;
+ }
+
+ List characters = charactersResponse.Data.Avatars;
+
+ GameRecordCharacterAvatarInfoTransformer transformer = serviceProvider
+ .GetRequiredService();
+
+ foreach (RecordCharacter character in characters)
+ {
+ if (AvatarIds.IsPlayer(character.Id))
{
- List characters = charactersResponse.Data.Avatars;
-
- GameRecordCharacterAvatarInfoTransformer transformer = serviceProvider
- .GetRequiredService();
-
- foreach (RecordCharacter character in characters)
- {
- if (AvatarIds.IsPlayer(character.Id))
- {
- continue;
- }
-
- token.ThrowIfCancellationRequested();
- EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == character.Id);
- AddOrUpdateAvatarInfo(entity, character.Id, uid, appDbContext, transformer, character);
- }
+ continue;
}
+
+ EntityAvatarInfo? entity = dbInfoMap.GetValueOrDefault(character.Id);
+ AddOrUpdateAvatarInfo(entity, character.Id, uid, appDbContext, transformer, character);
}
}
+ Return:
return await avatarInfoDbService.GetAvatarInfoListByUidAsync(uid).ConfigureAwait(false);
}
- ///
- /// 米游社养成计算方式 更新数据库角色信息
- ///
- /// 用户与角色
- /// 取消令牌
- /// 角色列表
public async ValueTask> UpdateDbAvatarInfosByCalculateAvatarDetailAsync(UserAndUid userAndUid, CancellationToken token)
{
token.ThrowIfCancellationRequested();
string uid = userAndUid.Uid.Value;
List dbInfos = await avatarInfoDbService.GetAvatarInfoListByUidAsync(uid).ConfigureAwait(false);
- EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
+ EnsureItemsAvatarIdUnique(ref dbInfos, uid, out Dictionary dbInfoMap);
using (IServiceScope scope = serviceProvider.CreateScope())
{
@@ -155,8 +133,6 @@ internal sealed partial class AvatarInfoDbBulkOperation
continue;
}
- token.ThrowIfCancellationRequested();
-
Response detailAvatarResponse = await calculateClient
.GetAvatarDetailAsync(userAndUid, avatar, token)
.ConfigureAwait(false);
@@ -166,8 +142,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
continue;
}
- token.ThrowIfCancellationRequested();
- EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == avatar.Id);
+ EntityAvatarInfo? entity = dbInfoMap.GetValueOrDefault(avatar.Id);
AddOrUpdateAvatarInfo(entity, avatar.Id, uid, appDbContext, transformer, detailAvatarResponse.Data);
}
}
@@ -181,15 +156,14 @@ internal sealed partial class AvatarInfoDbBulkOperation
if (entity is null)
{
entity = EntityAvatarInfo.From(uid, webInfo);
- entity.ShowcaseRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.AddAndSave(entity);
}
else
{
entity.Info = webInfo;
- entity.ShowcaseRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.UpdateAndSave(entity);
}
+
+ entity.ShowcaseRefreshTime = DateTimeOffset.UtcNow;
+ appDbContext.AvatarInfos.UpdateAndSave(entity);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -200,17 +174,16 @@ internal sealed partial class AvatarInfoDbBulkOperation
EnkaAvatarInfo avatarInfo = new() { AvatarId = avatarId };
transformer.Transform(ref avatarInfo, source);
entity = EntityAvatarInfo.From(uid, avatarInfo);
- entity.CalculatorRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.AddAndSave(entity);
}
else
{
EnkaAvatarInfo avatarInfo = entity.Info;
transformer.Transform(ref avatarInfo, source);
entity.Info = avatarInfo;
- entity.CalculatorRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.UpdateAndSave(entity);
}
+
+ entity.CalculatorRefreshTime = DateTimeOffset.UtcNow;
+ appDbContext.AvatarInfos.UpdateAndSave(entity);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -221,29 +194,29 @@ internal sealed partial class AvatarInfoDbBulkOperation
EnkaAvatarInfo avatarInfo = new() { AvatarId = avatarId };
transformer.Transform(ref avatarInfo, source);
entity = EntityAvatarInfo.From(uid, avatarInfo);
- entity.GameRecordRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.AddAndSave(entity);
}
else
{
EnkaAvatarInfo avatarInfo = entity.Info;
transformer.Transform(ref avatarInfo, source);
entity.Info = avatarInfo;
- entity.GameRecordRefreshTime = DateTimeOffset.UtcNow;
- appDbContext.AvatarInfos.UpdateAndSave(entity);
}
+
+ entity.GameRecordRefreshTime = DateTimeOffset.UtcNow;
+ appDbContext.AvatarInfos.UpdateAndSave(entity);
}
- private void EnsureItemsAvatarIdDistinct(ref List dbInfos, string uid)
+ private void EnsureItemsAvatarIdUnique(ref List dbInfos, string uid, out Dictionary dbInfoMap)
{
- int distinctCount = dbInfos.Select(info => info.Info.AvatarId).ToHashSet().Count;
-
- // Avatars are actually less than the list told us.
- // This means that there are duplicate items.
- if (distinctCount < dbInfos.Count)
+ dbInfoMap = [];
+ foreach (ref readonly EntityAvatarInfo info in CollectionsMarshal.AsSpan(dbInfos))
{
- avatarInfoDbService.RemoveAvatarInfoRangeByUid(uid);
- dbInfos = [];
+ if (!dbInfoMap.TryAdd(info.Info.AvatarId, info))
+ {
+ avatarInfoDbService.RemoveAvatarInfoRangeByUid(uid);
+ dbInfoMap.Clear();
+ dbInfos.Clear();
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs
index 44ed0d8b..1846f283 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoService.cs
@@ -52,7 +52,7 @@ internal sealed partial class AvatarInfoService : IAvatarInfoService
return new(RefreshResult.ShowcaseNotOpen, default);
}
- List list = avatarInfoDbBulkOperation.UpdateDbAvatarInfosByShowcase(userAndUid.Uid.Value, resp.AvatarInfoList, token);
+ List list = await avatarInfoDbBulkOperation.UpdateDbAvatarInfosByShowcaseAsync(userAndUid.Uid.Value, resp.AvatarInfoList, token);
Summary summary = await GetSummaryCoreAsync(list, token).ConfigureAwait(false);
return new(RefreshResult.Ok, summary);
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilder.cs
index bb9a2004..7b8e05cb 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilder.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilder.cs
@@ -1,9 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.ViewModel.AvatarProperty;
+
namespace Snap.Hutao.Service.AvatarInfo.Factory.Builder;
internal sealed class AvatarViewBuilder : IAvatarViewBuilder
{
- public ViewModel.AvatarProperty.AvatarView AvatarView { get; } = new();
+ public AvatarView View { get; } = new();
+
+ public float Score { get => View.Score; set => View.Score = value; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilderExtension.cs
index 30c5806d..12b2164a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilderExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/Builder/AvatarViewBuilderExtension.cs
@@ -20,13 +20,13 @@ internal static class AvatarViewBuilderExtension
Costume costume = avatar.Costumes.Single(c => c.Id == id);
// Set to costume icon
- builder.AvatarView.Icon = AvatarIconConverter.IconNameToUri(costume.FrontIcon);
- builder.AvatarView.SideIcon = AvatarIconConverter.IconNameToUri(costume.SideIcon);
+ builder.View.Icon = AvatarIconConverter.IconNameToUri(costume.FrontIcon);
+ builder.View.SideIcon = AvatarIconConverter.IconNameToUri(costume.SideIcon);
}
else
{
- builder.AvatarView.Icon = AvatarIconConverter.IconNameToUri(avatar.Icon);
- builder.AvatarView.SideIcon = AvatarIconConverter.IconNameToUri(avatar.SideIcon);
+ builder.View.Icon = AvatarIconConverter.IconNameToUri(avatar.Icon);
+ builder.View.SideIcon = AvatarIconConverter.IconNameToUri(avatar.SideIcon);
}
return builder;
@@ -41,7 +41,7 @@ internal static class AvatarViewBuilderExtension
public static TBuilder SetCalculatorRefreshTimeFormat(this TBuilder builder, string calculatorRefreshTimeFormat)
where TBuilder : IAvatarViewBuilder
{
- return builder.Configure(b => b.AvatarView.CalculatorRefreshTimeFormat = calculatorRefreshTimeFormat);
+ return builder.Configure(b => b.View.CalculatorRefreshTimeFormat = calculatorRefreshTimeFormat);
}
public static TBuilder SetConstellations(this TBuilder builder, List talents, List? talentIds)
@@ -65,7 +65,7 @@ internal static class AvatarViewBuilderExtension
public static TBuilder SetConstellations(this TBuilder builder, List constellations)
where TBuilder : IAvatarViewBuilder
{
- return builder.Configure(b => b.AvatarView.Constellations = constellations);
+ return builder.Configure(b => b.View.Constellations = constellations);
}
public static TBuilder SetCritScore(this TBuilder builder, Dictionary? fightPropMap)
@@ -90,19 +90,13 @@ internal static class AvatarViewBuilderExtension
public static TBuilder SetCritScore(this TBuilder builder, float critScore)
where TBuilder : IAvatarViewBuilder
{
- return builder.SetCritScore($"{critScore:F2}");
- }
-
- public static TBuilder SetCritScore(this TBuilder builder, string critScore)
- where TBuilder : IAvatarViewBuilder
- {
- return builder.Configure(b => b.AvatarView.CritScore = critScore);
+ return builder.Configure(b => b.View.CritScore = critScore);
}
public static TBuilder SetElement(this TBuilder builder, ElementType element)
where TBuilder : IAvatarViewBuilder
{
- return builder.Configure(b => b.AvatarView.Element = element);
+ return builder.Configure(b => b.View.Element = element);
}
public static TBuilder SetFetterLevel(this TBuilder builder, FetterLevel? level)
@@ -110,7 +104,7 @@ internal static class AvatarViewBuilderExtension
{
if (level.TryGetValue(out FetterLevel value))
{
- return builder.Configure(b => b.AvatarView.FetterLevel = value);
+ return builder.Configure(b => b.View.FetterLevel = value);
}
return builder;
@@ -119,7 +113,7 @@ internal static class AvatarViewBuilderExtension
public static TBuilder SetFetterLevel(this TBuilder builder, uint level)
where TBuilder : IAvatarViewBuilder
{
- return builder.Configure(b => b.AvatarView.FetterLevel = level);
+ return builder.Configure(b => b.View.FetterLevel = level);
}
public static TBuilder SetGameRecordRefreshTimeFormat(this TBuilder builder, DateTimeOffset refreshTime, Func