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
25 changes: 23 additions & 2 deletions Sources/OpenSwiftUI/App/App/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
// Status: Complete
// ID: 20E520D074F8AF54E6253E3E22B86490 (SwiftUI)

import OpenSwiftUICore

// MARK: - App

/// A type that represents the structure and behavior of an app.
///
/// Create an app by declaring a structure that conforms to the `App` protocol.
Expand Down Expand Up @@ -140,6 +144,25 @@ extension App {
}
}

// MARK: - AppRootModifier

private var appRootViewWrappers: [(AnyView) -> AnyView] = []

@_spi(Private)
public func registerAppRootModifier<M>(_ modifier: M) where M: ViewModifier {
appRootViewWrappers.append({ AnyView($0.modifier(modifier)) })
}

func applyAppRootModifier(_ view: AnyView) -> AnyView {
var result = view
for modifier in appRootViewWrappers {
result = modifier(result)
}
return result
}

// MARK: - Platform implementation

#if os(iOS) || os(visionOS)
import UIKit
typealias DelegateBaseClass = UIResponder
Expand All @@ -165,5 +188,3 @@ func runTestingApp<V1, V2>(rootView: V1, comparisonView: V2, didLaunch: @escapin
_openSwiftUIPlatformUnimplementedFailure()
}
#endif

/*private*/ var appRootViewWrappers: [(AnyView) -> AnyView] = []
182 changes: 144 additions & 38 deletions Sources/OpenSwiftUI/App/App/UIKit/UIKitAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
// ID: 4475FD12FD59DEBA453321BD91F6EA04 (SwiftUI)

#if os(iOS) || os(visionOS)
import UIKit
import OpenAttributeGraphShims
package import OpenSwiftUICore
public import UIKit
#if OPENSWIFTUI_OPENCOMBINE
import OpenCombine
#else
import Combine
#endif

// MARK: - AppDelegate [TODO]

Expand Down Expand Up @@ -136,45 +143,144 @@ class AppSceneDelegate: UIResponder, UIWindowSceneDelegate {
super.init()
}

// private var rootModifier: RootModifier {
//
// }
//
// private func makeRootView(_ view: AnyView) -> ModifiedContent<AnyView, RootModifier> {
// // for each appRootViewWrappers and then rootModifier
// }
private var rootModifier: RootModifier {
guard let sceneBridge else {
preconditionFailure("Application configuration error.")
}
guard let sceneStorageValues else {
preconditionFailure("State restoration error.")
}
return RootModifier(
sceneBridge: sceneBridge,
sceneDelegateBox: sceneDelegateBox,
sceneStorageValues: sceneStorageValues,
presentationDataValue: presentationDataValue,
scenePhase: scenePhase,
sceneID: sceneItemID
)
}

private func makeRootView(_ view: AnyView) -> ModifiedContent<AnyView, RootModifier> {
applyAppRootModifier(view).modifier(rootModifier)
}
}

//struct SwiftUI.RootModifier {
// weak var sceneBridge: Swift.Optional<SwiftUI.SceneBridge>
// weak var sceneDelegateBox: Swift.Optional<SwiftUI.AnyFallbackDelegateBox>
// weak var sceneStorageValues: Swift.Optional<SwiftUI.SceneStorageValues>
// var presentationDataValue: Swift.Optional<Swift.AnyHashable>
// var scenePhase: SwiftUI.ScenePhase
// var sceneID: Swift.Optional<SwiftUI.SceneID>
// var _rootFocusScope: SwiftUI.Namespace
//}
//struct SwiftUI.(SceneSessionKey in _4475FD12FD59DEBA453321BD91F6EA04) {
// /* Static Stored Variable */
// static SwiftUI.(SceneSessionKey in _4475FD12FD59DEBA453321BD91F6EA04).defaultValue : Swift.Optional<SwiftUI.WeakBox<__C.UISceneSession>>
//}
//struct SwiftUI.(RootEnvironmentModifier in _4475FD12FD59DEBA453321BD91F6EA04) {
// weak var sceneBridge: Swift.Optional<SwiftUI.SceneBridge>
// weak var sceneDelegateBox: Swift.Optional<SwiftUI.AnyFallbackDelegateBox>
// weak var sceneStorageValues: Swift.Optional<SwiftUI.SceneStorageValues>
// var scenePhase: SwiftUI.ScenePhase
// var sceneID: Swift.Optional<SwiftUI.SceneID>
//}
//struct SwiftUI.(RootEnvironmentModifier in _4475FD12FD59DEBA453321BD91F6EA04).Child {
// var _modifier: AttributeGraph.Attribute<SwiftUI.(RootEnvironmentModifier in _4475FD12FD59DEBA453321BD91F6EA04)>
// var _env: AttributeGraph.Attribute<SwiftUI.EnvironmentValues>
// var oldModifier: Swift.Optional<SwiftUI.(RootEnvironmentModifier in _4475FD12FD59DEBA453321BD91F6EA04)>
//
// /* Function */
// SwiftUI.(RootEnvironmentModifier in _4475FD12FD59DEBA453321BD91F6EA04).Child.updateValue() -> ()
//}
// MARK: - RootModifier

struct RootModifier: ViewModifier {
weak var sceneBridge: SceneBridge?
weak var sceneDelegateBox: AnyFallbackDelegateBox?
weak var sceneStorageValues: SceneStorageValues?
var presentationDataValue: AnyHashable?
var scenePhase: ScenePhase
var sceneID: SceneID?
@Namespace var rootFocusScope

func body(content: Content) -> some View {
content
.rootEnvironment(
sceneBridge: sceneBridge,
sceneDelegateBox: sceneDelegateBox,
sceneStorageValues: sceneStorageValues,
scenePhase: scenePhase,
sceneID: sceneID
)
.presentedSceneValue(presentationDataValue)
}
}

// MARK: - EnvironmentValues + sceneSession

private struct SceneSessionKey: EnvironmentKey {
static let defaultValue: WeakBox<UISceneSession>? = nil
}

@_spi(Private)
@available(OpenSwiftUI_v2_0, *)
@available(macOS, unavailable)
@available(watchOS, unavailable)
extension EnvironmentValues {
public var sceneSession: UISceneSession? {
get { self[SceneSessionKey.self]?.base }
set { self[SceneSessionKey.self] = newValue.map(WeakBox.init) }
}
}

// MARK: - RootEnvironmentModifier

extension View {
func rootEnvironment(
sceneBridge: SceneBridge? = nil,
sceneDelegateBox: AnyFallbackDelegateBox? = nil,
sceneStorageValues: SceneStorageValues? = nil,
scenePhase: ScenePhase = .background,
sceneID: SceneID? = nil
) -> some View {
modifier(RootEnvironmentModifier(
sceneBridge: sceneBridge,
sceneDelegateBox: sceneDelegateBox,
sceneStorageValues: sceneStorageValues,
scenePhase: scenePhase,
sceneID: sceneID
))
}
}

private struct RootEnvironmentModifier: PrimitiveViewModifier, _GraphInputsModifier {
weak var sceneBridge: SceneBridge?
weak var sceneDelegateBox: AnyFallbackDelegateBox?
weak var sceneStorageValues: SceneStorageValues?
var scenePhase: ScenePhase
var sceneID: SceneID?

static func _makeInputs(
modifier: _GraphValue<Self>,
inputs: inout _GraphInputs
) {
inputs.environment = Attribute(
Child(
modifier: modifier.value,
env: inputs.environment
)
)
}

// TODO
class SceneStorageValues {}
struct Child: StatefulRule {
@Attribute var modifier: RootEnvironmentModifier
@Attribute var env: EnvironmentValues
var oldModifier: RootEnvironmentModifier?

typealias Value = EnvironmentValues

mutating func updateValue() {
let (modifier, modifierChanged) = $modifier.changedValue()
let (environment, environmentChanged) = $env.changedValue()
let shouldUpdate: Bool
if environmentChanged {
shouldUpdate = true
} else if modifierChanged && oldModifier.map({ compareValues($0, modifier) }) != false {
shouldUpdate = true
} else if !hasValue {
shouldUpdate = true
} else {
shouldUpdate = false
}
guard shouldUpdate else {
return
}
var result = environment
result[keyPath: SceneBridge.environmentStore] = modifier.sceneBridge
result.sceneStorageValues = modifier.sceneStorageValues
result.scenePhase = modifier.scenePhase
result.sceneID = modifier.sceneID
if modifier.scenePhase != .active {
result.redactionReasons.formUnion(.privacy)
}
modifier.sceneDelegateBox?.addDelegate(to: &result)
AppGraph.delegateBox?.addDelegate(to: &result)
value = result
oldModifier = modifier
}
}
}
#endif
4 changes: 4 additions & 0 deletions Sources/OpenSwiftUI/App/Scene/ScenePhase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Status: Complete
// ID: 130BB08D98602D712FD59CAC6992C14A (SwiftUI)

// MARK: - ScenePhase

/// An indication of a scene's operational state.
///
/// The system moves your app's ``Scene`` instances through phases that reflect
Expand Down Expand Up @@ -96,6 +98,8 @@ public enum ScenePhase: Comparable {
case active
}

// MARK: - EnvironmentValues + scenePhase

private struct ScenePhaseKey: EnvironmentKey {
static let defaultValue: ScenePhase = .background
}
Expand Down
26 changes: 26 additions & 0 deletions Sources/OpenSwiftUI/App/Scene/SceneStorage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// SceneStorage.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: TODO
// ID: 1700ED20D4EA891B02973E899ABDB425 (SwiftUI)

import OpenSwiftUICore

// MARK: - SceneStorageValues [WIP]

class SceneStorageValues {}

// MARK: - EnvironmentValues + sceneStorageValues

private struct SceneStorageValuesKey: EnvironmentKey {
static let defaultValue: WeakBox<SceneStorageValues>? = nil
}

extension EnvironmentValues {
var sceneStorageValues: SceneStorageValues? {
get { self[SceneStorageValuesKey.self]?.base }
set { self[SceneStorageValuesKey.self] = newValue.map(WeakBox.init) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// PresentedSceneValueInputModifier.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: TODO
// ID: 16926B370582AC5E886A9B0FCFCEA0ED (SwiftUI?)

import OpenAttributeGraphShims
import OpenSwiftUICore

extension WindowGroup {
// TODO
}

// TODO
public struct PresentedWindowContent {}

// MARK: - PresentedSceneValueInput

private struct PresentedSceneValueInput: ViewInput {
static var defaultValue: OptionalAttribute<AnyHashable?> { .init() }
}

// MARK: - PresentedSceneValueInputModifier

extension View {
func presentedSceneValue(
_ value: AnyHashable?
) -> some View {
modifier(PresentedSceneValueInputModifier(presentedValue: value))
}
}

private struct PresentedSceneValueInputModifier: ViewInputsModifier {
var presentedValue: AnyHashable?

static func _makeViewInputs(
modifier: _GraphValue<Self>,
inputs: inout _ViewInputs
) {
inputs[PresentedSceneValueInput.self] = .init(modifier.value.presentedValue)
}
}
Loading