From cffae20b4b56acc3c769d0be6b7b62b7ea09b829 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 29 Jun 2025 01:02:43 +0800 Subject: [PATCH 1/2] Update PreferenceKey to 6.5.4 --- .../Data/Preference/PreferenceBridge.swift | 20 +++---- .../Data/Preference/PreferenceKey.swift | 46 +++------------ .../Data/Preference/PreferencesOutputs.swift | 41 ++++++------- .../Event/Gesture/Gesture.swift | 4 +- .../Util/Data/VersionSeedTracker.swift | 57 ------------------- .../View/Graph/ViewGraph.swift | 2 +- .../View/Input/ViewOutputs.swift | 4 +- 7 files changed, 44 insertions(+), 130 deletions(-) delete mode 100644 Sources/OpenSwiftUICore/Util/Data/VersionSeedTracker.swift diff --git a/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift b/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift index 388991aa7..1fa826424 100644 --- a/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift +++ b/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift @@ -20,7 +20,7 @@ package final class PreferenceBridge { private var bridgedPreferences: [BridgedPreference] = [] struct BridgedPreference { - var key: AnyPreferenceKey.Type + var key: any PreferenceKey.Type var combiner: AnyWeakAttribute } @@ -55,20 +55,20 @@ package final class PreferenceBridge { package func wrapOutputs(_ outputs: inout PreferencesOutputs, inputs: _ViewInputs) { bridgedViewInputs = inputs.customInputs for key in inputs.preferences.keys { - if key == _AnyPreferenceKey.self { + if key == HostPreferencesKey.self { let combiner = Attribute( HostPreferencesCombiner( keys: inputs.preferences.hostKeys, - values: Attribute(identifier: outputs[anyKey: _AnyPreferenceKey.self] ?? .nil) + values: outputs[HostPreferencesKey.self] ) ) - outputs[anyKey: key] = combiner.identifier + outputs[HostPreferencesKey.self] = combiner _hostPreferenceKeys = WeakAttribute(inputs.preferences.hostKeys) _hostPreferencesCombiner = WeakAttribute(combiner) } else { struct MakeCombiner: PreferenceKeyVisitor { var result: AnyAttribute? - + mutating func visit(key: K.Type) where K : PreferenceKey { let combiner = PreferenceCombiner(attributes: []) result = Attribute(combiner).identifier @@ -78,7 +78,7 @@ package final class PreferenceBridge { break } var combiner = MakeCombiner() - key.visitKey(&combiner) + combiner.visit(key: key) guard let result = combiner.result else { break } @@ -111,7 +111,7 @@ package final class PreferenceBridge { } } - package func addValue(_ src: AnyAttribute, for key: any AnyPreferenceKey.Type) { + package func addValue(_ src: AnyAttribute, for key: any PreferenceKey.Type) { struct AddValue: PreferenceKeyVisitor { var combiner: AnyAttribute var value: AnyAttribute @@ -129,11 +129,11 @@ package final class PreferenceBridge { let combiner = bridgedPreference.combiner.attribute else { return } var visitor = AddValue(combiner: combiner, value: src) - key.visitKey(&visitor) + visitor.visit(key: key) viewGraph.graphInvalidation(from: src) } - package func removeValue(_ src: AnyAttribute, for key: any AnyPreferenceKey.Type, isInvalidating: Bool = false) { + package func removeValue(_ src: AnyAttribute, for key: any PreferenceKey.Type, isInvalidating: Bool = false) { struct RemoveValue: PreferenceKeyVisitor { var combiner: AnyAttribute var value: AnyAttribute @@ -156,7 +156,7 @@ package final class PreferenceBridge { let combiner = bridgedPreference.combiner.attribute else { return } var visitor = RemoveValue(combiner: combiner, value: src) - key.visitKey(&visitor) + visitor.visit(key: key) if visitor.changed { viewGraph.graphInvalidation(from: isInvalidating ? nil : src) } diff --git a/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift b/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift index d47a530ff..7936b85a7 100644 --- a/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift +++ b/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift @@ -75,34 +75,17 @@ extension PreferenceKey { } } -// MARK: - AnyPreferenceKey - -package protocol AnyPreferenceKey { - static var valueType: any Any.Type { get } - static func visitKey(_ v: inout V) where V: PreferenceKeyVisitor -} - // MARK: - PreferenceKeyVisitor package protocol PreferenceKeyVisitor { mutating func visit(key: K.Type) where K: PreferenceKey } -// MARK: - _AnyPreferenceKey - -package struct _AnyPreferenceKey: AnyPreferenceKey where K: PreferenceKey{ - package static var valueType: any Any.Type { K.self } - - package static func visitKey(_ v: inout V) where V : PreferenceKeyVisitor { - v.visit(key: K.self) - } -} - -// MARK: - PreferenceKeys +// MARK: - PreferenceKeys [6.5.4] package struct PreferenceKeys: Equatable, RandomAccessCollection, MutableCollection { - var keys: [any AnyPreferenceKey.Type] = [] - + var keys: [any PreferenceKey.Type] = [] + @inlinable package init() {} @@ -110,35 +93,22 @@ package struct PreferenceKeys: Equatable, RandomAccessCollection, MutableCollect package var isEmpty: Bool { keys.isEmpty } @inlinable - package func contains(_ key: any AnyPreferenceKey.Type) -> Bool { + package func contains(_ key: any PreferenceKey.Type) -> Bool { keys.contains { $0 == key } } - @inlinable - package func contains(_ key: K.Type) -> Bool where K: PreferenceKey { - contains(_AnyPreferenceKey.self) - } - - package mutating func add(_ key: any AnyPreferenceKey.Type) { + package mutating func add(_ key: any PreferenceKey.Type) { guard !contains(key) else { return } keys.append(key) } - - package mutating func add(_ key: K.Type) where K: PreferenceKey { - add(_AnyPreferenceKey.self) - } - - package mutating func remove(_ key: AnyPreferenceKey.Type) { + + package mutating func remove(_ key: any PreferenceKey.Type) { guard let index = keys.firstIndex(where: { $0 == key }) else { return } keys.remove(at: index) } - package mutating func remove(_ key: K.Type) where K: PreferenceKey { - remove(_AnyPreferenceKey.self) - } - package static func == (lhs: PreferenceKeys, rhs: PreferenceKeys) -> Bool { guard lhs.keys.count == rhs.keys.count else { return false @@ -158,7 +128,7 @@ package struct PreferenceKeys: Equatable, RandomAccessCollection, MutableCollect package var endIndex: Int { keys.endIndex } @inlinable - package subscript(position: Int) -> AnyPreferenceKey.Type { + package subscript(position: Int) -> any PreferenceKey.Type { get { keys[position] } set { keys[position] = newValue } } diff --git a/Sources/OpenSwiftUICore/Data/Preference/PreferencesOutputs.swift b/Sources/OpenSwiftUICore/Data/Preference/PreferencesOutputs.swift index ed759058e..3eb8c08dd 100644 --- a/Sources/OpenSwiftUICore/Data/Preference/PreferencesOutputs.swift +++ b/Sources/OpenSwiftUICore/Data/Preference/PreferencesOutputs.swift @@ -2,11 +2,13 @@ // PreferencesOutputs.swift // OpenSwiftUICore // -// Audited for iOS 18.0 // Status: Complete +// ID: 639FD567E11A491423DEEA5A95A52B4C (SwiftUICore) package import OpenGraphShims +// MARK: - PreferencesOutputs [6.5.4] + package struct PreferencesOutputs { private var preferences: [KeyValue] package var debugProperties: _ViewDebug.Properties @@ -17,13 +19,19 @@ package struct PreferencesOutputs { debugProperties = [] } - subscript(anyKey key: AnyPreferenceKey.Type) -> AnyAttribute? { - get { preferences.first { $0.key == key }?.value } - set { - if key == _AnyPreferenceKey.self { - if !debugProperties.contains(.displayList) { - debugProperties.formUnion(.displayList) + subscript(anyKey key: any PreferenceKey.Type) -> AnyAttribute? { + get { + for preference in preferences { + guard preference.key == key else { + continue } + return preference.value + } + return nil + } + set { + if key == DisplayList.Key.self { + debugProperties.insert(.displayList) } if let index = preferences.firstIndex(where: { $0.key == key }) { if let newValue { @@ -41,19 +49,19 @@ package struct PreferencesOutputs { subscript(key: K.Type) -> Attribute? where K: PreferenceKey { get { - let value = self[anyKey: _AnyPreferenceKey.self] + let value = self[anyKey: key] return value.map { Attribute(identifier: $0) } } set { - self[anyKey: _AnyPreferenceKey.self] = newValue.map { $0.identifier } + self[anyKey: key] = newValue.map { $0.identifier } } } package mutating func appendPreference(key: K.Type, value: Attribute) where K: PreferenceKey{ - preferences.append(KeyValue(key: _AnyPreferenceKey.self, value: value.identifier)) + preferences.append(KeyValue(key: key, value: value.identifier)) } - package func forEachPreference(_ body: (any AnyPreferenceKey.Type, AnyAttribute) -> Void) { + package func forEachPreference(_ body: (any PreferenceKey.Type, AnyAttribute) -> Void) { preferences.forEach { body($0.key, $0.value) } } @@ -72,22 +80,15 @@ package struct PreferencesOutputs { } package func detachIndirectOutputs() { - struct ResetPreference: PreferenceKeyVisitor { - var destination: AnyAttribute - func visit(key: K.Type) where K: PreferenceKey { - destination.source = .nil - } - } for keyValue in preferences { - var visitor = ResetPreference(destination: keyValue.value) - keyValue.key.visitKey(&visitor) + keyValue.value.source = .nil } } } extension PreferencesOutputs { private struct KeyValue { - var key: any AnyPreferenceKey.Type + var key: any PreferenceKey.Type var value: AnyAttribute } } diff --git a/Sources/OpenSwiftUICore/Event/Gesture/Gesture.swift b/Sources/OpenSwiftUICore/Event/Gesture/Gesture.swift index cffedfc2f..424a3d29f 100644 --- a/Sources/OpenSwiftUICore/Event/Gesture/Gesture.swift +++ b/Sources/OpenSwiftUICore/Event/Gesture/Gesture.swift @@ -266,7 +266,7 @@ public struct _GestureOutputs { preconditionFailure("TODO") } - package subscript(anyKey key: any AnyPreferenceKey.Type) -> AnyAttribute? { + package subscript(anyKey key: any PreferenceKey.Type) -> AnyAttribute? { get { preconditionFailure("TODO") } set { preconditionFailure("TODO") } } @@ -283,7 +283,7 @@ public struct _GestureOutputs { preconditionFailure("TODO") } - package func forEachPreference(_ body: (any AnyPreferenceKey.Type, AnyAttribute) -> Void) { + package func forEachPreference(_ body: (any PreferenceKey.Type, AnyAttribute) -> Void) { preconditionFailure("TODO") } } diff --git a/Sources/OpenSwiftUICore/Util/Data/VersionSeedTracker.swift b/Sources/OpenSwiftUICore/Util/Data/VersionSeedTracker.swift deleted file mode 100644 index 14560a3c7..000000000 --- a/Sources/OpenSwiftUICore/Util/Data/VersionSeedTracker.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// VersionSeedTracker.swift -// OpenSwiftUI -// Audited for iOS 15.5 -// Status: Complete - -//struct VersionSeedTracker { -// var seed: VersionSeed -//} -// -//struct VersionSeedSetTracker { -// private var values: [Value] -// -// mutating func addPreference(_: Key.Type) { -// values.append(Value(key: _AnyPreferenceKey.self, seed: .invalid)) -// } -// -// mutating func updateSeeds(to preferences: PreferenceList) { -// for index in values.indices { -// var visitor = UpdateSeedVisitor(preferences: preferences, seed: nil) -// values[index].key.visitKey(&visitor) -// guard let seed = visitor.seed else { -// continue -// } -// values[index].seed = seed -// } -// } -//} -// -//extension VersionSeedSetTracker { -// private struct Value { -// var key: AnyPreferenceKey.Type -// var seed: VersionSeed -// } -//} -// -//extension VersionSeedSetTracker { -// private struct HasChangesVisitor: PreferenceKeyVisitor { -// let preferences: PreferenceList -// var seed: VersionSeed -// var matches: Bool? -// -// mutating func visit(key: (some PreferenceKey).Type) { -// let valueSeed = preferences[key].seed -// matches = seed.matches(valueSeed) -// } -// } -// -// private struct UpdateSeedVisitor: PreferenceKeyVisitor { -// let preferences: PreferenceList -// var seed: VersionSeed? -// -// mutating func visit(key: (some PreferenceKey).Type) { -// seed = preferences[key].seed -// } -// } -//} diff --git a/Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift b/Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift index 7b94cb5fc..59ca56806 100644 --- a/Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift +++ b/Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift @@ -137,7 +137,7 @@ package final class ViewGraph: GraphHost { set { setPreferenceBridge(to: newValue) } } - var bridgedPreferences: [(AnyPreferenceKey.Type, AnyAttribute)] = [] + var bridgedPreferences: [(any PreferenceKey.Type, AnyAttribute)] = [] package static var current: ViewGraph { GraphHost.currentHost as! ViewGraph } diff --git a/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift b/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift index 99ff0059a..999a58b14 100644 --- a/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift +++ b/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift @@ -28,7 +28,7 @@ public struct _ViewOutputs { _layoutComputer = OptionalAttribute() } - package subscript(anyKey key: any AnyPreferenceKey.Type) -> AnyAttribute? { + package subscript(anyKey key: any PreferenceKey.Type) -> AnyAttribute? { get { preferences[anyKey: key] } set { preferences[anyKey: key] = newValue } } @@ -42,7 +42,7 @@ public struct _ViewOutputs { preferences.appendPreference(key: key, value: value) } - package func forEachPreference(_ body: (any AnyPreferenceKey.Type, AnyAttribute) -> Void) { + package func forEachPreference(_ body: (any PreferenceKey.Type, AnyAttribute) -> Void) { preferences.forEachPreference(body) } } From 1f3804b1a9b5a49be07d9d860a2559a53ddcf97b Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 29 Jun 2025 01:51:05 +0800 Subject: [PATCH 2/2] Add visitKey API --- .../Data/Preference/PreferenceBridge.swift | 60 ++++++++----------- .../Data/Preference/PreferenceKey.swift | 4 ++ 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift b/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift index 1fa826424..5bca86529 100644 --- a/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift +++ b/Sources/OpenSwiftUICore/Data/Preference/PreferenceBridge.swift @@ -78,7 +78,7 @@ package final class PreferenceBridge { break } var combiner = MakeCombiner() - combiner.visit(key: key) + key.visitKey(&combiner) guard let result = combiner.result else { break } @@ -112,52 +112,42 @@ package final class PreferenceBridge { } package func addValue(_ src: AnyAttribute, for key: any PreferenceKey.Type) { - struct AddValue: PreferenceKeyVisitor { - var combiner: AnyAttribute - var value: AnyAttribute - func visit(key _: Key.Type) { - combiner.mutateBody( - as: PreferenceCombiner.self, - invalidating: true - ) { combiner in - combiner.attributes.append(WeakAttribute(base: AnyWeakAttribute(value))) - } - } - } guard let viewGraph, let bridgedPreference = bridgedPreferences.first(where: { $0.key == key }), let combiner = bridgedPreference.combiner.attribute else { return } - var visitor = AddValue(combiner: combiner, value: src) - visitor.visit(key: key) + func project(_ key: K.Type) where K: PreferenceKey { + combiner.mutateBody( + as: PreferenceCombiner.self, + invalidating: true + ) { combiner in + combiner.attributes.append(WeakAttribute(base: AnyWeakAttribute(src))) + } + } + project(key) viewGraph.graphInvalidation(from: src) } package func removeValue(_ src: AnyAttribute, for key: any PreferenceKey.Type, isInvalidating: Bool = false) { - struct RemoveValue: PreferenceKeyVisitor { - var combiner: AnyAttribute - var value: AnyAttribute - var changed = false - mutating func visit(key _: Key.Type) { - combiner.mutateBody( - as: PreferenceCombiner.self, - invalidating: true - ) { combiner in - guard let index = combiner.attributes.firstIndex(where: { $0.attribute?.identifier == value }) else { - return - } - combiner.attributes.remove(at: index) - changed = true - } - } - } guard let viewGraph, let bridgedPreference = bridgedPreferences.first(where: { $0.key == key }), let combiner = bridgedPreference.combiner.attribute else { return } - var visitor = RemoveValue(combiner: combiner, value: src) - visitor.visit(key: key) - if visitor.changed { + var changed = false + func project(_ key: K.Type) where K: PreferenceKey { + combiner.mutateBody( + as: PreferenceCombiner.self, + invalidating: true + ) { combiner in + guard let index = combiner.attributes.firstIndex(where: { $0.attribute?.identifier == src }) else { + return + } + combiner.attributes.remove(at: index) + changed = true + } + } + project(key) + if changed { viewGraph.graphInvalidation(from: isInvalidating ? nil : src) } } diff --git a/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift b/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift index 7936b85a7..0dbb778b9 100644 --- a/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift +++ b/Sources/OpenSwiftUICore/Data/Preference/PreferenceKey.swift @@ -73,6 +73,10 @@ extension PreferenceKey { return name } } + + package static func visitKey(_ visitor: inout Visitor) where Visitor: PreferenceKeyVisitor { + visitor.visit(key: Self.self) + } } // MARK: - PreferenceKeyVisitor