From 4e205397caa08ffc6c307dedf01ae74d88cb74c9 Mon Sep 17 00:00:00 2001 From: david-swift Date: Thu, 15 Aug 2024 10:44:43 +0200 Subject: [PATCH] Make widget data more flexible --- Sources/Meta.docc/Tutorials/CreateBackend.md | 10 ++--- Sources/Model/Extensions/Array.swift | 24 +++++------ .../Model/User Interface/View/AnyView.swift | 30 ++++++------- .../Model/User Interface/View/Widget.swift | 8 ++-- .../User Interface/View/WidgetData.swift | 43 +++++++++++++++++++ Sources/View/AppearObserver.swift | 12 +++--- Sources/View/ContentModifier.swift | 17 +++++--- Sources/View/DummyEitherView.swift | 12 +++--- Sources/View/Freeze.swift | 12 +++--- Sources/View/InspectorWrapper.swift | 12 +++--- Sources/View/ModifierStopper.swift | 16 +++---- Sources/View/StateWrapper.swift | 12 +++--- Tests/SampleBackends/Backend1.swift | 32 +++++++------- Tests/SampleBackends/Backend2.swift | 16 +++---- 14 files changed, 153 insertions(+), 103 deletions(-) create mode 100644 Sources/Model/User Interface/View/WidgetData.swift diff --git a/Sources/Meta.docc/Tutorials/CreateBackend.md b/Sources/Meta.docc/Tutorials/CreateBackend.md index 894d695..d32a88c 100644 --- a/Sources/Meta.docc/Tutorials/CreateBackend.md +++ b/Sources/Meta.docc/Tutorials/CreateBackend.md @@ -78,10 +78,10 @@ public struct VStack: Wrapper, TermKitWidget { } public func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - let storages = content.storages(modifiers: modifiers, type: type) // Get the storages of child views + let storages = content.storages(data: data, type: type) // Get the storages of child views if storages.count == 1 { return .init(storages[0].pointer, content: [.mainContent: storages]) } @@ -99,14 +99,14 @@ public struct VStack: Wrapper, TermKitWidget { public func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { guard let storages = storage.content[.mainContent] else { return } - content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type) // Update the storages of child views + content.update(storages, data: data, updateProperties: updateProperties, type: type) // Update the storages of child views } } @@ -123,7 +123,7 @@ It indicates that a state variable (see ) of an ancestor view If state doesn't change, it is impossible for the UI to change. However, consider the following exceptions: -- _Always_ update view content (using ``AnyView/updateStorage(_:modifiers:updateProperties:type:)`` or ``Swift/Array/storages(modifiers:type:)``). Child views may contain own state. +- _Always_ update view content (using ``AnyView/updateStorage(_:data:updateProperties:type:)`` or ``Swift/Array/storages(data:type:)``). Child views may contain own state. - _Always_ update closures (such as the action of a button widget). They may contain reference to state which is updated whenever a view update takes place. - _Always_ update bindings. As one can see when looking at ``Binding/init(get:set:)``, they contain two closures which, in most cases, contain a reference to state. diff --git a/Sources/Model/Extensions/Array.swift b/Sources/Model/Extensions/Array.swift index 7033179..3c85146 100644 --- a/Sources/Model/Extensions/Array.swift +++ b/Sources/Model/Extensions/Array.swift @@ -14,19 +14,19 @@ extension Array: AnyView where Element == AnyView { /// Get a widget from a collection of views. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The app storage type. /// - Returns: A widget. public func widget( - modifiers: [(AnyView) -> AnyView], + data: WidgetData, type: Data.Type ) -> Widget where Data: ViewRenderData { - if count == 1, let widget = self[safe: 0]?.widget(modifiers: modifiers, type: type) { + if count == 1, let widget = self[safe: 0]?.widget(data: data, type: type) { return widget } else { var modified = self for (index, view) in modified.enumerated() { - modified[safe: index] = view.getModified(modifiers: modifiers, type: type) + modified[safe: index] = view.getModified(data: data, type: type) } return Data.WrapperType { modified } } @@ -35,35 +35,35 @@ extension Array: AnyView where Element == AnyView { /// Update a collection of views with a collection of view storages. /// - Parameters: /// - storages: The collection of view storages. - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - updateProperties: Whether to update properties. /// - type: The type of the app storage. public func update( _ storages: [ViewStorage], - modifiers: [(AnyView) -> AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { - for (index, element) in filter({ $0.renderable(type: type, modifiers: modifiers) }).enumerated() { + for (index, element) in filter({ $0.renderable(type: type, data: data) }).enumerated() { if let storage = storages[safe: index] { element - .widget(modifiers: modifiers, type: type) - .updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + .widget(data: data, type: type) + .updateStorage(storage, data: data, updateProperties: updateProperties, type: type) } } } /// Get the view storages of a collection of views. /// - Parameters: - /// - modifiers: Modify views before generating the storages. + /// - data: Modify views before generating the storages. /// - type: The type of the app storage. /// - Returns: The storages. public func storages( - modifiers: [(AnyView) -> AnyView], + data: WidgetData, type: Data.Type ) -> [ViewStorage] where Data: ViewRenderData { compactMap { view in - view.renderable(type: type, modifiers: modifiers) ? view.storage(modifiers: modifiers, type: type) : nil + view.renderable(type: type, data: data) ? view.storage(data: data, type: type) : nil } } diff --git a/Sources/Model/User Interface/View/AnyView.swift b/Sources/Model/User Interface/View/AnyView.swift index 379f5e8..b22aa6a 100644 --- a/Sources/Model/User Interface/View/AnyView.swift +++ b/Sources/Model/User Interface/View/AnyView.swift @@ -15,9 +15,9 @@ public protocol AnyView { extension AnyView { - func getModified(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> AnyView where Data: ViewRenderData { + func getModified(data: WidgetData, type: Data.Type) -> AnyView where Data: ViewRenderData { var modified: AnyView = self - for modifier in modifiers { + for modifier in data.modifiers { modified = modifier(modified) } return modified @@ -26,48 +26,48 @@ extension AnyView { /// Update a storage to a view. /// - Parameters: /// - storage: The storage. - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - updateProperties: Whether to update properties. /// - type: The type of the app storage. public func updateStorage( _ storage: ViewStorage, - modifiers: [(AnyView) -> AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { - widget(modifiers: modifiers, type: type) - .update(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + widget(data: data, type: type) + .update(storage, data: data, updateProperties: updateProperties, type: type) } /// Get a storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The widget types. /// - Returns: The storage. public func storage( - modifiers: [(AnyView) -> AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - widget(modifiers: modifiers, type: type).container(modifiers: modifiers, type: type) + widget(data: data, type: type).container(data: data, type: type) } /// Wrap the view into a widget. - /// - Parameter modifiers: Modify views before being updated. + /// - Parameter data: Modify views before being updated. /// - Returns: The widget. - func widget(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> Widget where Data: ViewRenderData { - let modified = getModified(modifiers: modifiers, type: type) + func widget(data: WidgetData, type: Data.Type) -> Widget where Data: ViewRenderData { + let modified = getModified(data: data, type: type) if let peer = modified as? Widget { return peer } if let array = modified as? Body { return Data.WrapperType { array } } - return Data.WrapperType { viewContent.map { $0.getModified(modifiers: modifiers, type: type) } } + return Data.WrapperType { viewContent.map { $0.getModified(data: data, type: type) } } } /// Whether the view can be rendered in a certain environment. - func renderable(type: Data.Type, modifiers: [(AnyView) -> AnyView]) -> Bool where Data: ViewRenderData { - let result = getModified(modifiers: modifiers, type: type) + func renderable(type: Data.Type, data: WidgetData) -> Bool where Data: ViewRenderData { + let result = getModified(data: data, type: type) return result as? Data.WidgetType != nil || result as? SimpleView != nil || result as? View != nil diff --git a/Sources/Model/User Interface/View/Widget.swift b/Sources/Model/User Interface/View/Widget.swift index d4b3de4..d854373 100644 --- a/Sources/Model/User Interface/View/Widget.swift +++ b/Sources/Model/User Interface/View/Widget.swift @@ -13,23 +13,23 @@ public protocol Widget: AnyView { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(AnyView) -> AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(AnyView) -> AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData diff --git a/Sources/Model/User Interface/View/WidgetData.swift b/Sources/Model/User Interface/View/WidgetData.swift new file mode 100644 index 0000000..6c1e1aa --- /dev/null +++ b/Sources/Model/User Interface/View/WidgetData.swift @@ -0,0 +1,43 @@ +// +// WidgetData.swift +// Meta +// +// Created by david-swift on 15.08.24. +// + +/// Data passed to widgets when initializing or updating the container. +public struct WidgetData { + + /// The view modifiers. + public var modifiers: [(AnyView) -> AnyView] = [] + /// The scene storage of the parent scene element. + public var sceneStorage: SceneStorage + /// The app storage of the parent app. + public var appStorage: any AppStorage + /// Fields for custom data. + public var fields: [String: Any] = [:] + + /// Modify the data so that there are no modifiers. + public var noModifiers: Self { + modify { $0.modifiers = [] } + } + + /// Initialize widget data. + /// - Parameters: + /// - sceneStorage: The storage of the parent scene element. + /// - appStorage: The storage of the parent app. + public init(sceneStorage: SceneStorage, appStorage: any AppStorage) { + self.sceneStorage = sceneStorage + self.appStorage = appStorage + } + + /// Modify the widget data. + /// - Parameter action: The modification action. + /// - Returns: The data. + public func modify(action: (inout Self) -> Void) -> Self { + var newSelf = self + action(&newSelf) + return newSelf + } + +} diff --git a/Sources/View/AppearObserver.swift b/Sources/View/AppearObserver.swift index c575007..2df1ad5 100644 --- a/Sources/View/AppearObserver.swift +++ b/Sources/View/AppearObserver.swift @@ -15,14 +15,14 @@ struct AppearObserver: ConvenienceWidget { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - let storage = content.storage(modifiers: modifiers, type: type) + let storage = content.storage(data: data, type: type) modify(storage) return storage } @@ -30,16 +30,16 @@ struct AppearObserver: ConvenienceWidget { /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { - content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type) } } diff --git a/Sources/View/ContentModifier.swift b/Sources/View/ContentModifier.swift index 1f9a7e5..e8db113 100644 --- a/Sources/View/ContentModifier.swift +++ b/Sources/View/ContentModifier.swift @@ -15,30 +15,35 @@ struct ContentModifier: ConvenienceWidget where Content: AnyView { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - content.storage(modifiers: modifiers + [modifyView], type: type) + content.storage(data: data.modify { $0.modifiers += [modifyView] }, type: type) } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { content - .updateStorage(storage, modifiers: modifiers + [modifyView], updateProperties: updateProperties, type: type) + .updateStorage( + storage, + data: data.modify { $0.modifiers += [modifyView] }, + updateProperties: updateProperties, + type: type + ) } /// Apply the modifier to a view. diff --git a/Sources/View/DummyEitherView.swift b/Sources/View/DummyEitherView.swift index d15919b..067377a 100644 --- a/Sources/View/DummyEitherView.swift +++ b/Sources/View/DummyEitherView.swift @@ -17,32 +17,32 @@ struct DummyEitherView: Widget { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { let content = type.EitherViewType(condition) { view1 ?? [] } else: { view2 ?? [] } - let storage = content.storage(modifiers: modifiers, type: type) + let storage = content.storage(data: data, type: type) return storage } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { let content = type.EitherViewType(condition) { view1 ?? [] } else: { view2 ?? [] } - content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type) } } diff --git a/Sources/View/Freeze.swift b/Sources/View/Freeze.swift index 3127db9..1e5fc24 100644 --- a/Sources/View/Freeze.swift +++ b/Sources/View/Freeze.swift @@ -15,32 +15,32 @@ struct Freeze: ConvenienceWidget { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - content.storage(modifiers: modifiers, type: type) + content.storage(data: data, type: type) } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { guard !freeze else { return } - content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type) } } diff --git a/Sources/View/InspectorWrapper.swift b/Sources/View/InspectorWrapper.swift index 2942baf..4e61da6 100644 --- a/Sources/View/InspectorWrapper.swift +++ b/Sources/View/InspectorWrapper.swift @@ -15,14 +15,14 @@ struct InspectorWrapper: ConvenienceWidget { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - let storage = content.storage(modifiers: modifiers, type: type) + let storage = content.storage(data: data, type: type) modify(storage, true) return storage } @@ -30,16 +30,16 @@ struct InspectorWrapper: ConvenienceWidget { /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { - content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type) modify(storage, updateProperties) } diff --git a/Sources/View/ModifierStopper.swift b/Sources/View/ModifierStopper.swift index 3281f9e..d4167df 100644 --- a/Sources/View/ModifierStopper.swift +++ b/Sources/View/ModifierStopper.swift @@ -5,7 +5,7 @@ // Created by david-swift on 29.06.24. // -/// Remove all of the content modifiers for the wrapped views. +/// Remove all of the content data for the wrapped views. struct ModifierStopper: ConvenienceWidget { /// The wrapped view. @@ -13,36 +13,36 @@ struct ModifierStopper: ConvenienceWidget { /// The view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - content.storage(modifiers: [], type: type) + content.storage(data: data.noModifiers, type: type) } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. - /// - modifiers: Modify views before being updated + /// - data: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The type of the app storage. func update( _ storage: ViewStorage, - modifiers: [(any AnyView) -> any AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { - content.updateStorage(storage, modifiers: [], updateProperties: updateProperties, type: type) + content.updateStorage(storage, data: data.noModifiers, updateProperties: updateProperties, type: type) } } extension AnyView { - /// Remove all of the content modifiers for the wrapped views. + /// Remove all of the content data for the wrapped views. /// - Returns: A view. public func stopModifiers() -> AnyView { ModifierStopper(content: self) diff --git a/Sources/View/StateWrapper.swift b/Sources/View/StateWrapper.swift index 5365965..5853dcf 100644 --- a/Sources/View/StateWrapper.swift +++ b/Sources/View/StateWrapper.swift @@ -31,13 +31,13 @@ struct StateWrapper: ConvenienceWidget { /// Update a view storage. /// - Parameters: /// - storage: The view storage. - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - updateProperties: Whether to update properties. /// - type: The type of the app storage. /// - Returns: The view storage. func update( _ storage: ViewStorage, - modifiers: [(AnyView) -> AnyView], + data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { @@ -54,19 +54,19 @@ struct StateWrapper: ConvenienceWidget { guard let storage = storage.content[.mainContent]?.first else { return } - content().updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type) + content().updateStorage(storage, data: data, updateProperties: updateProperties, type: type) } /// Get a view storage. /// - Parameters: - /// - modifiers: Modify views before being updated. + /// - data: Modify views before being updated. /// - type: The type of the app storage. /// - Returns: The view storage. func container( - modifiers: [(AnyView) -> AnyView], + data: WidgetData, type: Data.Type ) -> ViewStorage where Data: ViewRenderData { - let content = content().storage(modifiers: modifiers, type: type) + let content = content().storage(data: data, type: type) let storage = ViewStorage(content.pointer, content: [.mainContent: [content]]) storage.state = state return storage diff --git a/Tests/SampleBackends/Backend1.swift b/Tests/SampleBackends/Backend1.swift index f66cfe2..26511a9 100644 --- a/Tests/SampleBackends/Backend1.swift +++ b/Tests/SampleBackends/Backend1.swift @@ -6,14 +6,14 @@ public enum Backend1 { public init() { } - public func container(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { print("Init test widget 1") let storage = ViewStorage(nil) storage.fields["test"] = 0 return storage } - public func update(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Data.Type) { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) { print("Update test widget 1 (#\(storage.fields["test"] ?? ""))") storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1 } @@ -24,14 +24,14 @@ public enum Backend1 { public init() { } - public func container(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { print("Init test widget 3") let storage = ViewStorage(nil) storage.fields["test"] = 0 return storage } - public func update(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Data.Type) { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) { print("Update test widget 3 (#\(storage.fields["test"] ?? ""))") storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1 } @@ -48,7 +48,7 @@ public enum Backend1 { self.action = action } - public func container(modifiers: [(any AnyView) -> any AnyView], type: Data.Type) -> ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { print("Init button") let storage = ViewStorage(nil) Task { @@ -59,7 +59,7 @@ public enum Backend1 { return storage } - public func update(_ storage: ViewStorage, modifiers: [(any AnyView) -> any AnyView], updateProperties: Bool, type: Data.Type) { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) { storage.fields["action"] = action if updateProperties { if (storage.previousState as? Self)?.label != label { @@ -92,10 +92,12 @@ public enum Backend1 { public func container(app: Storage) -> SceneStorage where Storage: AppStorage { print("Show \(id)") - let viewStorage = content.storage(modifiers: [], type: MainViewRenderData.self) - return .init(id: id, pointer: nil, content: [.mainContent : [viewStorage]]) { + let storage = SceneStorage(id: id, pointer: nil) { print("Make visible") } + let viewStorage = content.storage(data: .init(sceneStorage: storage, appStorage: app), type: MainViewRenderData.self) + storage.content[.mainContent] = [viewStorage] + return storage } public func update(_ storage: SceneStorage, app: Storage, updateProperties: Bool) where Storage: AppStorage { @@ -103,7 +105,7 @@ public enum Backend1 { guard let viewStorage = storage.content[.mainContent]?.first else { return } - content.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: MainViewRenderData.self) + content.updateStorage(viewStorage, data: .init(sceneStorage: storage, appStorage: app), updateProperties: updateProperties, type: MainViewRenderData.self) } } @@ -116,17 +118,17 @@ public enum Backend1 { self.content = content() } - public func container(modifiers: [(any Meta.AnyView) -> any Meta.AnyView], type: Data.Type) -> Meta.ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> Meta.ViewStorage where Data: ViewRenderData { let storage = ViewStorage(nil) - storage.content = [.mainContent: content.storages(modifiers: modifiers, type: type)] + storage.content = [.mainContent: content.storages(data: data, type: type)] return storage } - public func update(_ storage: Meta.ViewStorage, modifiers: [(any Meta.AnyView) -> any Meta.AnyView], updateProperties: Bool, type: Data.Type) where Data: ViewRenderData { + public func update(_ storage: Meta.ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData { guard let storages = storage.content[.mainContent] else { return } - content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.update(storages, data: data, updateProperties: updateProperties, type: type) } } @@ -136,11 +138,11 @@ public enum Backend1 { public init(_ condition: Bool, view1: () -> Body, else view2: () -> Body) { } - public func container(modifiers: [(any AnyView) -> any AnyView], type: Data.Type) -> ViewStorage where Data : ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data : ViewRenderData { .init(nil) } - public func update(_ storage: ViewStorage, modifiers: [(any AnyView) -> any AnyView], updateProperties: Bool, type: Data.Type) where Data : ViewRenderData { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data : ViewRenderData { } } diff --git a/Tests/SampleBackends/Backend2.swift b/Tests/SampleBackends/Backend2.swift index dd7d05e..b5b276d 100644 --- a/Tests/SampleBackends/Backend2.swift +++ b/Tests/SampleBackends/Backend2.swift @@ -6,14 +6,14 @@ public enum Backend2 { public init() { } - public func container(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { print("Init test widget 2") let storage = ViewStorage(nil) storage.fields["test"] = 0 return storage } - public func update(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Data.Type) { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) { print("Update test widget 2 (#\(storage.fields["test"] ?? ""))") storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1 } @@ -24,14 +24,14 @@ public enum Backend2 { public init() { } - public func container(modifiers: [(AnyView) -> AnyView], type: Data.Type) -> ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { print("Init test widget 4") let storage = ViewStorage(nil) storage.fields["test"] = 0 return storage } - public func update(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Data.Type) { + public func update(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) { print("Update test widget 4 (#\(storage.fields["test"] ?? ""))") storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1 } @@ -46,17 +46,17 @@ public enum Backend2 { self.content = content() } - public func container(modifiers: [(any Meta.AnyView) -> any Meta.AnyView], type: Data.Type) -> Meta.ViewStorage where Data: ViewRenderData { + public func container(data: WidgetData, type: Data.Type) -> Meta.ViewStorage where Data: ViewRenderData { let storage = ViewStorage(nil) - storage.content = [.mainContent: content.storages(modifiers: modifiers, type: type)] + storage.content = [.mainContent: content.storages(data: data, type: type)] return storage } - public func update(_ storage: Meta.ViewStorage, modifiers: [(any Meta.AnyView) -> any Meta.AnyView], updateProperties: Bool, type: Data.Type) where Data: ViewRenderData { + public func update(_ storage: Meta.ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData { guard let storages = storage.content[.mainContent] else { return } - content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type) + content.update(storages, data: data, updateProperties: updateProperties, type: type) } }