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
7 changes: 6 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool {
var sharedSwiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("BareSlashRegexLiterals"),
.enableUpcomingFeature("InternalImportsByDefault"),
.enableUpcomingFeature("InferSendableFromCaptures"),
.define("OPENSWIFTUI_SUPPRESS_DEPRECATED_WARNINGS"),
.swiftLanguageMode(.v5),
]
Expand Down Expand Up @@ -74,7 +75,11 @@ if development {

let warningsAsErrorsCondition = envEnable("OPENSWIFTUI_WERROR", default: isXcodeEnv && development)
if warningsAsErrorsCondition {
sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
// Hold off the werror feature as we can't avoid the concurrency warning.
// Reenable the folllowing after swift-evolution#443 is release.

// sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
// sharedSwiftSettings.append(.unsafeFlags(["-Wwarning", "concurrency"]))
}

// NOTE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ public struct EnvironmentValues: CustomStringConvertible {
private var _plist: PropertyList
private let tracker: PropertyList.Tracker?

// FIXME
var plist: PropertyList { _plist }

init(plist: PropertyList) {
_plist = plist
tracker = nil
Expand Down
86 changes: 84 additions & 2 deletions Sources/OpenSwiftUICore/Data/Environment/EnvironmentalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,97 @@
// OpenSwiftUICore
//
// Audited for iOS 18.0
// Status: WIP
// Status: Blocked by Tracing

import OpenGraphShims

// MARK: - EnvironmentalView

@MainActor
@preconcurrency
package protocol EnvironmentalView: PrimitiveView, UnaryView {
associatedtype EnvironmentBody: View
func body(environment: EnvironmentValues) -> EnvironmentBody
}

extension EnvironmentalView {
nonisolated public static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
preconditionFailure("")
let child = EnvironmentalViewChild(view: view.value, env: inputs.environment)
return EnvironmentBody.makeDebuggableView(view: _GraphValue(child), inputs: inputs)
}
}

// MARK: - EnvironmentalViewChild

struct EnvironmentalViewChild<V>: StatefulRule, AsyncAttribute, CustomStringConvertible where V: EnvironmentalView {
@Attribute var view: V
@Attribute var env: EnvironmentValues
let tracker: PropertyList.Tracker

init(view: Attribute<V>, env: Attribute<EnvironmentValues>) {
_view = view
_env = env
tracker = .init()
}

typealias Value = V.EnvironmentBody

func updateValue() {
let (view, viewChanged) = $view.changedValue()
let (env, envChanged) = $env.changedValue()

let shouldReset: Bool
if viewChanged {
shouldReset = true
} else if envChanged, tracker.hasDifferentUsedValues(env.plist) {
shouldReset = true
} else {
// TODO: Optimize this API call
let outputValue: UnsafePointer<V.EnvironmentBody>? = Graph.outputValue()
shouldReset = outputValue == nil
}
guard shouldReset else { return }
tracker.reset()
tracker.initializeValues(from: env.plist)
// TODO: Tracing
value = view.body(environment: env)
}

var description: String {
"EnvironmentReading: \(V.self)"
}
}

// MARK: - EnvironmentReader

@MainActor
@preconcurrency
package struct EnvironmentReader<Content>: EnvironmentalView where Content: View {
let content: (EnvironmentValues) -> Content

package init(@ViewBuilder _ content: @escaping (EnvironmentValues) -> Content) {
self.content = content
}

package func body(environment: EnvironmentValues) -> Content {
content(environment)
}

nonisolated package static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs {
guard Semantics.EnvironmentReaderViewIsMulti.isEnabled else {
return _ViewListOutputs.unaryViewList(view: view, inputs: inputs)
}
let child = EnvironmentalViewChild(view: view.value, env: inputs.base.environment)
return EnvironmentBody.makeDebuggableViewList(view: _GraphValue(child), inputs: inputs)
}

nonisolated package static func _viewListCount(inputs: _ViewListCountInputs) -> Int? {
guard Semantics.EnvironmentReaderViewIsMulti.isEnabled else {
return 1
}
return Content._viewListCount(inputs: inputs)
}

package typealias Body = Never
package typealias EnvironmentBody = Content
}
1 change: 0 additions & 1 deletion Sources/OpenSwiftUICore/Graph/GraphValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public struct _GraphValue<Value>: Equatable {

package func unsafeBitCast<T>(to _: T.Type) -> _GraphValue<T> {
_GraphValue<T>(value.unsafeBitCast(to: T.self))

}

public static func == (a: _GraphValue<Value>, b: _GraphValue<Value>) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenSwiftUICore/Modifier/ModifiedContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

extension View {
@inlinable
public func modifier<T>(_ modifier: T) -> ModifiedContent<Self, T> {
nonisolated public func modifier<T>(_ modifier: T) -> ModifiedContent<Self, T> {
.init(content: self, modifier: modifier)
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
// Status: WIP

@frozen
public struct _EnvironmentKeyWritingModifier<Value>: ViewModifier/*, _GraphInputsModifier*/ {
public struct _EnvironmentKeyWritingModifier<Value>: ViewModifier, _GraphInputsModifier, PrimitiveViewModifier {
public var keyPath: WritableKeyPath<EnvironmentValues, Value>
public var value: Value

@inlinable
@inline(__always)
public init(keyPath: WritableKeyPath<EnvironmentValues, Value>, value: Value) {
self.keyPath = keyPath
self.value = value
Expand All @@ -20,12 +19,16 @@ public struct _EnvironmentKeyWritingModifier<Value>: ViewModifier/*, _GraphInput
public static func _makeInputs(modifier: _GraphValue<_EnvironmentKeyWritingModifier<Value>>, inputs: inout _GraphInputs) {
// TODO
}


}

@available(*, unavailable)
extension _EnvironmentKeyWritingModifier: Sendable {}

extension View {
@inlinable
@inline(__always)
public func environment<V>(_ keyPath: WritableKeyPath<EnvironmentValues, V>, _ value: V) -> some View {
nonisolated public func environment<V>(_ keyPath: WritableKeyPath<EnvironmentValues, V>, _ value: V) -> some View {
modifier(_EnvironmentKeyWritingModifier<V>(keyPath: keyPath, value: value))
}
}
72 changes: 37 additions & 35 deletions Sources/OpenSwiftUICore/Modifier/ViewModifier/ViewModifier.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// ViewModifier.swift
// OpenSwiftUI
// OpenSwiftUICore
//
// Audited for iOS 15.5
// Status: Complete
Expand Down Expand Up @@ -48,68 +48,45 @@
/// Downtown Bus. A view extension, using custom a modifier, renders the
/// caption in blue text surrounded by a rounded
/// rectangle.](OpenSwiftUI-View-ViewModifier.png)
@MainActor
@preconcurrency
public protocol ViewModifier {
/// The type of view representing the body.
associatedtype Body: View

/// Makes a new view using the view modifier and inputs that you provide.
static func _makeView(
nonisolated static func _makeView(
modifier: _GraphValue<Self>,
inputs: _ViewInputs,
body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs

static func _makeViewList(
nonisolated static func _makeViewList(
modifier: _GraphValue<Self>,
inputs: _ViewListInputs,
body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs
) -> _ViewListOutputs

/// The number of views that `_makeViewList()` would produce, or
/// nil if unknown.
static func _viewListCount(
nonisolated static func _viewListCount(
inputs: _ViewListCountInputs,
body: (_ViewListCountInputs) -> Int?
) -> Int?

/// The content view type passed to `body()`.
typealias Content = _ViewModifier_Content<Self>
/// The type of view representing the body.
associatedtype Body: View

/// Gets the current body of the caller.
///
/// `content` is a proxy for the view that will have the modifier
/// represented by `Self` applied to it.
@ViewBuilder
@MainActor
@preconcurrency
func body(content: Content) -> Body
}

extension ViewModifier {
public static func _makeView(
modifier: _GraphValue<Self>,
inputs: _ViewInputs,
body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
makeView(modifier: modifier, inputs: inputs, body: body)
}

public static func _makeViewList(
modifier: _GraphValue<Self>,
inputs: _ViewListInputs,
body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs
) -> _ViewListOutputs {
makeViewList(modifier: modifier, inputs: inputs, body: body)
}

public static func _viewListCount(
inputs: _ViewListCountInputs,
body: (_ViewListCountInputs) -> Int?
) -> Int? {
viewListCount(inputs: inputs, body: body)
}
/// The content view type passed to `body()`.
typealias Content = _ViewModifier_Content<Self>
}

package protocol PrimitiveViewModifier: ViewModifier where Body == Never {}

extension ViewModifier where Body == Never {
public func body(content _: Content) -> Never {
bodyError()
Expand Down Expand Up @@ -163,3 +140,28 @@ extension ViewModifier {
preconditionFailure("body() should not be called on \(Self.self)")
}
}

extension ViewModifier {
public static func _makeView(
modifier: _GraphValue<Self>,
inputs: _ViewInputs,
body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
makeView(modifier: modifier, inputs: inputs, body: body)
}

public static func _makeViewList(
modifier: _GraphValue<Self>,
inputs: _ViewListInputs,
body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs
) -> _ViewListOutputs {
makeViewList(modifier: modifier, inputs: inputs, body: body)
}

public static func _viewListCount(
inputs: _ViewListCountInputs,
body: (_ViewListCountInputs) -> Int?
) -> Int? {
viewListCount(inputs: inputs, body: body)
}
}
46 changes: 20 additions & 26 deletions Sources/OpenSwiftUICore/View/AnyView.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
//
// AnyView.swift
// OpenSwiftUI
// OpenSwiftUICore
//
// Audited for iOS 15.5
// Audited for iOS 18.0
// Status: WIP
// ID: A96961F3546506F21D8995C6092F15B5
// ID: A96961F3546506F21D8995C6092F15B5 (OpenSwiftUI)
// ID: 7578D05D331D7F1A2E0C2F8DEF38AAD4 (OpenSwiftUICore)

import OpenGraphShims
import OpenSwiftUI_SPI

@frozen
public struct AnyView: PrimitiveView {
public struct AnyView: View, PrimitiveView {
var storage: AnyViewStorageBase

public init<V>(_ view: V) where V: View {
self.init(view, id: nil)
if let anyView = view as? AnyView {
storage = anyView.storage
} else {
storage = AnyViewStorage(view: view)
}
}

@_alwaysEmitIntoClient
Expand Down Expand Up @@ -42,19 +47,7 @@ public struct AnyView: PrimitiveView {
}
self = visitor.view!
}

init<V: View>(_ view: V, id: UniqueID?) {
if let anyView = view as? AnyView {
storage = anyView.storage
} else {
storage = AnyViewStorage(view: view, id: id)
}
}

func visitContent<Visitor: ViewVisitor>(_ visitor: inout Visitor) {
storage.visitContent(&visitor)
}


public static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
#if canImport(Darwin)
let outputs = inputs.makeIndirectOutputs()
Expand All @@ -76,16 +69,14 @@ public struct AnyView: PrimitiveView {
public static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs {
preconditionFailure("TODO")
}

package func visitContent<Visitor: ViewVisitor>(_ visitor: inout Visitor) {
storage.visitContent(&visitor)
}
}

@usableFromInline
class AnyViewStorageBase {
let id: UniqueID?

init(id: UniqueID?) {
self.id = id
}

fileprivate var type: Any.Type { preconditionFailure("") }
fileprivate var canTransition: Bool { preconditionFailure("") }
fileprivate func matches(_ other: AnyViewStorageBase) -> Bool { preconditionFailure("") }
Expand All @@ -111,10 +102,13 @@ class AnyViewStorageBase {
private final class AnyViewStorage<V: View>: AnyViewStorageBase {
let view: V

init(view: V, id: UniqueID?) {
init(view: V) {
self.view = view
super.init(id: id)
super.init()
}

// FIXME
var id: UniqueID? { nil }

override var type: Any.Type { V.self }

Expand Down
Loading
Loading