From fd95b6d2f53b311e676245006eebd0ddbf8b2eb7 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 13 Apr 2026 00:30:26 +0800 Subject: [PATCH 1/2] Add LocationContaining, Duration extensions, and utility stubs for GF --- GF/DeviceSwiftShims/Core/GestureTrait.swift | 2 +- .../Extension/StandardLibraryAdditions.swift | 15 +++++++--- .../GestureNode/GestureNodeID.swift | 2 +- GF/DeviceSwiftShims/Logging.swift | 28 +++++++++++++++++++ .../Util/LocationContaining.swift | 24 ++++++++++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 GF/DeviceSwiftShims/Logging.swift create mode 100644 GF/DeviceSwiftShims/Util/LocationContaining.swift diff --git a/GF/DeviceSwiftShims/Core/GestureTrait.swift b/GF/DeviceSwiftShims/Core/GestureTrait.swift index fe19378..9b94c8f 100644 --- a/GF/DeviceSwiftShims/Core/GestureTrait.swift +++ b/GF/DeviceSwiftShims/Core/GestureTrait.swift @@ -40,7 +40,7 @@ public struct GestureTrait: Hashable, Identifiable, Sendable { attrs[.pointCount] = .int(pointCount) } if let minimumDuration { - attrs[.minimumDuration] = .double(Double(minimumDuration)) + attrs[.minimumDuration] = .double(minimumDuration.asTimeInterval()) } if let maximumMovement { attrs[.maximumMovement] = .double(maximumMovement) diff --git a/GF/DeviceSwiftShims/Extension/StandardLibraryAdditions.swift b/GF/DeviceSwiftShims/Extension/StandardLibraryAdditions.swift index 0707947..9fd3db9 100644 --- a/GF/DeviceSwiftShims/Extension/StandardLibraryAdditions.swift +++ b/GF/DeviceSwiftShims/Extension/StandardLibraryAdditions.swift @@ -1,10 +1,17 @@ // // StandardLibraryAdditions.swift // Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +extension Duration { + package func asTimeInterval() -> Double { + let (seconds, attoseconds) = components + return Double(seconds) + Double(attoseconds) / 1e18 + } -extension Double { - package init(_ duration: Duration) { - let (seconds, attoseconds) = duration.components - self = Double(seconds) + Double(attoseconds) / 1e18 + package static var max: Duration { + Duration(secondsComponent: .max, attosecondsComponent: .max) } } diff --git a/GF/DeviceSwiftShims/GestureNode/GestureNodeID.swift b/GF/DeviceSwiftShims/GestureNode/GestureNodeID.swift index b91c6dc..2dc7d61 100644 --- a/GF/DeviceSwiftShims/GestureNode/GestureNodeID.swift +++ b/GF/DeviceSwiftShims/GestureNode/GestureNodeID.swift @@ -1,6 +1,6 @@ // // GestureNodeID.swift -// OpenGestures +// Gestures // // Audited for 9126.1.5 // Status: Complete diff --git a/GF/DeviceSwiftShims/Logging.swift b/GF/DeviceSwiftShims/Logging.swift new file mode 100644 index 0000000..da4348f --- /dev/null +++ b/GF/DeviceSwiftShims/Logging.swift @@ -0,0 +1,28 @@ +// MARK: - Logging + +@_transparent +package func preconditionFailure(_ message: @autoclosure () -> String, file: StaticString, line: UInt) -> Never { + Swift.fatalError(message(), file: file, line: line) +} + +@_transparent +package func preconditionFailure(_ message: @autoclosure () -> String) -> Never { + preconditionFailure(message(), file: #fileID, line: #line) +} + +// MARK: - Abstract and stub call + +@_transparent +package func _gesturesUnreachableCode(_ function: String = #function, file: StaticString = #fileID, line: UInt = #line) -> Never { + preconditionFailure("", file: file, line: line) +} + +@_transparent +package func _gesturesBaseClassAbstractMethod(_ function: String = #function, file: StaticString = #fileID, line: UInt = #line) -> Never { + preconditionFailure("", file: file, line: line) +} + +@_transparent +package func _gesturesEmptyStub(_ function: String = #function, file: StaticString = #fileID, line: UInt = #line) { + // Intentionally empty - stub implementation +} diff --git a/GF/DeviceSwiftShims/Util/LocationContaining.swift b/GF/DeviceSwiftShims/Util/LocationContaining.swift new file mode 100644 index 0000000..77d0a65 --- /dev/null +++ b/GF/DeviceSwiftShims/Util/LocationContaining.swift @@ -0,0 +1,24 @@ +// +// LocationContaining.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +import CoreGraphics + +package protocol LocationContaining { + var location: CGPoint { get } +} + +extension CGPoint: LocationContaining { + package var location: CGPoint { + self + } +} + +extension Never: LocationContaining { + package var location: CGPoint { + _gesturesUnreachableCode() + } +} From f666fffd6c30ce9a7ae9c9b5f6a87ef3e29226f7 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 13 Apr 2026 01:43:31 +0800 Subject: [PATCH 2/2] Update Time related API --- .../arm64-apple-ios-simulator.swiftinterface | 79 ++++++++++++++++ .../x86_64-apple-ios-simulator.swiftinterface | 79 ++++++++++++++++ .../arm64-apple-macos.swiftinterface | 79 ++++++++++++++++ .../arm64e-apple-macos.swiftinterface | 79 ++++++++++++++++ .../x86_64-apple-macos.swiftinterface | 79 ++++++++++++++++ .../template.swiftinterface | 79 ++++++++++++++++ .../Time/GestureUpdateDriver.swift | 77 +++++++++++++++ GF/DeviceSwiftShims/Time/TimeScheduler.swift | 93 +++++++++++++++++++ GF/DeviceSwiftShims/Time/TimeSource.swift | 31 +++++++ GF/DeviceSwiftShims/Time/Timestamp.swift | 61 ++++++++++++ .../Time/UptimeTimeSource.swift | 28 ++++++ 11 files changed, 764 insertions(+) create mode 100644 GF/DeviceSwiftShims/Time/GestureUpdateDriver.swift create mode 100644 GF/DeviceSwiftShims/Time/TimeScheduler.swift create mode 100644 GF/DeviceSwiftShims/Time/TimeSource.swift create mode 100644 GF/DeviceSwiftShims/Time/Timestamp.swift create mode 100644 GF/DeviceSwiftShims/Time/UptimeTimeSource.swift diff --git a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface index d6a8013..67d3172 100644 --- a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface +++ b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface @@ -2,6 +2,7 @@ // swift-compiler-version: Apple Swift version 6.2 effective-5.10 (swiftlang-6.2.0.16.112 clang-1800.1.29) // swift-module-flags: -target arm64-apple-ios26.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -Osize -enable-upcoming-feature InternalImportsByDefault -enable-experimental-feature Extern -module-name Gestures // swift-module-flags-ignorable: -interface-compiler-version 6.2 +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -209,6 +210,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -216,3 +294,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface index ac97575..14677d9 100644 --- a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +++ b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface @@ -2,6 +2,7 @@ // swift-compiler-version: Apple Swift version 6.2 effective-5.10 (swiftlang-6.2.0.16.112 clang-1800.1.29) // swift-module-flags: -target x86_64-apple-ios26.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -Osize -enable-upcoming-feature InternalImportsByDefault -enable-experimental-feature Extern -module-name Gestures // swift-module-flags-ignorable: -interface-compiler-version 6.2 +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -209,6 +210,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -216,3 +294,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface index bd1002a..7e69653 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface @@ -2,6 +2,7 @@ // swift-compiler-version: Apple Swift version 6.2 effective-5.10 (swiftlang-6.2.0.16.112 clang-1800.1.29) // swift-module-flags: -target arm64-apple-macos26.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -Osize -enable-upcoming-feature InternalImportsByDefault -enable-experimental-feature Extern -module-name Gestures // swift-module-flags-ignorable: -interface-compiler-version 6.2 +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -209,6 +210,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -216,3 +294,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface index e824423..c6c6e81 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface @@ -2,6 +2,7 @@ // swift-compiler-version: Apple Swift version 6.2 effective-5.10 (swiftlang-6.2.0.16.112 clang-1800.1.29) // swift-module-flags: -target arm64e-apple-macos26.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -Osize -enable-upcoming-feature InternalImportsByDefault -enable-experimental-feature Extern -module-name Gestures // swift-module-flags-ignorable: -interface-compiler-version 6.2 +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -209,6 +210,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -216,3 +294,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface index ba13ed7..42ec532 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface @@ -2,6 +2,7 @@ // swift-compiler-version: Apple Swift version 6.2 effective-5.10 (swiftlang-6.2.0.16.112 clang-1800.1.29) // swift-module-flags: -target x86_64-apple-macos26.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -Osize -enable-upcoming-feature InternalImportsByDefault -enable-experimental-feature Extern -module-name Gestures // swift-module-flags-ignorable: -interface-compiler-version 6.2 +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -209,6 +210,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -216,3 +294,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface b/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface index 6e49d0a..34a5c0a 100644 --- a/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface +++ b/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface @@ -1,3 +1,4 @@ +public import Dispatch @_exported public import Gestures public import Swift public import _Concurrency @@ -205,6 +206,83 @@ extension Gestures.GestureNodeOptions : Swift.CustomStringConvertible { get } } +public protocol TimeSource { + var timestamp: Gestures.Timestamp { get } +} +extension Swift.Never : Gestures.TimeSource { + public var timestamp: Gestures.Timestamp { + get + } +} +public protocol TimeSourceImpl : Gestures.TimeSource { + var _duration: Swift.Duration { get } +} +public protocol GestureUpdateDriver : Swift.Sendable { + func register(_ handler: @escaping () -> Swift.Void) -> Gestures.GestureUpdateDriverToken + func unregister(token: Gestures.GestureUpdateDriverToken) +} +public struct GestureUpdateDriverToken : Swift.Hashable, Swift.Sendable { + public var value: Swift.UInt32 + public init(value: Swift.UInt32) + public static func == (a: Gestures.GestureUpdateDriverToken, b: Gestures.GestureUpdateDriverToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public protocol TimeScheduler : AnyObject, Gestures.TimeSource { + #if compiler(>=5.3) && $NonescapableTypes + func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)?) -> Gestures.TimeSchedulerToken + #endif + func cancel(token: Gestures.TimeSchedulerToken) +} +public struct TimeSchedulerToken : Swift.Hashable, Swift.Sendable { + public let rawValue: Swift.Int + public init(rawValue: Swift.Int) + public static func == (a: Gestures.TimeSchedulerToken, b: Gestures.TimeSchedulerToken) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +final public class DispatchTimeScheduler : @unchecked Swift.Sendable, Gestures.TimeScheduler { + final public let queue: Dispatch.DispatchQueue + final public let timeSource: any Gestures.TimeSource + public init(queue: Dispatch.DispatchQueue, timeSource: any Gestures.TimeSource) + final public var timestamp: Gestures.Timestamp { + get + } + #if compiler(>=5.3) && $NonescapableTypes + final public func schedule(after duration: Swift.Duration, handler: @escaping () -> Swift.Void, cancelHandler: (() -> Swift.Void)? = nil) -> Gestures.TimeSchedulerToken + #endif + final public func cancel(token: Gestures.TimeSchedulerToken) + @objc deinit +} +@frozen public struct Timestamp : Swift.Hashable, Swift.Comparable, Swift.Sendable, Swift.CustomStringConvertible { + package let value: Swift.Duration + public static func < (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Bool + public var description: Swift.String { + get + } + public func advanced(by duration: Swift.Duration) -> Gestures.Timestamp + public func duration(to other: Gestures.Timestamp) -> Swift.Duration + public static func + (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Swift.Duration) -> Gestures.Timestamp + public static func - (lhs: Gestures.Timestamp, rhs: Gestures.Timestamp) -> Swift.Duration + public static func += (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func -= (lhs: inout Gestures.Timestamp, rhs: Swift.Duration) + public static func == (a: Gestures.Timestamp, b: Gestures.Timestamp) -> Swift.Bool + public func hash(into hasher: inout Swift.Hasher) + public var hashValue: Swift.Int { + get + } +} +public struct UptimeTimeSource : Gestures.TimeSourceImpl, Swift.Sendable { + public init() + public var _duration: Swift.Duration { + get + } +} extension Gestures.GestureTrait : Swift.CustomStringConvertible {} extension Gestures.GestureTrait : Swift.CustomDebugStringConvertible {} extension Gestures.GestureTraitCollection : Swift.CustomStringConvertible {} @@ -212,3 +290,4 @@ extension Gestures.GestureTraitCollection : Swift.CustomDebugStringConvertible { extension Gestures.GestureNodeMatcher : Swift.CustomStringConvertible {} extension Gestures.GestureNodeMatcher : Swift.CustomDebugStringConvertible {} extension Gestures.GestureNodeID : Swift.BitwiseCopyable {} +extension Gestures.Timestamp : Swift.BitwiseCopyable {} diff --git a/GF/DeviceSwiftShims/Time/GestureUpdateDriver.swift b/GF/DeviceSwiftShims/Time/GestureUpdateDriver.swift new file mode 100644 index 0000000..79dec11 --- /dev/null +++ b/GF/DeviceSwiftShims/Time/GestureUpdateDriver.swift @@ -0,0 +1,77 @@ +// +// GestureUpdateDriver.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +// MARK: - GestureUpdateDriver + +/// Protocol for driving gesture update cycles. +public protocol GestureUpdateDriver: Sendable { + func register(_ handler: @escaping () -> Void) -> GestureUpdateDriverToken + + func unregister(token: GestureUpdateDriverToken) +} + +/// Token returned by GestureUpdateDriver.register. +public struct GestureUpdateDriverToken: Hashable, Sendable { + public var value: UInt32 + + public init(value: UInt32) { + self.value = value + } +} + +#if canImport(Darwin) +import Foundation + +// MARK: - RunLoopUpdateDriver + +/// Drives gesture updates via CFRunLoop observer, synced with the main run loop. +package final class RunLoopUpdateDriver: GestureUpdateDriver, @unchecked Sendable { + + private static var lastToken: UInt32 = 0 + + package var listeners: [GestureUpdateDriverToken: () -> Void] = [:] + + private lazy var runLoopObserver: CFRunLoopObserver! = CFRunLoopObserverCreateWithHandler( + nil, + CFRunLoopActivity.beforeWaiting.rawValue, + true, + 0 + ) { [weak self] _, _ in + self?.fireHandlers() + } + + package init() {} + + package func register(_ handler: @escaping () -> Void) -> GestureUpdateDriverToken { + Self.lastToken += 1 + let token = GestureUpdateDriverToken(value: Self.lastToken) + listeners[token] = handler + if listeners.count == 1 { + CFRunLoopAddObserver(CFRunLoopGetMain(), runLoopObserver, .commonModes) + } + return token + } + + package func unregister(token: GestureUpdateDriverToken) { + listeners.removeValue(forKey: token) + if listeners.isEmpty { + CFRunLoopRemoveObserver(CFRunLoopGetMain(), runLoopObserver, .commonModes) + } + } + + private func fireHandlers() { + for handler in listeners.values { + handler() + } + } + + deinit { + CFRunLoopRemoveObserver(CFRunLoopGetMain(), runLoopObserver, .commonModes) + } +} + +#endif diff --git a/GF/DeviceSwiftShims/Time/TimeScheduler.swift b/GF/DeviceSwiftShims/Time/TimeScheduler.swift new file mode 100644 index 0000000..0d32355 --- /dev/null +++ b/GF/DeviceSwiftShims/Time/TimeScheduler.swift @@ -0,0 +1,93 @@ +// +// TimeScheduler.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +public import Dispatch + +// MARK: - TimeScheduler + +public protocol TimeScheduler: AnyObject, TimeSource { + func schedule( + after duration: Duration, + handler: @escaping () -> Void, + cancelHandler: (() -> Void)? + ) -> TimeSchedulerToken + + func cancel(token: TimeSchedulerToken) +} + +// MARK: - TimeSchedulerToken + +public struct TimeSchedulerToken: Hashable, Sendable { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } +} + +// MARK: - ScheduledJob + +package struct ScheduledJob { + package let workItem: DispatchWorkItem + package let cancelHandler: (() -> Void)? + + package init(workItem: DispatchWorkItem, cancelHandler: (() -> Void)? = nil) { + self.workItem = workItem + self.cancelHandler = cancelHandler + } +} + +// MARK: - DispatchTimeScheduler + +public final class DispatchTimeScheduler: @unchecked Sendable, TimeScheduler { + public let queue: DispatchQueue + public let timeSource: any TimeSource + package var scheduledJobs: [TimeSchedulerToken: ScheduledJob] = [:] + package var counter: Int = 0 + + public init(queue: DispatchQueue, timeSource: any TimeSource) { + self.queue = queue + self.timeSource = timeSource + } + + // MARK: - TimeSource + + public var timestamp: Timestamp { + timeSource.timestamp + } + + // MARK: - TimeScheduler + + public func schedule( + after duration: Duration, + handler: @escaping () -> Void, + cancelHandler: (() -> Void)? = nil + ) -> TimeSchedulerToken { + counter += 1 + let token = TimeSchedulerToken(rawValue: counter) + let workItem = DispatchWorkItem(block: handler) + let job = ScheduledJob(workItem: workItem, cancelHandler: cancelHandler) + scheduledJobs[token] = job + let interval = duration.asTimeInterval() + queue.asyncAfter( + deadline: .now() + interval, + execute: workItem + ) + return token + } + + public func cancel(token: TimeSchedulerToken) { + guard let job = scheduledJobs.removeValue(forKey: token) else { + return + } + guard !job.workItem.isCancelled else { + return + } + job.workItem.cancel() + job.cancelHandler?() + } +} diff --git a/GF/DeviceSwiftShims/Time/TimeSource.swift b/GF/DeviceSwiftShims/Time/TimeSource.swift new file mode 100644 index 0000000..5f6f873 --- /dev/null +++ b/GF/DeviceSwiftShims/Time/TimeSource.swift @@ -0,0 +1,31 @@ +// +// TimeSource.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +// MARK: - TimeSource + +public protocol TimeSource { + var timestamp: Timestamp { get } +} + +extension Never: TimeSource { + public var timestamp: Timestamp { + _gesturesUnreachableCode() + } +} + +// MARK: - TimeSourceImpl + +public protocol TimeSourceImpl: TimeSource { + var _duration: Duration { get } +} + +extension TimeSourceImpl { + @_spi(Private) + public var timestamp: Timestamp { + Timestamp(value: _duration) + } +} diff --git a/GF/DeviceSwiftShims/Time/Timestamp.swift b/GF/DeviceSwiftShims/Time/Timestamp.swift new file mode 100644 index 0000000..ec8955d --- /dev/null +++ b/GF/DeviceSwiftShims/Time/Timestamp.swift @@ -0,0 +1,61 @@ +// +// Timestamp.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +// MARK: - Timestamp + +@frozen +public struct Timestamp: Hashable, Comparable, Sendable, CustomStringConvertible { + package let value: Duration + + package init(value: Duration) { + self.value = value + } + + // MARK: - Comparable + + public static func < (lhs: Timestamp, rhs: Timestamp) -> Bool { + lhs.value < rhs.value + } + + // MARK: - CustomStringConvertible + + public var description: String { + value.description + } + + // MARK: - Strideable-like + + public func advanced(by duration: Duration) -> Timestamp { + Timestamp(value: value + duration) + } + + public func duration(to other: Timestamp) -> Duration { + other.value - value + } + + // MARK: - Arithmetic with Duration + + public static func + (lhs: Timestamp, rhs: Duration) -> Timestamp { + Timestamp(value: lhs.value + rhs) + } + + public static func - (lhs: Timestamp, rhs: Duration) -> Timestamp { + Timestamp(value: lhs.value - rhs) + } + + public static func - (lhs: Timestamp, rhs: Timestamp) -> Duration { + lhs.value - rhs.value + } + + public static func += (lhs: inout Timestamp, rhs: Duration) { + lhs = lhs + rhs + } + + public static func -= (lhs: inout Timestamp, rhs: Duration) { + lhs = lhs - rhs + } +} diff --git a/GF/DeviceSwiftShims/Time/UptimeTimeSource.swift b/GF/DeviceSwiftShims/Time/UptimeTimeSource.swift new file mode 100644 index 0000000..fd07868 --- /dev/null +++ b/GF/DeviceSwiftShims/Time/UptimeTimeSource.swift @@ -0,0 +1,28 @@ +// +// UptimeTimeSource.swift +// Gestures +// +// Audited for 9126.1.5 +// Status: Complete + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#endif + +public struct UptimeTimeSource: TimeSourceImpl, Sendable { + public init() {} + + public var _duration: Duration { + #if canImport(Darwin) + let ns = clock_gettime_nsec_np(CLOCK_UPTIME_RAW) + return .nanoseconds(Int64(ns)) + #else + var ts = timespec() + clock_gettime(CLOCK_MONOTONIC, &ts) + let totalNs = Int64(ts.tv_sec) * 1_000_000_000 + Int64(ts.tv_nsec) + return .nanoseconds(totalNs) + #endif + } +}