From 6734af4110e800e969635d0f3f4bc40a711b96be Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 5 Jan 2024 15:26:10 +0800 Subject: [PATCH 1/3] Add PreferenceKey related protocol --- .../Internal/AnyPreferenceKey.swift | 20 +++++++++++++++++++ .../Internal/HostPreferenceKey.swift | 9 +++++++++ .../Internal/PreferenceKeyVisitor.swift | 11 ++++++++++ .../Preferences/Internal/PreferenceList.swift | 1 + 4 files changed, 41 insertions(+) create mode 100644 Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/AnyPreferenceKey.swift create mode 100644 Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/HostPreferenceKey.swift create mode 100644 Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift create mode 100644 Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/AnyPreferenceKey.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/AnyPreferenceKey.swift new file mode 100644 index 00000000..257149a7 --- /dev/null +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/AnyPreferenceKey.swift @@ -0,0 +1,20 @@ +// +// AnyPreferenceKey.swift +// OpenSwiftUI +// +// Created by Kyle on 2024/1/5. +// Lastest Version: iOS 15.5 +// Status: Complete + +protocol AnyPreferenceKey { + static var valueType: Any.Type { get } + static func visitKey(_ visitor: inout Visitor) +} + +struct _AnyPreferenceKey: AnyPreferenceKey { + static var valueType: Any.Type { Key.self } + + static func visitKey(_ visitor: inout Visitor) where Visitor : PreferenceKeyVisitor { + visitor.visit(key: Key.self) + } +} diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/HostPreferenceKey.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/HostPreferenceKey.swift new file mode 100644 index 00000000..d8d88e1a --- /dev/null +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/HostPreferenceKey.swift @@ -0,0 +1,9 @@ +// +// HostPreferenceKey.swift +// OpenSwiftUI +// +// Created by Kyle on 2023/1/5. +// Lastest Version: iOS 15.5 +// Status: Complete + +protocol HostPreferenceKey: PreferenceKey {} diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift new file mode 100644 index 00000000..0d45a000 --- /dev/null +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift @@ -0,0 +1,11 @@ +// +// PreferenceKeyVisitor.swift +// OpenSwiftUI +// +// Created by Kyle on 2023/1/5. +// Lastest Version: iOS 15.5 +// Status: Complete + +protocol PreferenceKeyVisitor { + func visit(key: Key.Type) +} diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift new file mode 100644 index 00000000..5ffcb745 --- /dev/null +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift @@ -0,0 +1 @@ +struct PreferenceList {} From 80b63f80182832be4fbe015199aa7ce8f5d9bdd5 Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 5 Jan 2024 16:02:27 +0800 Subject: [PATCH 2/3] Update VersionSeed implementation --- .../Internal/PreferenceKeyVisitor.swift | 2 +- .../Preferences/Internal/PreferenceList.swift | 35 +++++++++- .../Internal/Graph/VersionSeed.swift | 70 +++++++++++++++++++ .../VersionSeed/VersionSeedTests.swift | 21 ++++++ 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift create mode 100644 Tests/OpenSwiftUITests/Internal/VersionSeed/VersionSeedTests.swift diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift index 0d45a000..56e7dea9 100644 --- a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceKeyVisitor.swift @@ -7,5 +7,5 @@ // Status: Complete protocol PreferenceKeyVisitor { - func visit(key: Key.Type) + mutating func visit(key: Key.Type) } diff --git a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift index 5ffcb745..916b4631 100644 --- a/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift +++ b/Sources/OpenSwiftUI/DataAndStorage/Preferences/Internal/PreferenceList.swift @@ -1 +1,34 @@ -struct PreferenceList {} +// +// PreferenceList.swift +// OpenSwiftUI +// +// Created by Kyle on 2023/1/5. +// Lastest Version: iOS 15.5 +// Status: WIP + +struct PreferenceList { + private var first: PreferenceNode? + + subscript(_ keyType: Key.Type) -> Value { + get { fatalError("TODO") } + set { fatalError("TODO") } + } +} + +extension PreferenceList { + struct Value { + var value: V + var seed: VersionSeed + } +} + +private class PreferenceNode { + let keyType: Any.Type + let seed: VersionSeed + let mergedSeed: VersionSeed + let next: PreferenceNode? + + init(keyType: Any.Type, seed: VersionSeed, next: PreferenceNode?) { + fatalError("TODO") + } +} diff --git a/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift b/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift new file mode 100644 index 00000000..02ca8827 --- /dev/null +++ b/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift @@ -0,0 +1,70 @@ +// +// VersionSeed.swift +// OpenSwiftUI +// +// Created by Kyle on 2024/1/5. +// Lastest Version: iOS 15.5 +// Status: WIP +// ID: 1B00D77CE2C80F9C0F5A59FDEA30ED6B + +struct VersionSeed: CustomStringConvertible { + var value: UInt32 + + var description: String { + switch value { + case VersionSeed.zero.value: "empty" + case VersionSeed.invalid.value: "invalid" + default: value.description + } + } + + static var zero: VersionSeed { VersionSeed(value: .zero) } + static var invalid: VersionSeed { VersionSeed(value: .max) } + + var isValid: Bool { value != VersionSeed.invalid.value } +} + +struct VersionSeedTracker { + var seed: VersionSeed +} + +struct VersionSeedSetTracker { + private var values: [Value] + + func addPreference(_ keyType: Key.Type) { + + } + + func updateSeeds(to: PreferenceList) { + + } +} + +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: Key.Type) where Key : PreferenceKey { + let valueSeed = preferences[key].seed + matches = seed.isValid && valueSeed.isValid && seed.value == valueSeed.value + } + } + + private struct UpdateSeedVisitor: PreferenceKeyVisitor { + let preferences: PreferenceList + var seed: VersionSeed? + + mutating func visit(key: Key.Type) where Key : PreferenceKey { + seed = preferences[key].seed + } + } +} diff --git a/Tests/OpenSwiftUITests/Internal/VersionSeed/VersionSeedTests.swift b/Tests/OpenSwiftUITests/Internal/VersionSeed/VersionSeedTests.swift new file mode 100644 index 00000000..c6d34ef2 --- /dev/null +++ b/Tests/OpenSwiftUITests/Internal/VersionSeed/VersionSeedTests.swift @@ -0,0 +1,21 @@ +// +// VersionSeedTests.swift +// +// +// Created by Kyle on 2024/1/5. +// + +@testable import OpenSwiftUI +import Testing + +struct VersionSeedTests { + @Test(arguments: [ + (0, "empty"), + (UInt32.max, "invalid"), + (2, "2"), + ]) + func description(value: UInt32, expectedDescription: String) { + let seed = VersionSeed(value: value) + #expect(seed.description == expectedDescription) + } +} From 620df742eab5b47fead69bcaae54f8e44d1eb18b Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 5 Jan 2024 16:34:51 +0800 Subject: [PATCH 3/3] Complete VersionSeed implementation --- .../Internal/Graph/VersionSeed.swift | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift b/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift index 02ca8827..0859e31f 100644 --- a/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift +++ b/Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift @@ -4,7 +4,7 @@ // // Created by Kyle on 2024/1/5. // Lastest Version: iOS 15.5 -// Status: WIP +// Status: Complete // ID: 1B00D77CE2C80F9C0F5A59FDEA30ED6B struct VersionSeed: CustomStringConvertible { @@ -31,12 +31,19 @@ struct VersionSeedTracker { struct VersionSeedSetTracker { private var values: [Value] - func addPreference(_ keyType: Key.Type) { - + mutating func addPreference(_: Key.Type) { + values.append(Value(key: _AnyPreferenceKey.self, seed: .invalid)) } - func updateSeeds(to: PreferenceList) { - + 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 + } } } @@ -53,7 +60,7 @@ extension VersionSeedSetTracker { var seed: VersionSeed var matches: Bool? - mutating func visit(key: Key.Type) where Key : PreferenceKey { + mutating func visit(key: (some PreferenceKey).Type) { let valueSeed = preferences[key].seed matches = seed.isValid && valueSeed.isValid && seed.value == valueSeed.value } @@ -63,7 +70,7 @@ extension VersionSeedSetTracker { let preferences: PreferenceList var seed: VersionSeed? - mutating func visit(key: Key.Type) where Key : PreferenceKey { + mutating func visit(key: (some PreferenceKey).Type) { seed = preferences[key].seed } }