Skip to content

Commit

Permalink
Update AnyView and ViewDebug.makeView
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Ye committed Apr 5, 2024
1 parent 0cb73bb commit d8c5824
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 28 deletions.
21 changes: 19 additions & 2 deletions Sources/OpenSwiftUI/Core/Graph/GraphInputs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public struct _GraphInputs {
var cachedEnvironment: MutableBox<CachedEnvironment>
var phase: Attribute<_GraphInputs.Phase>
var transaction: Attribute<Transaction>
var changedDebugProperties: _ViewDebug.Properties
private var changedDebugProperties: _ViewDebug.Properties
private var options: _GraphInputs.Options
#if canImport(Darwin) // FIXME: See #39
var mergedInputs: Set<OGAttribute>
Expand Down Expand Up @@ -55,14 +55,31 @@ public struct _GraphInputs {
set { customInputs[type] = newValue }
}

// MARK: - cachedEnvironment

@inline(__always)
func detechedEnvironmentInputs() -> Self {
var newInputs = self
newInputs.cachedEnvironment = MutableBox(cachedEnvironment.wrappedValue)
return newInputs
}

// MARK: Options
@inline(__always)
mutating func updateCachedEnvironment(_ box: MutableBox<CachedEnvironment>) {
cachedEnvironment = box
changedDebugProperties.insert(.environment)
}

// MARK: - changedDebugProperties

@inline(__always)
func withEmptyChangedDebugPropertiesInputs<R>(_ body: (_GraphInputs) -> R) -> R {
var inputs = self
inputs.changedDebugProperties = []
return body(inputs)
}

// MARK: - options

@inline(__always)
var enableLayout: Bool {
Expand Down
17 changes: 9 additions & 8 deletions Sources/OpenSwiftUI/Core/View/CustomView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ internal import OpenGraphShims

extension View {
static func makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
var inputs = inputs
inputs.base.changedDebugProperties = []
let fields = DynamicPropertyCache.fields(of: Self.self)
let (body, buffer) = makeBody(view: view, inputs: &inputs.base, fields: fields)
OGSubgraph.beginTreeElement(value: body.value, flags: 0)
var outputs = Body._makeView(view: body, inputs: inputs)
if OGSubgraph.shouldRecordTree {
_ViewDebug.reallyWrap(&outputs, value: body, inputs: &inputs) // FIXME
OGSubgraph.endTreeElement(value: body.value)
var inputs = inputs
let (body, buffer) = inputs.withMutateGraphInputs { inputs in
makeBody(view: view, inputs: &inputs, fields: fields)
}
let outputs = _ViewDebug.makeView(
view: body,
inputs: inputs
) { view, inputs in
Body._makeView(view: body, inputs: inputs)
}
if let buffer {
buffer.traceMountedProperties(to: body, fields: fields)
Expand Down
5 changes: 3 additions & 2 deletions Sources/OpenSwiftUI/Core/View/ViewGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,9 @@ final class ViewGraph: GraphHost {
as: RootGeometry.self,
invalidating: true
) { rootGeometry in
// FIXME
rootGeometry.$layoutDirection = inputs.base.cachedEnvironment.wrappedValue.attribute(keyPath: \.layoutDirection)
inputs.withMutableCachedEnviroment {
rootGeometry.$layoutDirection = $0.attribute(keyPath: \.layoutDirection)
}
}
// TOOD
return makeRootView(rootView, inputs)
Expand Down
74 changes: 67 additions & 7 deletions Sources/OpenSwiftUI/Core/View/ViewInputs.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
internal import OpenGraphShims

public struct _ViewInputs {
var base: _GraphInputs
private var base: _GraphInputs
var preferences: PreferencesInputs
var transform: Attribute<ViewTransform>
var position: Attribute<ViewOrigin>
var containerPosition: Attribute<ViewOrigin>
var size: Attribute<ViewSize>
var safeAreaInsets: OptionalAttribute<SafeAreaInsets>

@inline(__always)
func detechedEnvironmentInputs() -> Self {
var newInputs = self
newInputs.base = self.base.detechedEnvironmentInputs()
return newInputs
init(
base: _GraphInputs,
preferences: PreferencesInputs,
transform: Attribute<ViewTransform>,
position: Attribute<ViewOrigin>,
containerPosition: Attribute<ViewOrigin>,
size: Attribute<ViewSize>,
safeAreaInsets: OptionalAttribute<SafeAreaInsets>
) {
self.base = base
self.preferences = preferences
self.transform = transform
self.position = position
self.containerPosition = containerPosition
self.size = size
self.safeAreaInsets = safeAreaInsets
}

func makeIndirectOutputs() -> _ViewOutputs {
Expand All @@ -36,7 +47,56 @@ public struct _ViewInputs {
}
return outputs
}


// MARK: - base

@inline(__always)
mutating func withMutateGraphInputs<R>(_ body: (inout _GraphInputs) -> R) -> R {
body(&base)
}

// MARK: - base.customInputs

@inline(__always)
func withCustomInputs<R>(_ body: (PropertyList) -> R) -> R {
body(base.customInputs)
}

@inline(__always)
mutating func withMutableCustomInputs<R>(_ body: (inout PropertyList) -> R) -> R {
body(&base.customInputs)
}

// MARK: - base.cachedEnvironment

@inline(__always)
func withCachedEnviroment<R>(_ body: (CachedEnvironment) -> R) -> R {
body(base.cachedEnvironment.wrappedValue)
}

@inline(__always)
func withMutableCachedEnviroment<R>(_ body: (inout CachedEnvironment) -> R) -> R {
body(&base.cachedEnvironment.wrappedValue)
}

@inline(__always)
func detechedEnvironmentInputs() -> Self {
var newInputs = self
newInputs.base = self.base.detechedEnvironmentInputs()
return newInputs
}

// MARK: - base.changedDebugProperties

@inline(__always)
func withEmptyChangedDebugPropertiesInputs<R>(_ body: (_ViewInputs) -> R) -> R {
var newInputs = self
return base.withEmptyChangedDebugPropertiesInputs {
newInputs.base = $0
return body(newInputs)
}
}

// MARK: Options

@inline(__always)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ public struct _EnvironmentKeyTransformModifier<Value>: PrimitiveViewModifier, _G
)
let attribute = Attribute(childEnvironment)
let cachedEnvironment = CachedEnvironment(attribute)
inputs.cachedEnvironment = MutableBox(cachedEnvironment)
inputs.changedDebugProperties.insert(.environment)
inputs.updateCachedEnvironment(MutableBox(cachedEnvironment))
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenSwiftUI/Data/Preference/PreferenceBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ final class PreferenceBridge {
}

func wrapInputs(_ inputs: inout _ViewInputs) {
inputs.base.customInputs = bridgedViewInputs
inputs.withMutableCustomInputs { $0 = bridgedViewInputs }
inputs.preferences.merge(requestedPreferences)
inputs.preferences.hostKeys = Attribute(MergePreferenceKeys(lhs: inputs.preferences.hostKeys, rhs: _hostPreferenceKeys))
}
Expand All @@ -165,7 +165,7 @@ final class PreferenceBridge {
result = Attribute(PreferenceCombiner<Key>(attributes: [])).identifier
}
}
bridgedViewInputs = inputs.base.customInputs
inputs.withCustomInputs { bridgedViewInputs = $0 }
for key in inputs.preferences.keys {
if key == _AnyPreferenceKey<HostPreferencesKey>.self {
let combiner = Attribute(HostPreferencesCombiner(
Expand Down
28 changes: 25 additions & 3 deletions Sources/OpenSwiftUI/View/Debug/TODO/ViewDebug.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,31 @@ extension _ViewDebug {
OGSubgraph.setShouldRecordTree()
}
}

// TODO:
/*private*/ static func reallyWrap<Value>(_: inout _ViewOutputs, value: _GraphValue<Value>, inputs _: UnsafePointer<_ViewInputs>) {}

@_transparent
@inline(__always)
static func makeView<Value>(
view: _GraphValue<Value>,
inputs: _ViewInputs,
body: (_ view: _GraphValue<Value>, _ inputs: _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
var inputs = inputs
if OGSubgraph.shouldRecordTree {
OGSubgraph.beginTreeElement(value: view.value, flags: 0)
}
var outputs = inputs.withEmptyChangedDebugPropertiesInputs { inputs in
body(view, inputs)
}
if OGSubgraph.shouldRecordTree {
_ViewDebug.reallyWrap(&outputs, value: view, inputs: &inputs)
OGSubgraph.endTreeElement(value: view.value)
}
return outputs
}

private static func reallyWrap<Value>(_: inout _ViewOutputs, value: _GraphValue<Value>, inputs _: UnsafePointer<_ViewInputs>) {
// TODO
}

fileprivate static func appendDebugData(from: Int/*AGTreeElement*/ , to: [_ViewDebug.Data]) {}
}
Expand Down
47 changes: 45 additions & 2 deletions Sources/OpenSwiftUI/View/View/AnyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class AnyViewStorageBase {
fileprivate var canTransition: Bool { fatalError() }
fileprivate func matches(_ other: AnyViewStorageBase) -> Bool { fatalError() }
fileprivate func makeChild(
uniqueID: UInt32,
uniqueId: UInt32,
container: Attribute<AnyViewInfo>,
inputs: _ViewInputs
) -> _ViewOutputs {
Expand Down Expand Up @@ -104,6 +104,21 @@ private final class AnyViewStorage<V: View>: AnyViewStorageBase {
other is AnyViewStorage<V>
}

override func makeChild(
uniqueId: UInt32,
container: Attribute<AnyViewInfo>,
inputs: _ViewInputs
) -> _ViewOutputs {
let child = AnyViewChild<V>(info: container, uniqueId: uniqueId)
let graphValue = _GraphValue(Attribute(child))
return _ViewDebug.makeView(
view: graphValue,
inputs: inputs
) { view, inputs in
V._makeView(view: view, inputs: inputs)
}
}

override func child<Value>() -> Value { view as! Value }

// TODO
Expand Down Expand Up @@ -155,7 +170,11 @@ private struct AnyViewContainer: StatefulRule, AsyncAttribute {
parentSubgraph.addChild(childGraph)
return childGraph.apply {
let childInputs = inputs.detechedEnvironmentInputs()
let childOutputs = storage.makeChild(uniqueID: uniqueId, container: current.unsafeCast(to: AnyViewInfo.self), inputs: childInputs)
let childOutputs = storage.makeChild(
uniqueId: uniqueId,
container: current.unsafeCast(to: AnyViewInfo.self),
inputs: childInputs
)
outputs.attachIndirectOutputs(to: childOutputs)
return AnyViewInfo(item: storage, subgraph: childGraph, uniqueID: uniqueId)
}
Expand All @@ -168,3 +187,27 @@ private struct AnyViewContainer: StatefulRule, AsyncAttribute {
subgraph.invalidate()
}
}

private struct AnyViewChild<V: View>: StatefulRule, AsyncAttribute {
@Attribute var info: AnyViewInfo
let uniqueId: UInt32

typealias Value = V

func updateValue() {
guard uniqueId == info.uniqueID else {
return
}
value = info.item.child()
}
}

extension AnyViewChild: CustomStringConvertible {
var description: String { "\(V.self)" }
}

// TODO
private struct AnyViewChildList<V: View> {
@Attribute var view: AnyView
var id: UniqueID?
}

0 comments on commit d8c5824

Please sign in to comment.