From 2b851a5459e2ce2d301763ac8a9f17b191200620 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Fri, 1 Dec 2023 14:58:10 +0800 Subject: [PATCH] activation optimization --- .../BaseClassLibrary/JsonSerializeTest.cs | 2 +- .../BaseClassLibrary/TypeReflectionTest.cs | 19 ++++ .../Snap.Hutao/Core/LifeCycle/Activation.cs | 86 ++++++++++--------- .../Snap.Hutao/Core/Setting/LocalSetting.cs | 30 ++++--- .../Core/Setting/UnsafeLocalSetting.cs | 85 ++++++++++++++++++ 5 files changed, 169 insertions(+), 53 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/TypeReflectionTest.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Core/Setting/UnsafeLocalSetting.cs diff --git a/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/JsonSerializeTest.cs b/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/JsonSerializeTest.cs index 40dd8c3a..656294cb 100644 --- a/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/JsonSerializeTest.cs +++ b/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/JsonSerializeTest.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; namespace Snap.Hutao.Test.BaseClassLibrary; [TestClass] -public class JsonSerializeTest +public sealed class JsonSerializeTest { public TestContext? TestContext { get; set; } diff --git a/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/TypeReflectionTest.cs b/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/TypeReflectionTest.cs new file mode 100644 index 00000000..668fc70a --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao.Test/BaseClassLibrary/TypeReflectionTest.cs @@ -0,0 +1,19 @@ +using System; + +namespace Snap.Hutao.Test.BaseClassLibrary; + +[TestClass] +public sealed class TypeReflectionTest +{ + [TestMethod] + public void TypeCodeOfEnumIsUserlyingTypeTypeCode() + { + Assert.AreEqual(Type.GetTypeCode(typeof(TestEnum)), TypeCode.Int32); + } + + private enum TestEnum + { + A, + B, + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs index 45906a33..959dc35d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs @@ -140,14 +140,19 @@ internal sealed partial class Activation : IActivation private async ValueTask HandleNormalLaunchActionAsync() { // Increase launch times - LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1); + LocalSetting.Update(SettingKeys.LaunchTimes, 0, x => x + 1); - if (StaticResource.IsAnyUnfulfilledCategoryPresent()) + // If it's the first time launch, we show the guide window anyway. + // Otherwise, we check if there's any unfulfilled resource category present. + if (UnsafeLocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, GuideState.Language) >= GuideState.StaticResourceBegin) { - LocalSetting.Set(SettingKeys.Major1Minor7Revision0GuideState, (uint)GuideState.StaticResourceBegin); + if (StaticResource.IsAnyUnfulfilledCategoryPresent()) + { + UnsafeLocalSetting.Set(SettingKeys.Major1Minor7Revision0GuideState, GuideState.StaticResourceBegin); + } } - if (LocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, (uint)GuideState.Language) < (uint)GuideState.Completed) + if (UnsafeLocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, GuideState.Language) < GuideState.Completed) { await taskContext.SwitchToMainThreadAsync(); serviceProvider.GetRequiredService(); @@ -160,31 +165,33 @@ internal sealed partial class Activation : IActivation private async ValueTask WaitMainWindowAsync() { - if (currentWindowReference.Window is null) + if (currentWindowReference.Window is not null) { - await taskContext.SwitchToMainThreadAsync(); - - serviceProvider.GetRequiredService(); - - await taskContext.SwitchToBackgroundAsync(); - - serviceProvider - .GetRequiredService() - .As()? - .InitializeInternalAsync() - .SafeForget(); - - serviceProvider - .GetRequiredService() - .As()? - .InitializeInternalAsync() - .SafeForget(); - - serviceProvider - .GetRequiredService() - .SetNormalActivity() - .SafeForget(); + return; } + + await taskContext.SwitchToMainThreadAsync(); + + serviceProvider.GetRequiredService(); + + await taskContext.SwitchToBackgroundAsync(); + + serviceProvider + .GetRequiredService() + .As()? + .InitializeInternalAsync() + .SafeForget(); + + serviceProvider + .GetRequiredService() + .As()? + .InitializeInternalAsync() + .SafeForget(); + + serviceProvider + .GetRequiredService() + .SetNormalActivity() + .SafeForget(); } private async ValueTask HandleUrlActivationAsync(Uri uri, bool isRedirected) @@ -279,21 +286,22 @@ internal sealed partial class Activation : IActivation if (currentWindowReference.Window is null) { serviceProvider.GetRequiredService(); + return; + } + + if (currentWindowReference.Window is MainWindow) + { + await serviceProvider + .GetRequiredService() + .NavigateAsync(INavigationAwaiter.Default, true) + .ConfigureAwait(false); + + return; } else { - if (currentWindowReference.Window is MainWindow) - { - await serviceProvider - .GetRequiredService() - .NavigateAsync(INavigationAwaiter.Default, true) - .ConfigureAwait(false); - } - else - { - // We have a non-Main Window, just exit current process anyway - Process.GetCurrentProcess().Kill(); - } + // We have a non-Main Window, just exit current process anyway + Process.GetCurrentProcess().Kill(); } } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Setting/LocalSetting.cs b/src/Snap.Hutao/Snap.Hutao/Core/Setting/LocalSetting.cs index cb495aac..d432d6c9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Setting/LocalSetting.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Setting/LocalSetting.cs @@ -43,6 +43,12 @@ internal static class LocalSetting return Get(key, defaultValue); } + /// + public static long Get(string key, long defaultValue) + { + return Get(key, defaultValue); + } + /// public static ulong Get(string key, ulong defaultValue) { @@ -150,6 +156,12 @@ internal static class LocalSetting Set(key, value); } + /// + public static void Set(string key, long value) + { + Set(key, value); + } + /// public static void Set(string key, ulong value) { @@ -227,13 +239,11 @@ internal static class LocalSetting Set(key, value); } - /// - /// 获取设置项的值 - /// - /// 设置项的类型 - /// 键 - /// 默认值 - /// 获取的值 + public static void Update(string key, int defaultValue, Func modifier) + { + Set(key, modifier(Get(key, defaultValue))); + } + private static T Get(string key, T defaultValue = default!) { if (Container.Values.TryGetValue(key, out object? value)) @@ -248,12 +258,6 @@ internal static class LocalSetting } } - /// - /// 设置设置项的值 - /// - /// 设置项的类型 - /// 键 - /// 值 private static void Set(string key, T value) { Container.Values[key] = value; diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Setting/UnsafeLocalSetting.cs b/src/Snap.Hutao/Snap.Hutao/Core/Setting/UnsafeLocalSetting.cs new file mode 100644 index 00000000..51ff1f26 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Core/Setting/UnsafeLocalSetting.cs @@ -0,0 +1,85 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Core.Setting; + +internal static class UnsafeLocalSetting +{ + public static unsafe TEnum Get(string key, TEnum defaultValue = default!) + where TEnum : unmanaged, Enum + { + switch (Type.GetTypeCode(typeof(TEnum))) + { + case TypeCode.Byte: + { + byte result = LocalSetting.Get(key, *(byte*)&defaultValue); + return *(TEnum*)&result; + } + + case TypeCode.Int16: + { + short result = LocalSetting.Get(key, *(short*)&defaultValue); + return *(TEnum*)&result; + } + + case TypeCode.UInt16: + { + ushort result = LocalSetting.Get(key, *(ushort*)&defaultValue); + return *(TEnum*)&result; + } + + case TypeCode.Int32: + { + int result = LocalSetting.Get(key, *(int*)&defaultValue); + return *(TEnum*)&result; + } + + case TypeCode.UInt32: + { + uint result = LocalSetting.Get(key, *(uint*)&defaultValue); + return *(TEnum*)&result; + } + + case TypeCode.Int64: + { + long result = LocalSetting.Get(key, *(long*)&defaultValue); + return *(TEnum*)&result; + } + + default: + // sbyte not supported + throw new InvalidCastException(); + } + } + + public static unsafe void Set(string key, TEnum value) + where TEnum : unmanaged, Enum + { + switch (Type.GetTypeCode(typeof(TEnum))) + { + case TypeCode.Byte: + LocalSetting.Set(key, *(byte*)&value); + break; + case TypeCode.Int16: + LocalSetting.Set(key, *(short*)&value); + break; + case TypeCode.UInt16: + LocalSetting.Set(key, *(ushort*)&value); + break; + case TypeCode.Int32: + LocalSetting.Set(key, *(int*)&value); + break; + case TypeCode.UInt32: + LocalSetting.Set(key, *(uint*)&value); + break; + case TypeCode.Int64: + LocalSetting.Set(key, *(long*)&value); + break; + case TypeCode.UInt64: + LocalSetting.Set(key, *(ulong*)&value); + break; + default: + throw new InvalidCastException(); + } + } +} \ No newline at end of file