Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AnyView implementation #59

Merged
merged 11 commits into from
Apr 5, 2024
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
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
Loading