From 2c68e831d590c2a4c5cea449ab83cdbb98ce9c87 Mon Sep 17 00:00:00 2001 From: Carson Katri Date: Fri, 9 Apr 2021 09:52:06 -0400 Subject: [PATCH 1/2] Add dynamicMemberLookup attribute to Binding --- Sources/TokamakCore/State/Binding.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/TokamakCore/State/Binding.swift b/Sources/TokamakCore/State/Binding.swift index 8b8ab6d41..672bc76ff 100644 --- a/Sources/TokamakCore/State/Binding.swift +++ b/Sources/TokamakCore/State/Binding.swift @@ -21,7 +21,9 @@ typealias Updater = (inout T) -> () view's state in-place synchronously, but only schedule an update with the renderer at a later time. */ -@propertyWrapper public struct Binding: DynamicProperty { +@propertyWrapper +@dynamicMemberLookup +public struct Binding: DynamicProperty { public var wrappedValue: Value { get { get() } nonmutating set { set(newValue) } From eab532aa5667045645c0df95b24c17f78a6adb00 Mon Sep 17 00:00:00 2001 From: Carson Katri Date: Fri, 9 Apr 2021 11:21:09 -0400 Subject: [PATCH 2/2] Add @inlinable where SwiftUI uses it --- Sources/TokamakCore/Environment/Environment.swift | 11 ++++++----- .../TokamakCore/Environment/EnvironmentKey.swift | 2 ++ Sources/TokamakCore/Modifiers/PaddingLayout.swift | 4 ++++ Sources/TokamakCore/Modifiers/StyleModifiers.swift | 5 +++++ .../TokamakCore/MountedViews/MountedElement.swift | 8 ++++---- Sources/TokamakCore/MountedViews/MountedScene.swift | 2 +- .../Preferences/_PreferenceActionModifier.swift | 1 + .../Preferences/_PreferenceReadingView.swift | 4 ++++ .../Preferences/_PreferenceTransformModifier.swift | 2 ++ .../Preferences/_PreferenceWritingModifier.swift | 2 ++ Sources/TokamakCore/Shapes/ModifiedShapes.swift | 1 + Sources/TokamakCore/Shapes/Shape.swift | 1 + Sources/TokamakCore/Tokens/Angle.swift | 10 ++++++++-- Sources/TokamakCore/Tokens/Color.swift | 2 ++ Sources/TokamakCore/Tokens/ColorScheme.swift | 1 + Sources/TokamakCore/Tokens/Font.swift | 1 + Sources/TokamakCore/Views/Containers/ForEach.swift | 13 ++++++++----- Sources/TokamakCore/Views/Containers/Group.swift | 3 ++- .../TokamakCore/Views/Layout/GeometryReader.swift | 1 + Sources/TokamakCore/Views/Layout/HStack.swift | 1 + Sources/TokamakCore/Views/Layout/VStack.swift | 1 + Sources/TokamakCore/Views/Layout/ZStack.swift | 2 ++ Sources/TokamakCore/Views/Selectors/Picker.swift | 2 +- Sources/TokamakCore/Views/Spacers/Spacer.swift | 1 + Sources/TokamakDemo/ColorDemo.swift | 4 ++-- Sources/TokamakGTK/Modifiers/WidgetModifier.swift | 8 ++++---- .../Modifiers/ModifiedContent.swift | 2 +- 27 files changed, 69 insertions(+), 26 deletions(-) diff --git a/Sources/TokamakCore/Environment/Environment.swift b/Sources/TokamakCore/Environment/Environment.swift index 7e79f8d52..dc1a7c650 100644 --- a/Sources/TokamakCore/Environment/Environment.swift +++ b/Sources/TokamakCore/Environment/Environment.swift @@ -24,20 +24,21 @@ protocol EnvironmentReader { } @propertyWrapper public struct Environment: DynamicProperty { - enum Content { + @usableFromInline enum Content { case keyPath(KeyPath) case value(Value) } - private var content: Content - private let keyPath: KeyPath + @usableFromInline var content: Content + @inlinable public init(_ keyPath: KeyPath) { content = .keyPath(keyPath) - self.keyPath = keyPath } mutating func setContent(from values: EnvironmentValues) { - content = .value(values[keyPath: keyPath]) + if case let .keyPath(keyPath) = content { + content = .value(values[keyPath: keyPath]) + } } public var wrappedValue: Value { diff --git a/Sources/TokamakCore/Environment/EnvironmentKey.swift b/Sources/TokamakCore/Environment/EnvironmentKey.swift index 6f482a892..dd4cc0484 100644 --- a/Sources/TokamakCore/Environment/EnvironmentKey.swift +++ b/Sources/TokamakCore/Environment/EnvironmentKey.swift @@ -25,6 +25,7 @@ public struct _EnvironmentKeyWritingModifier: ViewModifier, EnvironmentMo public let keyPath: WritableKeyPath public let value: Value + @inlinable public init(keyPath: WritableKeyPath, value: Value) { self.keyPath = keyPath self.value = value @@ -38,6 +39,7 @@ public struct _EnvironmentKeyWritingModifier: ViewModifier, EnvironmentMo } public extension View { + @inlinable func environment( _ keyPath: WritableKeyPath, _ value: V diff --git a/Sources/TokamakCore/Modifiers/PaddingLayout.swift b/Sources/TokamakCore/Modifiers/PaddingLayout.swift index 8bed5bdc3..d2f1adb6d 100644 --- a/Sources/TokamakCore/Modifiers/PaddingLayout.swift +++ b/Sources/TokamakCore/Modifiers/PaddingLayout.swift @@ -16,6 +16,7 @@ public struct _PaddingLayout: ViewModifier { public var edges: Edge.Set public var insets: EdgeInsets? + @inlinable public init(edges: Edge.Set = .all, insets: EdgeInsets?) { self.edges = edges self.insets = insets @@ -27,15 +28,18 @@ public struct _PaddingLayout: ViewModifier { } public extension View { + @inlinable func padding(_ insets: EdgeInsets) -> some View { modifier(_PaddingLayout(insets: insets)) } + @inlinable func padding(_ edges: Edge.Set = .all, _ length: CGFloat? = nil) -> some View { let insets = length.map { EdgeInsets(_all: $0) } return modifier(_PaddingLayout(edges: edges, insets: insets)) } + @inlinable func padding(_ length: CGFloat) -> some View { padding(.all, length) } diff --git a/Sources/TokamakCore/Modifiers/StyleModifiers.swift b/Sources/TokamakCore/Modifiers/StyleModifiers.swift index a7f734110..8ea84bcd0 100644 --- a/Sources/TokamakCore/Modifiers/StyleModifiers.swift +++ b/Sources/TokamakCore/Modifiers/StyleModifiers.swift @@ -22,6 +22,7 @@ public struct _BackgroundModifier: ViewModifier, EnvironmentReader public var background: Background public var alignment: Alignment + @inlinable public init(background: Background, alignment: Alignment = .center) { self.background = background self.alignment = alignment @@ -50,6 +51,7 @@ extension _BackgroundModifier: Equatable where Background: Equatable { } public extension View { + @inlinable func background( _ background: Background, alignment: Alignment = .center @@ -65,6 +67,7 @@ public struct _OverlayModifier: ViewModifier, EnvironmentReader public var overlay: Overlay public var alignment: Alignment + @inlinable public init(overlay: Overlay, alignment: Alignment = .center) { self.overlay = overlay self.alignment = alignment @@ -90,12 +93,14 @@ extension _OverlayModifier: Equatable where Overlay: Equatable { } public extension View { + @inlinable func overlay(_ overlay: Overlay, alignment: Alignment = .center) -> some View where Overlay: View { modifier(_OverlayModifier(overlay: overlay, alignment: alignment)) } + @inlinable func border(_ content: S, width: CGFloat = 1) -> some View where S: ShapeStyle { overlay(Rectangle().strokeBorder(content, lineWidth: width)) } diff --git a/Sources/TokamakCore/MountedViews/MountedElement.swift b/Sources/TokamakCore/MountedViews/MountedElement.swift index 95b9b8b44..b51173758 100644 --- a/Sources/TokamakCore/MountedViews/MountedElement.swift +++ b/Sources/TokamakCore/MountedViews/MountedElement.swift @@ -75,10 +75,10 @@ public class MountedElement { var typeConstructorName: String { switch element { case .app: fatalError(""" - `App` values aren't supposed to be reconciled, thus the type constructor name is not stored \ - for `App` elements. Please report this crash as a bug at \ - https://github.com/swiftwasm/Tokamak/issues/new - """) + `App` values aren't supposed to be reconciled, thus the type constructor name is not stored \ + for `App` elements. Please report this crash as a bug at \ + https://github.com/swiftwasm/Tokamak/issues/new + """) case let .scene(scene): return scene.typeConstructorName case let .view(view): return view.typeConstructorName } diff --git a/Sources/TokamakCore/MountedViews/MountedScene.swift b/Sources/TokamakCore/MountedViews/MountedScene.swift index 64c3173f0..dd9f3e60f 100644 --- a/Sources/TokamakCore/MountedViews/MountedScene.swift +++ b/Sources/TokamakCore/MountedViews/MountedScene.swift @@ -97,7 +97,7 @@ extension _AnyScene { ) -> MountedScene { var title: String? if let titledSelf = scene as? TitledScene, - let text = titledSelf.title + let text = titledSelf.title { title = _TextProxy(text).rawText } diff --git a/Sources/TokamakCore/Preferences/_PreferenceActionModifier.swift b/Sources/TokamakCore/Preferences/_PreferenceActionModifier.swift index 0356ee41a..915575650 100644 --- a/Sources/TokamakCore/Preferences/_PreferenceActionModifier.swift +++ b/Sources/TokamakCore/Preferences/_PreferenceActionModifier.swift @@ -19,6 +19,7 @@ public struct _PreferenceActionModifier: _PreferenceWritingModifierProtocol where Key: PreferenceKey, Key.Value: Equatable { public let action: (Key.Value) -> () + @inlinable public init(action: @escaping (Key.Value) -> Swift.Void) { self.action = action } diff --git a/Sources/TokamakCore/Preferences/_PreferenceReadingView.swift b/Sources/TokamakCore/Preferences/_PreferenceReadingView.swift index 227b2e9f9..db42c33f9 100644 --- a/Sources/TokamakCore/Preferences/_PreferenceReadingView.swift +++ b/Sources/TokamakCore/Preferences/_PreferenceReadingView.swift @@ -25,6 +25,7 @@ public struct _DelayedPreferenceView: View, _PreferenceReadingView ) public let transform: (_PreferenceValue) -> Content + @inlinable public init(transform: @escaping (_PreferenceValue) -> Content) { self.transform = transform } @@ -39,6 +40,7 @@ public struct _DelayedPreferenceView: View, _PreferenceReadingView } public extension PreferenceKey { + @inlinable static func _delay( _ transform: @escaping (_PreferenceValue) -> T ) -> some View @@ -49,6 +51,7 @@ public extension PreferenceKey { } public extension View { + @inlinable func overlayPreferenceValue( _ key: Key.Type = Key.self, @ViewBuilder _ transform: @escaping (Key.Value) -> T @@ -58,6 +61,7 @@ public extension View { Key._delay { self.overlay(transform($0.value)) } } + @inlinable func backgroundPreferenceValue( _ key: Key.Type = Key.self, @ViewBuilder _ transform: @escaping (Key.Value) -> T diff --git a/Sources/TokamakCore/Preferences/_PreferenceTransformModifier.swift b/Sources/TokamakCore/Preferences/_PreferenceTransformModifier.swift index 9fbc0ea3c..b8903a9c2 100644 --- a/Sources/TokamakCore/Preferences/_PreferenceTransformModifier.swift +++ b/Sources/TokamakCore/Preferences/_PreferenceTransformModifier.swift @@ -21,6 +21,7 @@ public struct _PreferenceTransformModifier: _PreferenceWritingModifierProto { public let transform: (inout Key.Value) -> () + @inlinable public init( key _: Key.Type = Key.self, transform: @escaping (inout Key.Value) -> () @@ -37,6 +38,7 @@ public struct _PreferenceTransformModifier: _PreferenceWritingModifierProto } public extension View { + @inlinable func transformPreference( _ key: K.Type = K.self, _ callback: @escaping (inout K.Value) -> () diff --git a/Sources/TokamakCore/Preferences/_PreferenceWritingModifier.swift b/Sources/TokamakCore/Preferences/_PreferenceWritingModifier.swift index 0eec368cb..d9915715e 100644 --- a/Sources/TokamakCore/Preferences/_PreferenceWritingModifier.swift +++ b/Sources/TokamakCore/Preferences/_PreferenceWritingModifier.swift @@ -19,6 +19,7 @@ public struct _PreferenceWritingModifier: _PreferenceWritingModifierProtoco where Key: PreferenceKey { public let value: Key.Value + @inlinable public init(key: Key.Type = Key.self, value: Key.Value) { self.value = value } @@ -36,6 +37,7 @@ extension _PreferenceWritingModifier: Equatable where Key.Value: Equatable { } public extension View { + @inlinable func preference(key: K.Type = K.self, value: K.Value) -> some View where K: PreferenceKey { diff --git a/Sources/TokamakCore/Shapes/ModifiedShapes.swift b/Sources/TokamakCore/Shapes/ModifiedShapes.swift index 19317e987..89c188b42 100644 --- a/Sources/TokamakCore/Shapes/ModifiedShapes.swift +++ b/Sources/TokamakCore/Shapes/ModifiedShapes.swift @@ -20,6 +20,7 @@ public struct _StrokedShape: Shape where S: Shape { public var shape: S public var style: StrokeStyle + @inlinable public init(shape: S, style: StrokeStyle) { self.shape = shape self.style = style diff --git a/Sources/TokamakCore/Shapes/Shape.swift b/Sources/TokamakCore/Shapes/Shape.swift index 214efdf51..1891b3f56 100644 --- a/Sources/TokamakCore/Shapes/Shape.swift +++ b/Sources/TokamakCore/Shapes/Shape.swift @@ -53,6 +53,7 @@ public struct _ShapeView: PrimitiveView where Content: Shape, St public var style: Style public var fillStyle: FillStyle + @inlinable public init(shape: Content, style: Style, fillStyle: FillStyle = FillStyle()) { self.shape = shape self.style = style diff --git a/Sources/TokamakCore/Tokens/Angle.swift b/Sources/TokamakCore/Tokens/Angle.swift index cec8e3709..22da541bc 100644 --- a/Sources/TokamakCore/Tokens/Angle.swift +++ b/Sources/TokamakCore/Tokens/Angle.swift @@ -17,32 +17,37 @@ public struct Angle: AdditiveArithmetic { public var radians: Double - public var degrees: Double { + @inlinable public var degrees: Double { get { radians * (180.0 / .pi) } set { radians = newValue * (.pi / 180.0) } } + @inlinable public init() { self.init(radians: 0.0) } + @inlinable public init(radians: Double) { self.radians = radians } + @inlinable public init(degrees: Double) { self.init(radians: degrees * (.pi / 180.0)) } + @inlinable public static func radians(_ radians: Double) -> Angle { Angle(radians: radians) } + @inlinable public static func degrees(_ degrees: Double) -> Angle { Angle(degrees: degrees) } - public static let zero: Angle = .radians(0) + @inlinable public static var zero: Angle { .init() } public static func + (lhs: Self, rhs: Self) -> Self { .radians(lhs.radians + rhs.radians) @@ -64,6 +69,7 @@ public struct Angle: AdditiveArithmetic { } extension Angle: Hashable, Comparable { + @inlinable public static func < (lhs: Self, rhs: Self) -> Bool { lhs.radians < rhs.radians } diff --git a/Sources/TokamakCore/Tokens/Color.swift b/Sources/TokamakCore/Tokens/Color.swift index f36dd689c..20fb560d3 100644 --- a/Sources/TokamakCore/Tokens/Color.swift +++ b/Sources/TokamakCore/Tokens/Color.swift @@ -367,6 +367,7 @@ public extension EnvironmentValues { } public extension View { + @inlinable func accentColor(_ accentColor: Color?) -> some View { environment(\.accentColor, accentColor) } @@ -388,6 +389,7 @@ public extension EnvironmentValues { } public extension View { + @inlinable func foregroundColor(_ color: Color?) -> some View { environment(\.foregroundColor, color) } diff --git a/Sources/TokamakCore/Tokens/ColorScheme.swift b/Sources/TokamakCore/Tokens/ColorScheme.swift index 3914fac73..6d0455238 100644 --- a/Sources/TokamakCore/Tokens/ColorScheme.swift +++ b/Sources/TokamakCore/Tokens/ColorScheme.swift @@ -31,6 +31,7 @@ public extension EnvironmentValues { } public extension View { + @inlinable func colorScheme(_ colorScheme: ColorScheme) -> some View { environment(\.colorScheme, colorScheme) } diff --git a/Sources/TokamakCore/Tokens/Font.swift b/Sources/TokamakCore/Tokens/Font.swift index 3ea487f20..24e2d9ca9 100644 --- a/Sources/TokamakCore/Tokens/Font.swift +++ b/Sources/TokamakCore/Tokens/Font.swift @@ -354,6 +354,7 @@ public extension EnvironmentValues { } public extension View { + @inlinable func font(_ font: Font?) -> some View { environment(\.font, font) } diff --git a/Sources/TokamakCore/Views/Containers/ForEach.swift b/Sources/TokamakCore/Views/Containers/ForEach.swift index 9b8b226d9..8aedcf84f 100644 --- a/Sources/TokamakCore/Views/Containers/ForEach.swift +++ b/Sources/TokamakCore/Views/Containers/ForEach.swift @@ -104,24 +104,27 @@ public protocol _AnyIDView { var anyContent: AnyView { get } } +@usableFromInline struct IDView: View, _AnyIDView where Content: View, ID: Hashable { - let content: Content - let id: ID - var anyId: AnyHashable { AnyHashable(id) } - var anyContent: AnyView { AnyView(content) } + @usableFromInline let content: Content + @usableFromInline let id: ID + @usableFromInline var anyId: AnyHashable { AnyHashable(id) } + @usableFromInline var anyContent: AnyView { AnyView(content) } + @inlinable init(_ content: Content, id: ID) { self.content = content self.id = id } - var body: some View { + @usableFromInline var body: some View { content .environment(\._id, AnyHashable(id)) } } public extension View { + @inlinable func id(_ id: ID) -> some View where ID: Hashable { IDView(self, id: id) } diff --git a/Sources/TokamakCore/Views/Containers/Group.swift b/Sources/TokamakCore/Views/Containers/Group.swift index d174b075b..3b8de794d 100644 --- a/Sources/TokamakCore/Views/Containers/Group.swift +++ b/Sources/TokamakCore/Views/Containers/Group.swift @@ -13,7 +13,8 @@ // limitations under the License. public struct Group { - let content: Content + @usableFromInline let content: Content + @inlinable public init(@ViewBuilder content: () -> Content) { self.content = content() } diff --git a/Sources/TokamakCore/Views/Layout/GeometryReader.swift b/Sources/TokamakCore/Views/Layout/GeometryReader.swift index 49157eb09..1362b2105 100644 --- a/Sources/TokamakCore/Views/Layout/GeometryReader.swift +++ b/Sources/TokamakCore/Views/Layout/GeometryReader.swift @@ -42,6 +42,7 @@ public func makeProxy(from size: CGSize) -> GeometryProxy { public struct GeometryReader: PrimitiveView where Content: View { public let content: (GeometryProxy) -> Content + @inlinable public init(@ViewBuilder content: @escaping (GeometryProxy) -> Content) { self.content = content } diff --git a/Sources/TokamakCore/Views/Layout/HStack.swift b/Sources/TokamakCore/Views/Layout/HStack.swift index 70d1089e3..f9e6f789c 100644 --- a/Sources/TokamakCore/Views/Layout/HStack.swift +++ b/Sources/TokamakCore/Views/Layout/HStack.swift @@ -33,6 +33,7 @@ public struct HStack: PrimitiveView where Content: View { public let spacing: CGFloat? public let content: Content + @inlinable public init( alignment: VerticalAlignment = .center, spacing: CGFloat? = nil, diff --git a/Sources/TokamakCore/Views/Layout/VStack.swift b/Sources/TokamakCore/Views/Layout/VStack.swift index f4f921bdc..2f0303ae4 100644 --- a/Sources/TokamakCore/Views/Layout/VStack.swift +++ b/Sources/TokamakCore/Views/Layout/VStack.swift @@ -30,6 +30,7 @@ public struct VStack: PrimitiveView where Content: View { public let spacing: CGFloat? public let content: Content + @inlinable public init( alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, diff --git a/Sources/TokamakCore/Views/Layout/ZStack.swift b/Sources/TokamakCore/Views/Layout/ZStack.swift index 352b7b814..4769a9559 100644 --- a/Sources/TokamakCore/Views/Layout/ZStack.swift +++ b/Sources/TokamakCore/Views/Layout/ZStack.swift @@ -17,6 +17,7 @@ public struct Alignment: Equatable { public var horizontal: HorizontalAlignment public var vertical: VerticalAlignment + @inlinable public init( horizontal: HorizontalAlignment, vertical: VerticalAlignment @@ -48,6 +49,7 @@ public struct ZStack: PrimitiveView where Content: View { public let spacing: CGFloat? public let content: Content + @inlinable public init( alignment: Alignment = .center, spacing: CGFloat? = nil, diff --git a/Sources/TokamakCore/Views/Selectors/Picker.swift b/Sources/TokamakCore/Views/Selectors/Picker.swift index 3c3bfae2a..cb38728a7 100644 --- a/Sources/TokamakCore/Views/Selectors/Picker.swift +++ b/Sources/TokamakCore/Views/Selectors/Picker.swift @@ -69,7 +69,7 @@ public struct Picker: View // update the binding. ForEach(0..