Skip to content

Commit

Permalink
Add AnyView implementation (#59)
Browse files Browse the repository at this point in the history
* Update ViewDebug and OG version

* Update View location

* Update View Accessor

* Add AnyViewInfo and AnyViewStorageBase

* Update AnyViewContainer

* Add intern implementation

* Update AnyView._makeView

* Update AnyViewStorage

* Update AnyView and ViewDebug.makeView

* Fix GraphHost crash bug

* Fix Linux build issue
  • Loading branch information
Kyle-Ye authored Apr 5, 2024
1 parent 14597bb commit 93b09bf
Show file tree
Hide file tree
Showing 21 changed files with 620 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"location" : "https://github.com/OpenSwiftUIProject/OpenGraph",
"state" : {
"branch" : "main",
"revision" : "dd6cacbdcf2af1d8f7ce2b0e7194a920935326de"
"revision" : "c952860989b69c4537146b323c0ec1cb3f8fb206"
}
},
{
Expand Down
17 changes: 17 additions & 0 deletions Sources/OpenSwiftUI/Core/BodyAccessor/ViewBodyAccessor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// ViewBodyAccessor.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: WIP

struct ViewBodyAccessor<Container: View>: BodyAccessor {
typealias Body = Container.Body

func updateBody(of: Container, changed: Bool) {
guard changed else {
return
}
// TODO
}
}
7 changes: 5 additions & 2 deletions Sources/OpenSwiftUI/Core/Graph/GraphHost.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ class GraphHost {
}

final func intern<Value>(_ value: Value, id: _GraphInputs.ConstantID) -> Attribute<Value> {
fatalError("TODO")
let id = id.internID
return data.globalSubgraph.apply {
data.inputs.intern(value, id: id.internID)
}
}

final func setNeedsUpdate(mayDeferUpdate: Bool) {
Expand Down Expand Up @@ -385,7 +388,7 @@ private final class AsyncTransaction {

extension OGGraph {
final func graphHost() -> GraphHost {
context!.assumingMemoryBound(to: GraphHost.self).pointee
unsafeBitCast(context, to: GraphHost.self)
}

fileprivate final func setGraphHost(_ graphHost: GraphHost) {
Expand Down
47 changes: 45 additions & 2 deletions Sources/OpenSwiftUI/Core/Graph/GraphInputs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public struct _GraphInputs {
var cachedEnvironment: MutableBox<CachedEnvironment>
var phase: Attribute<_GraphInputs.Phase>
var transaction: Attribute<Transaction>
var changedDebugProperties: _ViewDebug.Properties
var options: _GraphInputs.Options
private var changedDebugProperties: _ViewDebug.Properties
private var options: _GraphInputs.Options
#if canImport(Darwin) // FIXME: See #39
var mergedInputs: Set<OGAttribute>
#endif
Expand Down Expand Up @@ -54,6 +54,38 @@ public struct _GraphInputs {
get { customInputs[type] }
set { customInputs[type] = newValue }
}

// MARK: - cachedEnvironment

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

@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 {
get { options.contains(.enableLayout) }
// TODO: setter
}
}

extension _GraphInputs {
Expand All @@ -65,9 +97,20 @@ extension _GraphInputs {
extension _GraphInputs {
struct Options: OptionSet {
let rawValue: UInt32

static var enableLayout: Options { Options(rawValue: 1 << 1) }
}
}

extension _GraphInputs {
typealias ConstantID = Int

func intern<Value>(_ value: Value, id: ConstantID) -> Attribute<Value> {
cachedEnvironment.wrappedValue.intern(value, id: id.internID)
}
}

extension _GraphInputs.ConstantID {
@inline(__always)
var internID: Self { self & 0x1 }
}
44 changes: 44 additions & 0 deletions Sources/OpenSwiftUI/Core/View/CustomView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// CustomView.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: WIP
// ID: 9F92ACD17B554E8AB7D29ABB1E796415

internal import OpenGraphShims

extension View {
static func makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
let fields = DynamicPropertyCache.fields(of: Self.self)
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)
}
return outputs
}

private static func makeBody(
view: _GraphValue<Self>,
inputs: inout _GraphInputs,
fields: DynamicPropertyCache.Fields
) -> (_GraphValue<Body>, _DynamicPropertyBuffer?) {
let kind = OGTypeID(Self.self).kind
switch kind {
case .struct, .enum, .optional, .tuple:
let accessor = ViewBodyAccessor<Self>()
return accessor.makeBody(container: view, inputs: &inputs, fields: fields)
default:
fatalError("views must be value types (either a struct or an enum); \(Self.self) is a class.")
}
}
}
11 changes: 0 additions & 11 deletions Sources/OpenSwiftUI/Core/View/TODO/_ViewInputs.swift

This file was deleted.

12 changes: 0 additions & 12 deletions Sources/OpenSwiftUI/Core/View/TODO/_ViewOutputs.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/// }
///
/// Assemble the view's body by combining one or more of the built-in views
/// provided by SwiftUI, like the ``Text`` instance in the example above, plus
/// provided by OpenSwiftUI, like the ``Text`` instance in the example above, plus
/// other custom views that you define, into a hierarchy of views. For more
/// information about creating custom views, see <doc:Declaring-a-Custom-View>.
///
Expand All @@ -43,16 +43,18 @@
/// custom view modifiers for easy reuse.
@_typeEraser(AnyView)
public protocol View {
static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs
static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs
static func _viewListCount(inputs: _ViewListCountInputs) -> Int?

/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required ``View/body-swift.property`` property.
associatedtype Body: View

static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs

static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs

static func _viewListCount(inputs: _ViewListCountInputs) -> Int?

/// The content and behavior of the view.
///
/// When you implement a custom view, you must implement a computed
Expand All @@ -73,24 +75,25 @@ public protocol View {
var body: Self.Body { get }
}

// FIXME
extension View {
public static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
.init()
makeView(view: view, inputs: inputs)
}

public static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs {
.init()
fatalError("TODO")
}

public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? {
nil
Body._viewListCount(inputs: inputs)
}
}


// MARK: - Never + View

extension Never: View {
public var body: Never {
// FIXME: should be "brk #1"
fatalError()
}
public var body: Never { self }
}

extension View {
Expand Down
11 changes: 8 additions & 3 deletions Sources/OpenSwiftUI/Core/View/ViewGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ final class ViewGraph: GraphHost {
@Attribute var dimensions: ViewSize
@Attribute var updateSeed: UInt32
// TODO
@Attribute var defaultLayoutComputer: LayoutComputer
// TODO
var cachedSizeThatFits: CGSize = .invalidValue
var sizeThatFitsObserver: SizeThatFitsObserver? {
didSet {
Expand Down Expand Up @@ -72,6 +74,8 @@ final class ViewGraph: GraphHost {
_position = _rootGeometry.origin()
_dimensions = _rootGeometry.size()
_updateSeed = Attribute(value: .zero)
// TODO
_defaultLayoutComputer = Attribute(value: .defaultValue)
// FIXME
makeRootView = { view, inputs in
let rootView = _GraphValue<Body>(view.unsafeCast(to: Body.self))
Expand Down Expand Up @@ -200,7 +204,7 @@ final class ViewGraph: GraphHost {
)
if requestedOutputs.contains(.layout) {
// FIXME
inputs.base.options.formUnion(.init(rawValue: 0xe2))
// inputs.base.options.formUnion(.init(rawValue: 0xe2))
}
requestedOutputs.addRequestedPreferences(to: &inputs)
_preferenceBridge?.wrapInputs(&inputs)
Expand All @@ -211,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
Loading

0 comments on commit 93b09bf

Please sign in to comment.