From 76567c8bc56a07f56ca18fd35f676d8e8d44c68d Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 2 Dec 2024 09:44:07 +1100 Subject: [PATCH] Don't use Observation on non-Darwin platforms Workaround for swiftlang/swift#75670 --- Sources/SwiftOCA/OCC/ControlClasses/Root.swift | 6 ++++++ Sources/SwiftOCA/OCC/PropertyTypes/Property.swift | 5 ++++- Sources/SwiftOCA/OCP.1/Ocp1Connection+Connect.swift | 13 ++++++++++++- Sources/SwiftOCA/OCP.1/Ocp1Connection.swift | 8 ++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftOCA/OCC/ControlClasses/Root.swift b/Sources/SwiftOCA/OCC/ControlClasses/Root.swift index 61d6b20..01b75d2 100644 --- a/Sources/SwiftOCA/OCC/ControlClasses/Root.swift +++ b/Sources/SwiftOCA/OCC/ControlClasses/Root.swift @@ -16,7 +16,9 @@ import AsyncExtensions import Foundation +#if canImport(Darwin) import Observation +#endif open class OcaRoot: CustomStringConvertible, @unchecked Sendable, _OcaObjectKeyPathRepresentable, Observable @@ -26,7 +28,9 @@ open class OcaRoot: CustomStringConvertible, @unchecked Sendable, public internal(set) weak var connectionDelegate: Ocp1Connection? fileprivate var subscriptionCancellable: Ocp1Connection.SubscriptionCancellable? + #if canImport(Darwin) fileprivate let _$observationRegistrar = Observation.ObservationRegistrar() + #endif // 1.1 open class var classID: OcaClassID { OcaClassID("1") } @@ -189,6 +193,7 @@ extension _OcaObjectKeyPathRepresentable where Self: OcaRoot { } } + #if canImport(Darwin) nonisolated func access( keyPath: KeyPath ) { @@ -201,6 +206,7 @@ extension _OcaObjectKeyPathRepresentable where Self: OcaRoot { ) rethrows -> T { try _$observationRegistrar.withMutation(of: self, keyPath: keyPath, mutation) } + #endif } public extension OcaRoot { diff --git a/Sources/SwiftOCA/OCC/PropertyTypes/Property.swift b/Sources/SwiftOCA/OCC/PropertyTypes/Property.swift index 725e71d..ffc8800 100644 --- a/Sources/SwiftOCA/OCC/PropertyTypes/Property.swift +++ b/Sources/SwiftOCA/OCC/PropertyTypes/Property.swift @@ -17,7 +17,9 @@ import AsyncAlgorithms import AsyncExtensions import Foundation +#if canImport(Darwin) import Observation +#endif public struct OcaPropertyResolutionFlags: OptionSet, Sendable { public typealias RawValue = UInt32 @@ -241,14 +243,15 @@ public struct OcaProperty: Codable, Sendable, _enclosingInstance object: T, wrapped wrappedKeyPath: ReferenceWritableKeyPath ) { + #if canImport(Darwin) object.access(keyPath: wrappedKeyPath) - _send = { @Sendable [subject] object, newValue in guard let object else { return } (object as! T).withMutation(keyPath: wrappedKeyPath) { subject.send(newValue) } } + #endif } public static subscript( diff --git a/Sources/SwiftOCA/OCP.1/Ocp1Connection+Connect.swift b/Sources/SwiftOCA/OCP.1/Ocp1Connection+Connect.swift index 2b8a5c8..972198f 100644 --- a/Sources/SwiftOCA/OCP.1/Ocp1Connection+Connect.swift +++ b/Sources/SwiftOCA/OCP.1/Ocp1Connection+Connect.swift @@ -20,6 +20,9 @@ import AsyncExtensions import Foundation import Logging import SystemPackage +#if canImport(Darwin) +import Observation +#endif private extension Ocp1Error { var ocp1ConnectionState: Ocp1ConnectionState? { @@ -101,6 +104,7 @@ private extension Ocp1ConnectionState { // MARK: - connection state observation +#if canImport(Darwin) extension Ocp1Connection { nonisolated func access( keyPath: KeyPath @@ -115,6 +119,7 @@ extension Ocp1Connection { try _$observationRegistrar.withMutation(of: self, keyPath: keyPath, mutation) } } +#endif // MARK: - monitor task management @@ -173,10 +178,14 @@ extension Ocp1Connection { /// wrapper to update the connection state, logging the old and new connection states private func _updateConnectionState(_ connectionState: Ocp1ConnectionState) { + logger.trace("_updateConnectionState: \(currentConnectionState) => \(connectionState)") + #if canImport(Darwin) withMutation(keyPath: \.currentConnectionState) { - logger.trace("_updateConnectionState: \(currentConnectionState) => \(connectionState)") _connectionState.send(connectionState) } + #else + _connectionState.send(connectionState) + #endif } /// update the device connection state, called from the connection (for @@ -279,7 +288,9 @@ extension Ocp1Connection { } public var currentConnectionState: Ocp1ConnectionState { +#if canImport(Darwin) access(keyPath: \.currentConnectionState) +#endif return _connectionState.value } diff --git a/Sources/SwiftOCA/OCP.1/Ocp1Connection.swift b/Sources/SwiftOCA/OCP.1/Ocp1Connection.swift index 784e1ad..a2879dc 100644 --- a/Sources/SwiftOCA/OCP.1/Ocp1Connection.swift +++ b/Sources/SwiftOCA/OCP.1/Ocp1Connection.swift @@ -20,7 +20,9 @@ import Atomics @preconcurrency import Foundation import Logging +#if canImport(Darwin) import Observation +#endif package let Ocp1MaximumDatagramPduSize = 1500 @@ -154,6 +156,10 @@ public struct Ocp1ConnectionStatistics: Sendable { private let CommandHandleBase = OcaUint32(100) +#if !canImport(Darwin) +protocol Observable {} +#endif + @OcaConnection open class Ocp1Connection: Observable, CustomStringConvertible { public nonisolated static let MinimumPduSize = 7 @@ -203,7 +209,9 @@ open class Ocp1Connection: Observable, CustomStringConvertible { var subscriptions = [OcaEvent: EventSubscriptions]() var logger = Logger(label: "com.padl.SwiftOCA") var connectionID = 0 + #if canImport(Darwin) let _$observationRegistrar = Observation.ObservationRegistrar() + #endif private var nextCommandHandle = CommandHandleBase