From f5982f81c09a72ad92bbea71e2b776eebb87dd71 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Thu, 30 May 2024 16:40:42 +0800 Subject: [PATCH] defer content load --- .../Control/Behavior/DeferLoadBehavior.cs | 44 ------------------- .../Control/Behavior/DeferLoadCollection.cs | 25 ----------- .../Snap.Hutao/Control/ScopedPage.cs | 2 + .../View/Helper/DeferContentLoader.cs | 24 ++++++++++ .../View/Helper/IDeferContentLoader.cs | 9 ++++ .../Snap.Hutao/View/Helper/LoadDeferral.cs | 15 ------- .../View/Page/AnnouncementPage.xaml | 4 +- .../View/Page/AnnouncementPage.xaml.cs | 2 +- .../ViewModel/Abstraction/IViewModel.cs | 16 ++----- .../ViewModel/Abstraction/ViewModel.cs | 3 ++ .../ViewModel/Home/AnnouncementViewModel.cs | 4 +- 11 files changed, 49 insertions(+), 99 deletions(-) delete mode 100644 src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadBehavior.cs delete mode 100644 src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadCollection.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/View/Helper/DeferContentLoader.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/View/Helper/IDeferContentLoader.cs delete mode 100644 src/Snap.Hutao/Snap.Hutao/View/Helper/LoadDeferral.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadBehavior.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadBehavior.cs deleted file mode 100644 index 27b52fbc..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadBehavior.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using CommunityToolkit.WinUI.Behaviors; -using Microsoft.UI.Xaml; -using System.Runtime.InteropServices; - -namespace Snap.Hutao.Control.Behavior; - -[DependencyProperty("ElementNames", typeof(DeferLoadCollection))] -internal sealed partial class DeferLoadBehavior : BehaviorBase -{ - protected override bool Initialize() - { - if (ElementNames.IsNullOrEmpty()) - { - return true; - } - - ThreadPool.UnsafeQueueUserWorkItem(LoadElements, this); - return true; - } - - private static void LoadElements(object? state) - { - if (state is not DeferLoadBehavior behavior) - { - return; - } - - List? elementNames = null; - behavior.AssociatedObject.DispatcherQueue.Invoke(() => elementNames = [.. behavior.ElementNames]); - - foreach (string name in CollectionsMarshal.AsSpan(elementNames)) - { - Thread.Sleep(1000); - - behavior.AssociatedObject.DispatcherQueue.TryEnqueue(() => - { - behavior.AssociatedObject.FindName(name); - }); - } - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadCollection.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadCollection.cs deleted file mode 100644 index c7ae5eb8..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/DeferLoadCollection.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Microsoft.Extensions.Primitives; -using Windows.Foundation.Metadata; - -namespace Snap.Hutao.Control.Behavior; - -[CreateFromString(MethodName = "Snap.Hutao.Control.Behavior.DeferLoadCollection.Parse")] -internal sealed class DeferLoadCollection : List -{ - public static DeferLoadCollection Parse(string text) - { - DeferLoadCollection collection = []; - foreach (StringSegment segment in new StringTokenizer(text, [','])) - { - if (segment.HasValue) - { - collection.Add(segment.Value); - } - } - - return collection; - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Control/ScopedPage.cs b/src/Snap.Hutao/Snap.Hutao/Control/ScopedPage.cs index 685f7f70..108bda3e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/ScopedPage.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/ScopedPage.cs @@ -5,6 +5,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; using Snap.Hutao.Service.Navigation; +using Snap.Hutao.View.Helper; using Snap.Hutao.ViewModel.Abstraction; namespace Snap.Hutao.Control; @@ -48,6 +49,7 @@ internal class ScopedPage : Page { IViewModel viewModel = pageScope.ServiceProvider.GetRequiredService(); viewModel.CancellationToken = viewCancellationTokenSource.Token; + viewModel.DeferContentLoader = new DeferContentLoader(this); DataContext = viewModel; } catch (Exception ex) diff --git a/src/Snap.Hutao/Snap.Hutao/View/Helper/DeferContentLoader.cs b/src/Snap.Hutao/Snap.Hutao/View/Helper/DeferContentLoader.cs new file mode 100644 index 00000000..969751ec --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/View/Helper/DeferContentLoader.cs @@ -0,0 +1,24 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.UI.Xaml; + +namespace Snap.Hutao.View.Helper; + +internal sealed class DeferContentLoader : IDeferContentLoader +{ + private readonly WeakReference reference = new(default!); + + public DeferContentLoader(FrameworkElement element) + { + this.reference.SetTarget(element); + } + + public void Load(string name) + { + if (reference.TryGetTarget(out FrameworkElement? element)) + { + element.FindName(name); + } + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Helper/IDeferContentLoader.cs b/src/Snap.Hutao/Snap.Hutao/View/Helper/IDeferContentLoader.cs new file mode 100644 index 00000000..99b61cdb --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/View/Helper/IDeferContentLoader.cs @@ -0,0 +1,9 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.View.Helper; + +internal interface IDeferContentLoader +{ + void Load(string name); +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Helper/LoadDeferral.cs b/src/Snap.Hutao/Snap.Hutao/View/Helper/LoadDeferral.cs deleted file mode 100644 index e4934471..00000000 --- a/src/Snap.Hutao/Snap.Hutao/View/Helper/LoadDeferral.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using CommunityToolkit.Mvvm.ComponentModel; -using Microsoft.Extensions.Primitives; -using Windows.Foundation.Metadata; - -namespace Snap.Hutao.View.Helper; - -internal sealed class LoadDeferral : ObservableObject -{ - private bool canLoad; - - public bool CanLoad { get => canLoad; set => SetProperty(ref canLoad, value); } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml index 061fbf99..29eef518 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml @@ -23,7 +23,6 @@ mc:Ignorable="d"> - @@ -218,9 +217,12 @@ diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml.cs index 845e8563..edb9bdd6 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml.cs @@ -20,4 +20,4 @@ internal sealed partial class AnnouncementPage : ScopedPage InitializeWith(); InitializeComponent(); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/IViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/IViewModel.cs index 54014fbe..51a1d39a 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/IViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/IViewModel.cs @@ -1,26 +1,18 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.View.Helper; + namespace Snap.Hutao.ViewModel.Abstraction; -/// -/// 视图模型接口 -/// [HighQuality] internal interface IViewModel : IPageScoped { - /// - /// 用于通知页面卸载的取消令牌 - /// CancellationToken CancellationToken { get; set; } - /// - /// 释放操作锁 - /// SemaphoreSlim DisposeLock { get; set; } - /// - /// 对应的视图是否已经释放 - /// + IDeferContentLoader DeferContentLoader { get; set; } + bool IsViewDisposed { get; set; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/ViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/ViewModel.cs index 30771548..e2025457 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/ViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Abstraction/ViewModel.cs @@ -3,6 +3,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using Snap.Hutao.Core.ExceptionService; +using Snap.Hutao.View.Helper; using System.Runtime.CompilerServices; namespace Snap.Hutao.ViewModel.Abstraction; @@ -22,6 +23,8 @@ internal abstract partial class ViewModel : ObservableObject, IViewModel public SemaphoreSlim DisposeLock { get; set; } = new(1); + public IDeferContentLoader DeferContentLoader { get; set; } = default!; + public bool IsViewDisposed { get; set; } protected TaskCompletionSource Initialization { get; } = new(); diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Home/AnnouncementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Home/AnnouncementViewModel.cs index d91a1820..e78f73c1 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Home/AnnouncementViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Home/AnnouncementViewModel.cs @@ -67,6 +67,7 @@ internal sealed partial class AnnouncementViewModel : Abstraction.ViewModel AnnouncementWrapper announcementWrapper = await announcementService.GetAnnouncementWrapperAsync(cultureOptions.LanguageCode, appOptions.Region, CancellationToken).ConfigureAwait(false); await taskContext.SwitchToMainThreadAsync(); Announcement = announcementWrapper; + DeferContentLoader.Load("GameAnnouncementPivot"); } catch (OperationCanceledException) { @@ -80,6 +81,7 @@ internal sealed partial class AnnouncementViewModel : Abstraction.ViewModel ObservableCollection hutaoAnnouncements = await hutaoAsAService.GetHutaoAnnouncementCollectionAsync().ConfigureAwait(false); await taskContext.SwitchToMainThreadAsync(); HutaoAnnouncements = hutaoAnnouncements; + DeferContentLoader.Load("HutaoAnnouncementControl"); } catch (OperationCanceledException) { @@ -141,4 +143,4 @@ internal sealed partial class AnnouncementViewModel : Abstraction.ViewModel Cards = result; } -} +} \ No newline at end of file