From bbba53ef929a48fe6c9c4ed3eae1af41715f317e Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 2 Feb 2024 00:15:10 +0800 Subject: [PATCH 1/3] Add FocusState.Binding --- .../EventHandling/Focus/FocusState.swift | 45 +++++++++++++++++++ .../EventHandling/Focus/FocusStore.swift | 23 ++++++++++ .../Focus/FocusStoreLocation.swift | 14 ++++++ .../EventHandling/Focus/FocusedValueKey.swift | 11 +++++ 4 files changed, 93 insertions(+) create mode 100644 Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift create mode 100644 Sources/OpenSwiftUI/EventHandling/Focus/FocusStore.swift create mode 100644 Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift create mode 100644 Sources/OpenSwiftUI/EventHandling/Focus/FocusedValueKey.swift diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift new file mode 100644 index 00000000..9bdd1405 --- /dev/null +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift @@ -0,0 +1,45 @@ +// +// FocusState.swift +// OpenSwiftUI +// +// Created by Kyle on 2024/2/1. +// Lastest Version: iOS 15.5 +// Status: WIP +// ID: 274D264A38B51DC68ACC48A91353B7D0 + +@frozen +//@propertyWrapper +public struct FocusState: DynamicProperty where Value: Hashable { + @frozen + @propertyWrapper + public struct Binding { + @OpenSwiftUI.Binding + private var binding: Value + + init(binding: OpenSwiftUI.Binding) { + _binding = binding + } + + public var wrappedValue: Value { + get { binding } + nonmutating set { binding = newValue } + } + + public var projectedValue: FocusState.Binding { + self + } + + var propertyID: ObjectIdentifier { + if let location = _binding.location as? FocusStoreLocation { + location.id + } else { + #if canImport(ObjectiveC) + ObjectIdentifier(PrivateType.self) + #else + ObjectIdentifier(unsafeBitCast(0, to: AnyObject.self)) + #endif + } + } + private enum PrivateType {} + } +} diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusStore.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStore.swift new file mode 100644 index 00000000..c1243492 --- /dev/null +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStore.swift @@ -0,0 +1,23 @@ +// FIXME +protocol ResponderNode {} + +struct FocusStore { + var seed: VersionSeed + var focusedResponders: ContiguousArray + var plists: [ObjectIdentifier : PropertyList] +} + +// MARK: - FocusStore.Key + +extension FocusStore { + struct Key: PropertyKey { + static var defaultValue: Entry? { nil } + } +} + +// MARK: - FocusStore.Item +extension FocusStore { + struct Entry { + + } +} diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift new file mode 100644 index 00000000..2a13878d --- /dev/null +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift @@ -0,0 +1,14 @@ +class FocusStoreLocation/*: Location*/ { + init() { fatalError() } + + var store: FocusStore + weak var host: GraphHost? + var resetValue: A + var focusSeed: VersionSeed + var failedAssignment: (A, VersionSeed)? + var resolvedEntry: FocusStore.Entry? + var resolvedSeed: VersionSeed + var _wasRead: Bool + + var id: ObjectIdentifier { ObjectIdentifier(self) } +} diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusedValueKey.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusedValueKey.swift new file mode 100644 index 00000000..d8887c28 --- /dev/null +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusedValueKey.swift @@ -0,0 +1,11 @@ +// +// FocusedValueKey.swift +// OpenSwiftUI +// +// Created by Kyle on 2024/2/1. +// Lastest Version: iOS 15.5 +// Status: Complete + +public protocol FocusedValueKey { + associatedtype Value +} From 4bb14a1fd08cf112cbb4d40f2a270d002233ff5e Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 2 Feb 2024 00:34:19 +0800 Subject: [PATCH 2/3] Add FocusState implementation --- .../EventHandling/Focus/FocusState.swift | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift index 9bdd1405..66492547 100644 --- a/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift @@ -8,7 +8,7 @@ // ID: 274D264A38B51DC68ACC48A91353B7D0 @frozen -//@propertyWrapper +@propertyWrapper public struct FocusState: DynamicProperty where Value: Hashable { @frozen @propertyWrapper @@ -40,6 +40,64 @@ public struct FocusState: DynamicProperty where Value: Hashable { #endif } } + private enum PrivateType {} } + + var value: Value + var location: AnyLocation? + var resetValue: Value + public var wrappedValue: Value { + get { + getValue(forReading: true) + } + nonmutating set { + guard let location else { + return + } + location.set(newValue, transaction: Transaction()) + } + } + + public var projectedValue: FocusState.Binding { + let value = getValue(forReading: false) + let binding: OpenSwiftUI.Binding + if let location { + binding = OpenSwiftUI.Binding(value: value, location: location) + } else { + Log.runtimeIssues("Accessing FocusState's value outside of the body of a View. This will result in a constant Binding of the initial value and will not update.") + binding = .constant(value) + } + return Binding(binding: binding) + } + + public static func _makeProperty(in buffer: inout _DynamicPropertyBuffer, container: _GraphValue, fieldOffset: Int, inputs: inout _GraphInputs) { + // TODO + } + + public init() where Value == Bool { + value = false + location = nil + resetValue = false + } + + public init() where Value == T?, T: Hashable { + value = nil + location = nil + resetValue = nil + } + + private func getValue(forReading: Bool) -> Value { + guard let location else { + return value + } + if GraphHost.isUpdating { + if forReading { + location.wasRead = true + } + return value + } else { + return location.get() + } + } } From 246f2ca7d643a801583559d13ec5ae2c0f49d480 Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 2 Feb 2024 00:45:37 +0800 Subject: [PATCH 3/3] Fix cast compile warning --- .../Focus/FocusStoreLocation.swift | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift index 2a13878d..ab229ad4 100644 --- a/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift +++ b/Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift @@ -1,5 +1,24 @@ -class FocusStoreLocation/*: Location*/ { - init() { fatalError() } +class FocusStoreLocation: AnyLocation { + override var wasRead: Bool { + get { + _wasRead + } + set { + _wasRead = newValue + } + } + + override func get() -> A { + fatalError("TODO") + } + + override func set(_ value: A, transaction: Transaction) { + fatalError("TODO") + } + + typealias Value = A + + override init() { fatalError() } var store: FocusStore weak var host: GraphHost?