diff --git a/Sources/OpenSwiftUI/AppStructure/AppOrganization/Graph/AppGraph.swift b/Sources/OpenSwiftUI/AppStructure/AppOrganization/Graph/AppGraph.swift new file mode 100644 index 0000000..107b10e --- /dev/null +++ b/Sources/OpenSwiftUI/AppStructure/AppOrganization/Graph/AppGraph.swift @@ -0,0 +1,67 @@ +// +// AppGraph.swift +// OpenSwiftUI +// +// Created by Kyle on 2023/9/22. +// Lastest Version: iOS 15.5 +// Status: WIP +// ID: A363922CEBDF47986D9772B903C8737A + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif os(WASI) +import WASILibc +#endif + +final class AppGraph: GraphHost { + static var shared: AppGraph? = nil + static var delegateBox: AnyFallbackDelegateBox? = nil + + private struct LaunchProfileOptions: OptionSet { + let rawValue: Int32 + + static var enable: LaunchProfileOptions { .init(rawValue: 1 << 1) } + } + + private lazy var launchProfileOptions: LaunchProfileOptions = { + let env = getenv("SWIFTUI_PROFILE_LAUNCH") + if let env { + return .init(rawValue: atoi(env)) + } else { + return [] + } + }() + + var didCollectLaunchProfile: Bool = false + + init(app _: some App) {} + + func extendedLaunchTestName() -> String? { nil } + + func startProfilingIfNecessary() { + guard !didCollectLaunchProfile else { + return + } + + if launchProfileOptions.contains(.enable) { + // AGGraphStartProfiling + } + } + + func stopProfilingIfNecessary() { + guard !didCollectLaunchProfile else { + return + } + didCollectLaunchProfile = true + + if launchProfileOptions.contains(.enable) { + // AGGraphStopProfiling + } + + if launchProfileOptions.rawValue != 0 { + // AGGraphArchiveJSON + } + } +} diff --git a/Sources/OpenSwiftUI/AppStructure/AppOrganization/Profile/FinishLaunchTestAction.swift b/Sources/OpenSwiftUI/AppStructure/AppOrganization/Profile/FinishLaunchTestAction.swift new file mode 100644 index 0000000..3ff6e26 --- /dev/null +++ b/Sources/OpenSwiftUI/AppStructure/AppOrganization/Profile/FinishLaunchTestAction.swift @@ -0,0 +1,30 @@ +// +// FinishLaunchTestAction.swift +// OpenSwiftUI +// +// Created by Kyle on 2024/2/25. +// Lastest Version: iOS 15.5 +// Status: Complete + +#if os(iOS) +import UIKit +#elseif os(macOS) +import AppKit +#endif + +struct FinishLaunchTestAction { + func callAsFunction() { + AppGraph.shared?.stopProfilingIfNecessary() + #if os(iOS) + UIApplication.shared.finishedTest(UIApplication.shared._launchTestName()) + #else + fatalError("Unimplemented for other platform") + #endif + } +} + +extension EnvironmentValues { + var finishLaunchTest: FinishLaunchTestAction { + FinishLaunchTestAction() + } +} diff --git a/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/AppGraph.swift b/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/AppGraph.swift deleted file mode 100644 index eb24a14..0000000 --- a/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/AppGraph.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// AppGraph.swift -// OpenSwiftUI -// -// Created by Kyle on 2023/9/22. -// Lastest Version: iOS 15.5 -// Status: WIP -// ID: A363922CEBDF47986D9772B903C8737A - -#if canImport(Darwin) -final class AppGraph: GraphHost { - init(app _: some App) {} - - static var shared: AppGraph? = nil - static var delegateBox: AnyFallbackDelegateBox? = nil - - func extendedLaunchTestName() -> String? { nil } - - func startProfilingIfNecessary() {} -} -#endif diff --git a/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/FallbackDelegateBox.swift b/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/FallbackDelegateBox.swift index c591247..e120cc6 100644 --- a/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/FallbackDelegateBox.swift +++ b/Sources/OpenSwiftUI/AppStructure/AppOrganization/TODO/FallbackDelegateBox.swift @@ -6,7 +6,6 @@ // Lastest Version: iOS 15.5 // Status: WIP -#if canImport(Darwin) import Foundation #if OPENSWIFTUI_OPENCOMBINE import OpenCombine @@ -39,6 +38,10 @@ class FallbackDelegateBox: AnyFallbackDelegateBox { } override var delegate: NSObject? { + // FIXME: error: constructing an object of class type 'Delegate' with a metatype value must use a 'required' initializer + #if !canImport(Darwin) + return nil + #else switch storage { case let .type(type): let delegate = type.init() @@ -47,6 +50,6 @@ class FallbackDelegateBox: AnyFallbackDelegateBox { case let .instance(delegate): return delegate } + #endif } } -#endif diff --git a/Sources/OpenSwiftUI/Test/_PerformanceTest.swift b/Sources/OpenSwiftUI/Test/_PerformanceTest.swift index 76a19e4..1c08019 100644 --- a/Sources/OpenSwiftUI/Test/_PerformanceTest.swift +++ b/Sources/OpenSwiftUI/Test/_PerformanceTest.swift @@ -35,24 +35,30 @@ extension _BenchmarkHost { public func _started(test: _PerformanceTest) { #if os(iOS) UIApplication.shared.startedTest(test.name) + #elseif os(macOS) + NSApplication.shared.startedTest(test.name) #else - fatalError("TODO") + fatalError("Unimplemented for other platform") #endif } public func _finished(test: _PerformanceTest) { #if os(iOS) UIApplication.shared.finishedTest(test.name) + #elseif os(macOS) + NSApplication.shared.finishedTest(test.name) #else - fatalError("TODO") + fatalError("Unimplemented for other platform") #endif } public func _failed(test: _PerformanceTest) { #if os(iOS) UIApplication.shared.failedTest(test.name, withFailure: nil) + #elseif os(macOS) + NSApplication.shared.failedTest(test.name, withFailure: nil) #else - fatalError("TODO") + fatalError("Unimplemented for other platform") #endif } } diff --git a/Sources/OpenSwiftUIShims/include/OpenSwiftUI_SPI.h b/Sources/OpenSwiftUIShims/include/OpenSwiftUI_SPI.h index 5ca9230..200a61c 100644 --- a/Sources/OpenSwiftUIShims/include/OpenSwiftUI_SPI.h +++ b/Sources/OpenSwiftUIShims/include/OpenSwiftUI_SPI.h @@ -14,9 +14,15 @@ - (void)startedTest:(nullable NSString *)name; - (void)finishedTest:(nullable NSString *)name; - (void)failedTest:(nullable NSString *)name withFailure:(nullable NSError*)failure; +- (nullable NSString *)_launchTestName; +@end +#elif __has_include() +#import +@interface NSApplication (OpenSwiftUI_SPI) +- (void)startedTest:(nullable NSString *)name; +- (void)finishedTest:(nullable NSString *)name; +- (void)failedTest:(nullable NSString *)name withFailure:(nullable NSError*)failure; @end -#else - #endif #endif /* OpenSwiftUI_SPI_h */