diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs index fd04204d..2ccf0181 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs @@ -31,9 +31,7 @@ internal sealed partial class AchievementService : IAchievementService if (archives is null) { await taskContext.SwitchToBackgroundAsync(); - ObservableCollection source = achievementDbService.GetAchievementArchiveCollection(); - await taskContext.SwitchToMainThreadAsync(); - archives = new(source, serviceProvider); + archives = new(achievementDbService.GetAchievementArchiveCollection(), serviceProvider); } return archives; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs index bc34e634..02aa3da0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs @@ -17,7 +17,6 @@ namespace Snap.Hutao.Service.AvatarInfo.Factory; internal sealed partial class SummaryFactory : ISummaryFactory { private readonly IMetadataService metadataService; - private readonly ITaskContext taskContext; /// public async ValueTask CreateAsync(IEnumerable avatarInfos, CancellationToken token) @@ -37,8 +36,6 @@ internal sealed partial class SummaryFactory : ISummaryFactory IList views = [.. avatars]; - await taskContext.SwitchToMainThreadAsync(); - return new() { Avatars = new(views), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs index e937db1d..a25c75bf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs @@ -212,7 +212,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory return new() { // history - HistoryWishes = taskContext.InvokeOnMainThread(() => new AdvancedCollectionView(historyWishes)), + HistoryWishes = new(historyWishes), // avatars OrangeAvatars = orangeAvatarCounter.ToStatisticsList(), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index 2e9f695a..9538d62a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -47,7 +47,6 @@ internal sealed partial class GachaLogService : IGachaLogService if (await metadataService.InitializeAsync().ConfigureAwait(false)) { context = await metadataService.GetContextAsync(token).ConfigureAwait(false); - await taskContext.SwitchToMainThreadAsync(); Archives = new(gachaLogDbService.GetGachaArchiveCollection(), serviceProvider); return true; } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/UserInitializationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/UserInitializationService.cs index 0aa3206f..612fec23 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/UserInitializationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/UserInitializationService.cs @@ -29,7 +29,7 @@ internal sealed partial class UserInitializationService : IUserInitializationSer user.UserInfo = new() { Nickname = SH.ModelBindingUserInitializationFailed }; await taskContext.SwitchToMainThreadAsync(); - user.UserGameRoles = []; + user.UserGameRoles = new([]); } return user; @@ -213,7 +213,6 @@ internal sealed partial class UserInitializationService : IUserInitializationSer if (userGameRolesResponse.IsOk()) { - await taskContext.SwitchToMainThreadAsync(); user.UserGameRoles = new(userGameRolesResponse.Data.List); return user.UserGameRoles.Count > 0; } diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs index 99612fef..ad9003c8 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs @@ -28,11 +28,6 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr private int deferCounter; private WeakEventListener, object?, NotifyCollectionChangedEventArgs>? sourceWeakEventListener; - public AdvancedCollectionView() - : this([]) - { - } - public AdvancedCollectionView(IList source) { view = []; @@ -633,9 +628,8 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr return false; } - CurrentChangingEventArgs e = new(); - OnCurrentChanging(e); - if (e.Cancel) + OnCurrentChanging(out bool cancel); + if (cancel) { return false; } @@ -645,14 +639,17 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr return true; } - private void OnCurrentChanging(CurrentChangingEventArgs e) + private void OnCurrentChanging(out bool cancel) { if (!created || deferCounter > 0) { + cancel = false; return; } + CurrentChangingEventArgs e = new(); CurrentChanging?.Invoke(this, e); + cancel = e.Cancel; } private void OnCurrentChanged() diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionViewExtension.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionViewExtension.cs index 3a605fd6..0a45c981 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionViewExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionViewExtension.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using System.Runtime.CompilerServices; + namespace Snap.Hutao.UI.Xaml.Data; internal static class AdvancedCollectionViewExtension @@ -13,4 +15,11 @@ internal static class AdvancedCollectionViewExtension view.MoveCurrentTo(default); } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AdvancedCollectionView ToAdvancedCollectionView(this IList source) + where T : class, IAdvancedCollectionViewItem + { + return new AdvancedCollectionView(source); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs index 352e5e97..02117d00 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs @@ -126,7 +126,7 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav return false; } - List sortedGoals; + AdvancedCollectionView sortedGoals; using (await EnterCriticalSectionAsync().ConfigureAwait(false)) { @@ -134,13 +134,13 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav .GetAchievementGoalListAsync(CancellationToken) .ConfigureAwait(false); - sortedGoals = goals.SortBy(goal => goal.Order).SelectList(AchievementGoalView.From); + sortedGoals = goals.SortBy(goal => goal.Order).SelectList(AchievementGoalView.From).ToAdvancedCollectionView(); } IAdvancedDbCollectionView archives = await scopeContext.AchievementService.GetArchivesAsync(CancellationToken).ConfigureAwait(false); await scopeContext.TaskContext.SwitchToMainThreadAsync(); - AchievementGoals = new(sortedGoals); + AchievementGoals = sortedGoals; Archives = archives; Archives.MoveCurrentTo(Archives.SourceCollection.SelectedOrDefault()); return true; @@ -298,8 +298,10 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav return; } + AdvancedCollectionView achievements = new(combined); + await scopeContext.TaskContext.SwitchToMainThreadAsync(); - Achievements = new(combined); + Achievements = achievements; AchievementFinishPercent.Update(this); UpdateAchievementsFilterByGoal(AchievementGoals?.CurrentItem); UpdateAchievementsSort(); diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs index 25be22b8..24f76e87 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs @@ -326,12 +326,10 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView { gameAccountFilter = new(SelectedScheme?.GetSchemeType()); ObservableReorderableDbCollection accounts = gameService.GameAccountCollection; + AdvancedCollectionView accountsView = new(accounts) { Filter = gameAccountFilter.Filter }; await taskContext.SwitchToMainThreadAsync(); - GameAccountsView = new(accounts) - { - Filter = gameAccountFilter.Filter, - }; + GameAccountsView = accountsView; } } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModelSlim.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModelSlim.cs index 4ff44e5e..3bc49e15 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModelSlim.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModelSlim.cs @@ -59,12 +59,10 @@ internal sealed partial class LaunchGameViewModelSlim : Abstraction.ViewModelSli } gameAccountFilter = new(scheme?.GetSchemeType()); + AdvancedCollectionView accountsView = new(accounts) { Filter = gameAccountFilter.Filter }; await taskContext.SwitchToMainThreadAsync(); - GameAccountsView = new(accounts) - { - Filter = gameAccountFilter.Filter, - }; + GameAccountsView = accountsView; } [Command("LaunchCommand")] diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/SpiralAbyssRecordViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/SpiralAbyssRecordViewModel.cs index deff8b5b..042466d0 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/SpiralAbyssRecordViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/SpiralAbyssRecordViewModel.cs @@ -85,8 +85,10 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel .ConfigureAwait(false); } + AdvancedCollectionView spiralAbyssEntries = new(collection); + await taskContext.SwitchToMainThreadAsync(); - SpiralAbyssEntries = new(collection); + SpiralAbyssEntries = spiralAbyssEntries; SpiralAbyssEntries.MoveCurrentTo(SpiralAbyssEntries.SourceCollection.FirstOrDefault(s => s.Engaged)); } catch (OperationCanceledException) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs index b2859b08..626523ef 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs @@ -109,8 +109,12 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel using (await EnterCriticalSectionAsync().ConfigureAwait(false)) { + AdvancedCollectionView avatarsView = new(list); + await taskContext.SwitchToMainThreadAsync(); - Avatars = new(list); + Avatars = avatarsView; + + // TODO: use CurrentItem Selected = Avatars.View.ElementAtOrDefault(0); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs index 0a711e7d..74e1d10c 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs @@ -68,8 +68,12 @@ internal sealed partial class WikiMonsterViewModel : Abstraction.ViewModel using (await EnterCriticalSectionAsync().ConfigureAwait(false)) { + AdvancedCollectionView monstersView = new(ordered); + await taskContext.SwitchToMainThreadAsync(); - Monsters = new(ordered); + Monsters = monstersView; + + // TODO: use CurrentItem Selected = Monsters.View.ElementAtOrDefault(0); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs index c57502c3..1a0cec91 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs @@ -108,9 +108,13 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel using (await EnterCriticalSectionAsync().ConfigureAwait(false)) { + AdvancedCollectionView weaponsView = new(list); + await taskContext.SwitchToMainThreadAsync(); - Weapons = new(list); + Weapons = weaponsView; + + // TODO: use CurrentItem Selected = Weapons.View.ElementAtOrDefault(0); }