Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Sources/OpenSwiftUICore/Data/Update.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,15 @@ package enum Update {
depth -= 1
unlock()
}


@inlinable
@inline(__always)
static func perform<T>(_ body: () throws -> T) rethrows -> T {
begin()
defer { end() }
return try body()
}

package static func enqueueAction(_ action: @escaping () -> Void) {
begin()
actions.append(action)
Expand Down
12 changes: 11 additions & 1 deletion Sources/OpenSwiftUICore/Event/Event/EventBindingManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// OpenSwiftUICore
//
// Status: WIP
// ID: D63F4C292364B83D9F441CFC1A31B3F3 (SwiftUICore)

import Foundation

Expand Down Expand Up @@ -58,9 +59,18 @@ final public class EventBindingManager {
preconditionFailure("TODO")
}

private func sendDownstream(_ events: [EventID: any EventType]) -> Set<EventID> {
preconditionFailure("TODO")
}

@discardableResult
package func send(_ events: [EventID: any EventType]) -> Set<EventID> {
preconditionFailure("TODO")
Update.locked { [weak self] in
guard let self else {
return []
}
return sendDownstream(events)
}
}

package func send<E>(_ event: E, id: Int) where E: EventType {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenSwiftUICore/Event/Gesture/Gesture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private struct GestureBodyAccessor<Container>: BodyAccessor where Container: Ges

@available(OpenSwiftUI_v1_0, *)
extension Gesture where Value == Body.Value {
public static func _makeGesture(
nonisolated public static func _makeGesture(
gesture: _GraphValue<Self>,
inputs: _GestureInputs
) -> _GestureOutputs<Self.Body.Value> {
Expand Down
3 changes: 1 addition & 2 deletions Sources/OpenSwiftUICore/Event/Gesture/GestureDebug.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ extension GestureDebug.Data: Defaultable {

// MARK: - PrimitiveDebuggableGesture [6.5.4]

package protocol PrimitiveDebuggableGesture {
}
package protocol PrimitiveDebuggableGesture {}

// MARK: - DebuggableGesturePhase [6.5.4]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private struct DependentGesture<V>: GestureModifier {

var dependency: GestureDependency

static func _makeGesture(
nonisolated static func _makeGesture(
modifier: _GraphValue<Self>,
inputs: _GestureInputs,
body: (_GestureInputs) -> _GestureOutputs<Value>
Expand Down
94 changes: 65 additions & 29 deletions Sources/OpenSwiftUICore/Event/Gesture/GestureGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//
// Status: WIP

import OpenGraphShims

// MARK: - GestureGraphDelegate [6.5.4]

package protocol GestureGraphDelegate: AnyObject {
Expand All @@ -13,67 +15,101 @@ package protocol GestureGraphDelegate: AnyObject {
// MARK: - GestureGraph [6.5.4] [WIP]

final package class GestureGraph: GraphHost, EventGraphHost, CustomStringConvertible {
package init(eventBindingManager: EventBindingManager) {
weak var rootResponder: AnyGestureResponder?
weak var delegate: GestureGraphDelegate?
package let eventBindingManager: EventBindingManager
@Attribute private var gestureTime: Time
@Attribute private var gestureEvents: [EventID: any EventType]
@Attribute private var inheritedPhase: _GestureInputs.InheritedPhase
@Attribute private var gestureResetSeed: UInt32
@OptionalAttribute private var rootPhase: GesturePhase<()>?
@OptionalAttribute private var gestureDebug: GestureDebug.Data?
@OptionalAttribute private var gestureCategoryAttr: GestureCategory?
@OptionalAttribute private var gestureLabelAttr: String??
@OptionalAttribute private var isCancellableAttr: Bool?
@OptionalAttribute private var requiredTapCountAttr: Int??
@OptionalAttribute private var gestureDependencyAttr: GestureDependency?
@Attribute private var gesturePreferenceKeys: PreferenceKeys
var nextUpdateTime: Time

init(rootResponder: AnyGestureResponder) {
self.rootResponder = rootResponder
preconditionFailure("TODO")
}

final package let eventBindingManager: EventBindingManager

final package var description: String {
get { preconditionFailure("TODO") }
package var description: String {
"GestureGraph<\(rootResponder.map { String(describing: $0.gestureType) } ?? "nil")> \(self)"
}

override final package func instantiateOutputs() {
override package func instantiateOutputs() {
preconditionFailure("TODO")
}

override final package func uninstantiateOutputs() {
preconditionFailure("TODO")
override package func uninstantiateOutputs() {
$rootPhase = nil
_ = gestureEvents
gestureEvents = [:]
inheritedPhase = .failed
gestureResetSeed = .zero
gesturePreferenceKeys = .init()
if let rootResponder {
rootResponder.resetGesture()
}
}

override final package func timeDidChange() {
preconditionFailure("TODO")
override package func timeDidChange() {
nextUpdateTime = .infinity
}

final package var responderNode: ResponderNode? {
get { preconditionFailure("TODO") }
package var responderNode: ResponderNode? {
rootResponder
}

final package var focusedResponder: ResponderNode? {
get { preconditionFailure("TODO") }
package var focusedResponder: ResponderNode? {
guard let rootResponder,
let host = rootResponder.host,
let eventGraphHost = host.as(EventGraphHost.self) else {
return nil
}
return eventGraphHost.focusedResponder
}

final package var nextGestureUpdateTime: Time {
get { preconditionFailure("TODO") }
package var nextGestureUpdateTime: Time {
nextUpdateTime
}

final package func setInheritedPhase(_ phase: _GestureInputs.InheritedPhase) {
preconditionFailure("TODO")
package func setInheritedPhase(_ phase: _GestureInputs.InheritedPhase) {
inheritedPhase = phase
}

final package func sendEvents(
package func sendEvents(
_ events: [EventID: any EventType],
rootNode: ResponderNode,
at time: Time
) -> GesturePhase<Void> {
guard let rootResponder, rootResponder.isValid else {
return .failed
}
preconditionFailure("TODO")
}

final package func resetEvents() {
preconditionFailure("TODO")
package func resetEvents() {
uninstantiate(immediately: false)
}

final package func enqueueAction(_ action: @escaping () -> Void) {
preconditionFailure("TODO")
package func enqueueAction(_ action: @escaping () -> Void) {
delegate?.enqueueAction(action)
}

final package func gestureCategory() -> GestureCategory? {
preconditionFailure("TODO")
package func gestureCategory() -> GestureCategory? {
guard let rootResponder, rootResponder.isValid else {
return nil
}
return Update.perform {
instantiateIfNeeded()
return gestureCategoryAttr
}
}

// @objc deinit {
// preconditionFailure("TODO")
// }
}

extension GestureGraph {
Expand Down
14 changes: 11 additions & 3 deletions Sources/OpenSwiftUICore/Event/Gesture/GestureModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// GestureModifier.swift
// OpenSwiftUICore
//
// Status: Blocked by makeDebuggableGesture
// Status: Complete

package protocol GestureModifier {
associatedtype Value
Expand Down Expand Up @@ -33,10 +33,18 @@ package struct ModifierGesture<ContentModifier, Content>: PrimitiveGesture
package typealias Value = ContentModifier.Value

package static func _makeGesture(
gesture: _GraphValue<ModifierGesture<ContentModifier, Content>>,
gesture: _GraphValue<Self>,
inputs: _GestureInputs
) -> _GestureOutputs<ContentModifier.Value> {
preconditionFailure("TODO")
ContentModifier.makeDebuggableGesture(
modifier: gesture[offset: { .of(&$0.modifier) }],
inputs: inputs
) { inputs in
Content.makeDebuggableGesture(
gesture: gesture[offset: { .of(&$0.content) }],
inputs: inputs
)
}
}
}

Expand Down
38 changes: 20 additions & 18 deletions Sources/OpenSwiftUICore/Event/Gesture/GestureViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ extension GestureViewModifier {
body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
var outputs = body(_Graph(), inputs)
if inputs.preferences.contains(ViewRespondersKey.self) {
if inputs.preferences.requiresViewResponders {
let filter = GestureFilter(
children: outputs.viewResponders(),
modifier: modifier.value,
inputs: inputs,
viewSubgraph: .current!
)
outputs.preferences[ViewRespondersKey.self] = Attribute(filter)
outputs.preferences.viewResponders = Attribute(filter)
}
let provider = inputs.gestureAccessibilityProvider
provider.makeGesture(
Expand Down Expand Up @@ -225,7 +225,7 @@ private class GestureResponder<Modifier>/*: AnyGestureResponder where Modifier:
// MARK: - GestureAccessibilityProvider [6.5.4]

package protocol GestureAccessibilityProvider {
static func makeGesture(
nonisolated static func makeGesture(
mask: @autoclosure () -> Attribute<GestureMask>,
inputs: _ViewInputs,
outputs: inout _ViewOutputs
Expand All @@ -237,7 +237,7 @@ private struct GestureAccessibilityProviderKey: GraphInput {
}

struct EmptyGestureAccessibilityProvider: GestureAccessibilityProvider {
static func makeGesture(
nonisolated static func makeGesture(
mask: @autoclosure () -> Attribute<GestureMask>,
inputs: _ViewInputs,
outputs: inout _ViewOutputs
Expand All @@ -259,17 +259,19 @@ extension _ViewInputs {
}
}

// MARK: - Optional: Gesture

//extension Optional: Gesture where Wrapped: Gesture {
// public typealias Value = Wrapped.Value
//
// public static func _makeGesture(
// gesture: _GraphValue<Optional<Wrapped>>,
// inputs: _GestureInputs
// ) -> _GestureOutputs<Wrapped.Value> { preconditionFailure("TODO") }
//
// public typealias Body = Never
//}
//
//extension Optional: PrimitiveGesture where Wrapped: Gesture {}
// MARK: - Optional: Gesture [WIP]

extension Optional: Gesture where Wrapped: Gesture {
public typealias Value = Wrapped.Value

nonisolated public static func _makeGesture(
gesture: _GraphValue<Optional<Wrapped>>,
inputs: _GestureInputs
) -> _GestureOutputs<Wrapped.Value> {
preconditionFailure("TODO")
}

public typealias Body = Never
}

extension Optional: PrimitiveGesture where Wrapped: Gesture {}
60 changes: 60 additions & 0 deletions Sources/OpenSwiftUICore/Event/Responder/ContentPathObserver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// ContentPathObserver.swift
// OpenSwiftUICore
//
// Status: Complete

@_spi(ForOpenSwiftUIOnly)
@available(OpenSwiftUI_v6_0, *)
public struct ContentPathChanges: OptionSet {
public var rawValue: UInt8

public init(rawValue: UInt8) {
self.rawValue = rawValue
}

package static let data: ContentPathChanges = .init(rawValue: 1 << 0)

package static let size: ContentPathChanges = .init(rawValue: 1 << 1)

package static let transform: ContentPathChanges = .init(rawValue: 1 << 2)
}

@_spi(ForOpenSwiftUIOnly)
@available(*, unavailable)
extension ContentPathChanges: Sendable {}

@_spi(ForOpenSwiftUIOnly)
@available(OpenSwiftUI_v6_0, *)
public protocol ContentPathObserver: AnyObject {
func respondersDidChange(
for parent: ViewResponder
)

func contentPathDidChange(
for parent: ViewResponder,
changes: ContentPathChanges,
transform: (old: ViewTransform, new: ViewTransform),
finished: inout Bool
)
}

package protocol TrivialContentPathObserver: ContentPathObserver {
func contentPathDidChange(for parent: ViewResponder)
}

extension TrivialContentPathObserver {
package func contentPathDidChange(
for parent: ViewResponder,
changes: ContentPathChanges,
transform: (old: ViewTransform, new: ViewTransform),
finished: inout Bool
) {
contentPathDidChange(for: parent)
finished = true
}

package func respondersDidChange(for parent: ViewResponder) {
contentPathDidChange(for: parent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ open class ResponderNode {
@available(*, unavailable)
extension ResponderNode: Sendable {}

// MARK: - ResponderVisitorResult [6.5.4] [WIP]
// MARK: - ResponderVisitorResult [6.5.4]

@_spi(ForOpenSwiftUIOnly)
@available(OpenSwiftUI_v6_0, *)
Expand Down
Loading