diff --git a/Package.resolved b/Package.resolved index 66dbe3c..f288005 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,7 +6,7 @@ "location" : "https://github.com/OpenSwiftUIProject/OpenGraph", "state" : { "branch" : "main", - "revision" : "8baf226a2dd579d70febed94aa5bb23a04e1e56e" + "revision" : "ed01e7196afe56bf953f2f14b0b463208dda9c8d" } }, { diff --git a/Sources/OpenSwiftUI/Core/Attribute/AsyncAttribute.swift b/Sources/OpenSwiftUI/Core/Attribute/AsyncAttribute.swift new file mode 100644 index 0000000..a92582b --- /dev/null +++ b/Sources/OpenSwiftUI/Core/Attribute/AsyncAttribute.swift @@ -0,0 +1,16 @@ +// +// AsyncAttribute.swift +// OpenSwiftUI +// +// Audited for RELEASE_2021 +// Status: WIP + +internal import OpenGraphShims + +protocol AsyncAttribute: _AttributeBody {} + +extension Attribute { + func syncMainIfReferences(do body: (Value) -> V) -> V { + fatalError("TODO") + } +} diff --git a/Sources/OpenSwiftUI/Data/Environment/EnvironmentKeyTransformModifier.swift b/Sources/OpenSwiftUI/Data/Environment/EnvironmentKeyTransformModifier.swift index d0e2973..a2e5cb5 100644 --- a/Sources/OpenSwiftUI/Data/Environment/EnvironmentKeyTransformModifier.swift +++ b/Sources/OpenSwiftUI/Data/Environment/EnvironmentKeyTransformModifier.swift @@ -3,9 +3,11 @@ // OpenSwiftUI // // Audited for RELEASE_2021 -// Status: WIP +// Status: Blocked by syncMainIfReferences // ID: 1DBD4F024EFF0E73A70DB6DD05D5B548 +internal import OpenGraphShims + @frozen public struct _EnvironmentKeyTransformModifier: PrimitiveViewModifier, _GraphInputsModifier { public var keyPath: WritableKeyPath @@ -17,12 +19,22 @@ public struct _EnvironmentKeyTransformModifier: PrimitiveViewModifier, _G self.transform = transform } - public static func _makeInputs(modifier: _GraphValue<_EnvironmentKeyTransformModifier>, inputs: inout _GraphInputs) { - + public static func _makeInputs(modifier: _GraphValue, inputs: inout _GraphInputs) { + let childEnvironment = ChildEnvironment( + modifier: modifier.value, + environment: inputs.cachedEnvironment.wrappedValue.environment, + oldKeyPath: nil + ) + let attribute = Attribute(childEnvironment) + let cachedEnvironment = CachedEnvironment(attribute) + inputs.cachedEnvironment = MutableBox(cachedEnvironment) + inputs.changedDebugProperties.insert(.environment) } } extension View { + /// Transforms the environment value of the specified key path with the + /// given function. @inlinable public func transformEnvironment( _ keyPath: WritableKeyPath, @@ -35,6 +47,47 @@ extension View { } } -private struct ChildEnvironment { +private struct ChildEnvironment: StatefulRule, AsyncAttribute { + @Attribute + private var modifier: _EnvironmentKeyTransformModifier + private var _environment: Attribute + private var oldValue: Value? + private var oldKeyPath: WritableKeyPath? + + init(modifier: Attribute<_EnvironmentKeyTransformModifier>, + environment: Attribute, + oldValue: Value? = nil, + oldKeyPath: WritableKeyPath? + ) { + _modifier = modifier + _environment = environment + self.oldValue = oldValue + self.oldKeyPath = oldKeyPath + } + var description: String { + "EnvironmentTransform: EnvironmentValues" + } + + typealias Value = EnvironmentValues + + mutating func updateValue() { + var (environment, environmentChanged) = _environment.changedValue() + let keyPath = modifier.keyPath + var newValue = environment[keyPath: keyPath] + _modifier.syncMainIfReferences { modifier in + modifier.transform(&newValue) + } + guard !environmentChanged, + let valueChanged = oldValue.map({ compareValues($0, newValue, mode: ._2) }), !valueChanged, + let keyPathChanged = oldKeyPath.map({ $0 == keyPath }), !keyPathChanged, + hasValue + else { + environment[keyPath: keyPath] = newValue + value = environment + oldValue = newValue + oldKeyPath = keyPath + return + } + } } diff --git a/Sources/OpenSwiftUI/View/Core/Debug/TODO/ViewDebug.swift b/Sources/OpenSwiftUI/View/Core/Debug/TODO/ViewDebug.swift index 81ff293..c2a582c 100644 --- a/Sources/OpenSwiftUI/View/Core/Debug/TODO/ViewDebug.swift +++ b/Sources/OpenSwiftUI/View/Core/Debug/TODO/ViewDebug.swift @@ -56,16 +56,16 @@ extension _ViewDebug { self.rawValue = rawValue } - public static let type = Property(rawValue: 1 << Property.type.rawValue) - public static let value = Property(rawValue: 1 << Property.value.rawValue) - public static let transform = Property(rawValue: 1 << Property.transform.rawValue) - public static let position = Property(rawValue: 1 << Property.position.rawValue) - public static let size = Property(rawValue: 1 << Property.size.rawValue) - public static let environment = Property(rawValue: 1 << Property.environment.rawValue) - public static let phase = Property(rawValue: 1 << Property.phase.rawValue) - public static let layoutComputer = Property(rawValue: 1 << Property.layoutComputer.rawValue) - public static let displayList = Property(rawValue: 1 << Property.displayList.rawValue) - public static let all = Property(rawValue: 0xFFFF_FFFF) + public static let type = Properties(rawValue: 1 << Property.type.rawValue) + public static let value = Properties(rawValue: 1 << Property.value.rawValue) + public static let transform = Properties(rawValue: 1 << Property.transform.rawValue) + public static let position = Properties(rawValue: 1 << Property.position.rawValue) + public static let size = Properties(rawValue: 1 << Property.size.rawValue) + public static let environment = Properties(rawValue: 1 << Property.environment.rawValue) + public static let phase = Properties(rawValue: 1 << Property.phase.rawValue) + public static let layoutComputer = Properties(rawValue: 1 << Property.layoutComputer.rawValue) + public static let displayList = Properties(rawValue: 1 << Property.displayList.rawValue) + public static let all = Properties(rawValue: 0xFFFF_FFFF) } }