From e3c69469172c104d659f655850cd1f62b137e81b Mon Sep 17 00:00:00 2001 From: david-swift Date: Thu, 20 Jun 2024 07:20:35 +0200 Subject: [PATCH] Fix modifiers not applied correctly Also fix renderable ignoring arrays of AnyView --- Sources/Model/Extensions/Array.swift | 14 +++++++++----- .../Model/User Interface/View/AnyView.swift | 18 ++++++++++-------- Sources/Model/User Interface/View/Widget.swift | 10 +++++++--- Tests/DemoApp/DemoApp.swift | 12 ++++++++---- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Sources/Model/Extensions/Array.swift b/Sources/Model/Extensions/Array.swift index fed93a9..6b970ff 100644 --- a/Sources/Model/Extensions/Array.swift +++ b/Sources/Model/Extensions/Array.swift @@ -15,10 +15,14 @@ extension Array: AnyView where Element == AnyView { /// Get the debug tree for an array of views. /// - Parameter parameters: Whether the widget parameters should be visible in the tree. /// - Returns: The tree. - public func getBodyDebugTree(parameters: Bool, type: WidgetType.Type) -> String { + public func getBodyDebugTree( + parameters: Bool, + type: WidgetType.Type, + modifiers: [(AnyView) -> AnyView] = [] + ) -> String { var description = "" - for view in self where view.renderable(type: type) { - description += view.getDebugTree(parameters: parameters, type: type) + "\n" + for view in self where view.renderable(type: type, modifiers: modifiers) { + description += view.getDebugTree(parameters: parameters, type: type, modifiers: modifiers) + "\n" } if !description.isEmpty { description.removeLast() @@ -55,7 +59,7 @@ extension Array: AnyView where Element == AnyView { updateProperties: Bool, type: WidgetType.Type ) { - for (index, element) in filter({ $0.renderable(type: type) }).enumerated() { + for (index, element) in filter({ $0.renderable(type: type, modifiers: modifiers) }).enumerated() { if let storage = storage[safe: index] { element .widget(modifiers: modifiers) @@ -72,7 +76,7 @@ extension Array: AnyView where Element == AnyView { modifiers: [(AnyView) -> AnyView], type: WidgetType.Type ) -> [ViewStorage] { - compactMap { $0.renderable(type: type) ? $0.storage(modifiers: [], type: type) : nil } + compactMap { $0.renderable(type: type, modifiers: modifiers) ? $0.storage(modifiers: [], type: type) : nil } } } diff --git a/Sources/Model/User Interface/View/AnyView.swift b/Sources/Model/User Interface/View/AnyView.swift index 9face06..4372946 100644 --- a/Sources/Model/User Interface/View/AnyView.swift +++ b/Sources/Model/User Interface/View/AnyView.swift @@ -27,9 +27,9 @@ extension AnyView { modifiers: [(AnyView) -> AnyView] = [] ) -> String { if let body = getModified(modifiers: modifiers) as? Body { - return body.getBodyDebugTree(parameters: parameters, type: type) + return body.getBodyDebugTree(parameters: parameters, type: type, modifiers: modifiers) } else if let widget = getModified(modifiers: modifiers) as? Widget { - return widget.getViewDescription(parameters: parameters, type: type) + return widget.getViewDescription(parameters: parameters, type: type, modifiers: modifiers) } return """ \(Self.self) { @@ -37,7 +37,7 @@ extension AnyView { .map { view in view.getModified(modifiers: modifiers) } - .getBodyDebugTree(parameters: parameters, type: type)) + .getBodyDebugTree(parameters: parameters, type: type, modifiers: modifiers)) } """ } @@ -87,11 +87,13 @@ extension AnyView { } /// Whether the view can be rendered in a certain environment. - func renderable(type: WidgetType.Type) -> Bool { - self as? WidgetType != nil - || self as? SimpleView != nil - || self as? View != nil - || self as? ConvenienceWidget != nil + func renderable(type: WidgetType.Type, modifiers: [(AnyView) -> AnyView]) -> Bool { + let result = getModified(modifiers: modifiers) + return result as? WidgetType != nil + || result as? SimpleView != nil + || result as? View != nil + || result as? ConvenienceWidget != nil + || result as? Body != nil } } diff --git a/Sources/Model/User Interface/View/Widget.swift b/Sources/Model/User Interface/View/Widget.swift index f63a2d2..fde0f26 100644 --- a/Sources/Model/User Interface/View/Widget.swift +++ b/Sources/Model/User Interface/View/Widget.swift @@ -38,19 +38,23 @@ extension Widget { public var viewContent: Body { [] } /// A description of the view. - public func getViewDescription(parameters: Bool, type: WidgetType.Type) -> String { + public func getViewDescription( + parameters: Bool, + type: WidgetType.Type, + modifiers: [(AnyView) -> AnyView] + ) -> String { var content = "" for element in debugTreeContent { if content.isEmpty { content += """ { - \(indented: element.body.getDebugTree(parameters: parameters, type: type)) + \(indented: element.body.getDebugTree(parameters: parameters, type: type, modifiers: modifiers)) } """ } else { content += """ \(element.0): { - \(indented: element.body.getDebugTree(parameters: parameters, type: type)) + \(indented: element.body.getDebugTree(parameters: parameters, type: type, modifiers: modifiers)) } """ } diff --git a/Tests/DemoApp/DemoApp.swift b/Tests/DemoApp/DemoApp.swift index 0ac0bbf..fbac523 100644 --- a/Tests/DemoApp/DemoApp.swift +++ b/Tests/DemoApp/DemoApp.swift @@ -26,9 +26,13 @@ struct TestView: SimpleView { } let backendType = Backend1.BackendWidget.self +let modifiers: [(AnyView) -> AnyView] = [ + { $0 as? Backend2.TestWidget2 != nil ? [Backend1.TestWidget1()] : $0 } +] -print(DemoView().getDebugTree(parameters: true, type: backendType)) -let storage = DemoView().storage(modifiers: [], type: backendType) -for _ in 0...2 { - DemoView().updateStorage(storage, modifiers: [], updateProperties: true, type: backendType) +print(DemoView().getDebugTree(parameters: true, type: backendType, modifiers: modifiers)) +let storage = DemoView().storage(modifiers: modifiers, type: backendType) +for round in 0...2 { + print("#\(round)") + DemoView().updateStorage(storage, modifiers: modifiers, updateProperties: true, type: backendType) }