Skip to content

Commit

Permalink
Add VersionSeed support (#18)
Browse files Browse the repository at this point in the history
* Add PreferenceKey related protocol

* Update VersionSeed implementation

* Complete VersionSeed implementation
  • Loading branch information
Kyle-Ye authored Jan 5, 2024
1 parent a517a4d commit 9783793
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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: PreferenceKeyVisitor>(_ visitor: inout Visitor)
}

struct _AnyPreferenceKey<Key: PreferenceKey>: AnyPreferenceKey {
static var valueType: Any.Type { Key.self }

static func visitKey<Visitor>(_ visitor: inout Visitor) where Visitor : PreferenceKeyVisitor {
visitor.visit(key: Key.self)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// HostPreferenceKey.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/1/5.
// Lastest Version: iOS 15.5
// Status: Complete

protocol HostPreferenceKey: PreferenceKey {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// PreferenceKeyVisitor.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/1/5.
// Lastest Version: iOS 15.5
// Status: Complete

protocol PreferenceKeyVisitor {
mutating func visit<Key: PreferenceKey>(key: Key.Type)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// PreferenceList.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/1/5.
// Lastest Version: iOS 15.5
// Status: WIP

struct PreferenceList {
private var first: PreferenceNode?

subscript<Key: PreferenceKey>(_ keyType: Key.Type) -> Value<Key.Value> {
get { fatalError("TODO") }
set { fatalError("TODO") }
}
}

extension PreferenceList {
struct Value<V> {
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")
}
}
77 changes: 77 additions & 0 deletions Sources/OpenSwiftUI/Internal/Graph/VersionSeed.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// VersionSeed.swift
// OpenSwiftUI
//
// Created by Kyle on 2024/1/5.
// Lastest Version: iOS 15.5
// Status: Complete
// 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<Key: HostPreferenceKey> {
var seed: VersionSeed
}

struct VersionSeedSetTracker {
private var values: [Value]

mutating func addPreference<Key: HostPreferenceKey>(_: Key.Type) {
values.append(Value(key: _AnyPreferenceKey<Key>.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.isValid && valueSeed.isValid && seed.value == valueSeed.value
}
}

private struct UpdateSeedVisitor: PreferenceKeyVisitor {
let preferences: PreferenceList
var seed: VersionSeed?

mutating func visit(key: (some PreferenceKey).Type) {
seed = preferences[key].seed
}
}
}
21 changes: 21 additions & 0 deletions Tests/OpenSwiftUITests/Internal/VersionSeed/VersionSeedTests.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit 9783793

Please sign in to comment.