Fix pointers not being passed by every widget

This commit is contained in:
david-swift 2024-07-01 21:53:14 +02:00
parent d9bbec862b
commit 9f114a471e
16 changed files with 184 additions and 151 deletions

View File

@ -13,10 +13,15 @@ extension Array: AnyView where Element == AnyView {
public var viewContent: Body { self }
/// Get a widget from a collection of views.
/// - Parameter modifiers: Modify views before being updated.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The app storage type.
/// - Returns: A widget.
public func widget(modifiers: [(AnyView) -> AnyView]) -> Widget {
if count == 1, let widget = self[safe: 0]?.widget(modifiers: modifiers) {
public func widget<Storage>(
modifiers: [(AnyView) -> AnyView],
type: Storage.Type
) -> Widget where Storage: AppStorage {
if count == 1, let widget = self[safe: 0]?.widget(modifiers: modifiers, type: type) {
return widget
} else {
var modified = self
@ -25,7 +30,7 @@ extension Array: AnyView where Element == AnyView {
modified[safe: index] = modifier(view)
}
}
return Wrapper { modified }
return Storage.WrapperType { modified }
}
}
@ -34,17 +39,17 @@ extension Array: AnyView where Element == AnyView {
/// - storage: The collection of view storages.
/// - modifiers: Modify views before being updated.
/// - updateProperties: Whether to update properties.
/// - type: The type of the widgets.
public func update<WidgetType>(
/// - type: The type of the app storage.
public func update<Storage>(
_ storage: [ViewStorage],
modifiers: [(AnyView) -> AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
type: Storage.Type
) where Storage: AppStorage {
for (index, element) in filter({ $0.renderable(type: type, modifiers: modifiers) }).enumerated() {
if let storage = storage[safe: index] {
element
.widget(modifiers: modifiers)
.widget(modifiers: modifiers, type: type)
.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
}
@ -53,12 +58,12 @@ extension Array: AnyView where Element == AnyView {
/// Get the view storages of a collection of views.
/// - Parameters:
/// - modifiers: Modify views before generating the storages.
/// - type: The type of the widgets.
/// - type: The type of the app storage.
/// - Returns: The storages.
public func storages<WidgetType>(
public func storages<Storage>(
modifiers: [(AnyView) -> AnyView],
type: WidgetType.Type
) -> [ViewStorage] {
type: Storage.Type
) -> [ViewStorage] where Storage: AppStorage {
compactMap { view in
view.renderable(type: type, modifiers: modifiers) ? view.storage(modifiers: modifiers, type: type) : nil
}

View File

@ -12,6 +12,8 @@ public protocol AppStorage: AnyObject {
associatedtype SceneElementType
/// The type of widget elements (which should be backend-specific).
associatedtype WidgetType
/// The wrapper widget.
associatedtype WrapperType: Wrapper
/// The scene.
var app: () -> any App { get }

View File

@ -12,8 +12,7 @@ public class SceneStorage {
public var id: String
/// The pointer.
///
/// It can be a C pointer, a Swift class, or other information depending on the backend,
/// or it can be left out.
/// It can be a C pointer, a Swift class, or other information depending on the backend.
public var pointer: Any?
/// The scene element's view content.
public var content: [String: [ViewStorage]]

View File

@ -28,14 +28,14 @@ extension AnyView {
/// - storage: The storage.
/// - modifiers: Modify views before being updated.
/// - updateProperties: Whether to update properties.
/// - type: The type of the widgets.
public func updateStorage<WidgetType>(
/// - type: The type of the app storage.
public func updateStorage<Storage>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
widget(modifiers: modifiers)
type: Storage.Type
) where Storage: AppStorage {
widget(modifiers: modifiers, type: type)
.update(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
@ -44,28 +44,31 @@ extension AnyView {
/// - modifiers: Modify views before being updated.
/// - type: The widget types.
/// - Returns: The storage.
public func storage<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
widget(modifiers: modifiers).container(modifiers: modifiers, type: type)
public func storage<Storage>(
modifiers: [(AnyView) -> AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
widget(modifiers: modifiers, type: type).container(modifiers: modifiers, type: type)
}
/// Wrap the view into a widget.
/// - Parameter modifiers: Modify views before being updated.
/// - Returns: The widget.
func widget(modifiers: [(AnyView) -> AnyView]) -> Widget {
func widget<Storage>(modifiers: [(AnyView) -> AnyView], type: Storage.Type) -> Widget where Storage: AppStorage {
let modified = getModified(modifiers: modifiers)
if let peer = modified as? Widget {
return peer
}
if let array = modified as? Body {
return Wrapper { array }
return Storage.WrapperType { array }
}
return Wrapper { viewContent.map { $0.getModified(modifiers: modifiers) } }
return Storage.WrapperType { viewContent.map { $0.getModified(modifiers: modifiers) } }
}
/// Whether the view can be rendered in a certain environment.
func renderable<WidgetType>(type: WidgetType.Type, modifiers: [(AnyView) -> AnyView]) -> Bool {
func renderable<Storage>(type: Storage.Type, modifiers: [(AnyView) -> AnyView]) -> Bool where Storage: AppStorage {
let result = getModified(modifiers: modifiers)
return result as? WidgetType != nil
return result as? Storage.WidgetType != nil
|| result as? SimpleView != nil
|| result as? View != nil
|| result as? ConvenienceWidget != nil

View File

@ -11,7 +11,6 @@ public class ViewStorage {
/// The pointer.
///
/// It can be a C pointer, a Swift class, or other information depending on the backend.
/// Some convenience widgets do not need a pointer to a native framework at all.
public var pointer: Any?
/// The view's content for container widgets.
public var content: [String: [ViewStorage]]

View File

@ -14,20 +14,23 @@ public protocol Widget: AnyView {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(AnyView) -> AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage
/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
updateProperties: Bool,
type: WidgetType.Type
)
type: Storage.Type
) where Storage: AppStorage
}

View File

@ -0,0 +1,15 @@
//
// Wrapper.swift
// Meta
//
// Created by david-swift on 01.07.24.
//
/// Wrap a body into a single widget.
public protocol Wrapper: Widget {
/// Initialize a `Wrapper`.
/// - Parameter content: The view content.
init(@ViewBuilder content: @escaping () -> Body)
}

View File

@ -16,11 +16,14 @@ struct AppearObserver: ConvenienceWidget {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(any AnyView) -> any AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
let storage = content.storage(modifiers: modifiers, type: type)
modify(storage)
return .init(nil, content: [.mainContent: [storage]])
return storage
}
/// Update the stored content.
@ -28,16 +31,13 @@ struct AppearObserver: ConvenienceWidget {
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard let storage = storage.content[.mainContent]?.first else {
return
}
type: Storage.Type
) where Storage: AppStorage {
content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
}

View File

@ -16,9 +16,12 @@ struct ContentModifier<Content>: ConvenienceWidget where Content: AnyView {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
.init(nil, content: [.mainContent: [content.storage(modifiers: modifiers + [modifyView], type: type)]])
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(any AnyView) -> any AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
content.storage(modifiers: modifiers + [modifyView], type: type)
}
/// Update the stored content.
@ -26,16 +29,13 @@ struct ContentModifier<Content>: ConvenienceWidget where Content: AnyView {
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard let storage = storage.content[.mainContent]?.first else {
return
}
type: Storage.Type
) where Storage: AppStorage {
content
.updateStorage(storage, modifiers: modifiers + [modifyView], updateProperties: updateProperties, type: type)
}

View File

@ -16,9 +16,12 @@ struct Freeze: ConvenienceWidget {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
.init(nil, content: [.mainContent: [content.storage(modifiers: modifiers, type: type)]])
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(any AnyView) -> any AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
content.storage(modifiers: modifiers, type: type)
}
/// Update the stored content.
@ -26,14 +29,14 @@ struct Freeze: ConvenienceWidget {
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard !freeze, let storage = storage.content[.mainContent]?.first else {
type: Storage.Type
) where Storage: AppStorage {
guard !freeze else {
return
}
content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)

View File

@ -16,11 +16,14 @@ struct InspectorWrapper: ConvenienceWidget {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(any AnyView) -> any AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
let storage = content.storage(modifiers: modifiers, type: type)
modify(storage)
return .init(nil, content: [.mainContent: [storage]])
return storage
}
/// Update the stored content.
@ -28,16 +31,13 @@ struct InspectorWrapper: ConvenienceWidget {
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard let storage = storage.content[.mainContent]?.first else {
return
}
type: Storage.Type
) where Storage: AppStorage {
content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
modify(storage)
}

View File

@ -14,9 +14,12 @@ struct ModifierStopper: ConvenienceWidget {
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
func container<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
.init(nil, content: [.mainContent: [content.storage(modifiers: [], type: type)]])
/// - type: The type of the app storage.
func container<Storage>(
modifiers: [(any AnyView) -> any AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
content.storage(modifiers: [], type: type)
}
/// Update the stored content.
@ -24,16 +27,13 @@ struct ModifierStopper: ConvenienceWidget {
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard let storage = storage.content[.mainContent]?.first else {
return
}
type: Storage.Type
) where Storage: AppStorage {
content.updateStorage(storage, modifiers: [], updateProperties: updateProperties, type: type)
}

View File

@ -35,13 +35,13 @@ struct StateWrapper: ConvenienceWidget {
/// - storage: The view storage.
/// - modifiers: Modify views before being updated.
/// - updateProperties: Whether to update properties.
/// - type: The type of the widgets.
func update<WidgetType>(
/// - type: The type of the app storage.
func update<Storage>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
type: Storage.Type
) where Storage: AppStorage {
var updateProperties = updateProperties
for property in state {
if let oldID = storage.state[property.key]?.id {
@ -53,20 +53,23 @@ struct StateWrapper: ConvenienceWidget {
StateManager.updatedState(id: property.value.id)
}
}
guard let storages = storage.content[.mainContent] else {
guard let storage = storage.content[.mainContent]?.first else {
return
}
content().update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content().updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
/// Get a view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
/// - type: The type of the app storage.
/// - Returns: The view storage.
func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
let content = content().storages(modifiers: modifiers, type: type)
let storage = ViewStorage(nil, content: [.mainContent: content])
func container<Storage>(
modifiers: [(AnyView) -> AnyView],
type: Storage.Type
) -> ViewStorage where Storage: AppStorage {
let content = content().storage(modifiers: modifiers, type: type)
let storage = ViewStorage(content.pointer, content: [.mainContent: [content]])
storage.state = state
if #available(macOS 14, *), #available(iOS 17, *), state.contains(where: { $0.value.isObservable }) {
observe(storage: storage)

View File

@ -1,47 +0,0 @@
//
// Wrapper.swift
// Meta
//
// Created by david-swift on 27.05.24.
//
/// Wrap a body into a single widget.
public struct Wrapper: ConvenienceWidget {
/// The content.
var content: Body
/// Initialize a `Wrapper`.
/// - Parameter content: The view content.
public init(@ViewBuilder content: @escaping () -> Body) {
self.content = content()
}
/// Update a view storage.
/// - Parameters:
/// - storage: The view storage.
/// - modifiers: Modify views before being updated.
/// - updateProperties: Whether to update properties.
/// - type: The widget types.
public func update<WidgetType>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
updateProperties: Bool,
type: WidgetType.Type
) {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
/// Get a view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the widgets.
/// - Returns: The view storage.
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
.init(nil, content: [.mainContent: content.storages(modifiers: modifiers, type: type)])
}
}

View File

@ -6,14 +6,14 @@ public enum Backend1 {
public init() { }
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
public func container<Storage>(modifiers: [(AnyView) -> AnyView], type: Storage.Type) -> ViewStorage where Storage: AppStorage {
print("Init test widget 1")
let storage = ViewStorage(nil)
storage.fields["test"] = 0
return storage
}
public func update<WidgetType>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: WidgetType.Type) {
public func update<Storage>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Storage.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<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
public func container<Storage>(modifiers: [(AnyView) -> AnyView], type: Storage.Type) -> ViewStorage where Storage: AppStorage {
print("Init test widget 3")
let storage = ViewStorage(nil)
storage.fields["test"] = 0
return storage
}
public func update<WidgetType>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: WidgetType.Type) {
public func update<Storage>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Storage.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<WidgetType>(modifiers: [(any AnyView) -> any AnyView], type: WidgetType.Type) -> ViewStorage {
public func container<Storage>(modifiers: [(any AnyView) -> any AnyView], type: Storage.Type) -> ViewStorage where Storage: AppStorage {
print("Init button")
let storage = ViewStorage(nil)
Task {
@ -59,7 +59,7 @@ public enum Backend1 {
return storage
}
public func update<WidgetType>(_ storage: ViewStorage, modifiers: [(any AnyView) -> any AnyView], updateProperties: Bool, type: WidgetType.Type) {
public func update<Storage>(_ storage: ViewStorage, modifiers: [(any AnyView) -> any AnyView], updateProperties: Bool, type: Storage.Type) {
if updateProperties {
print("Update button (label = \(label))")
storage.fields["action"] = action
@ -90,7 +90,7 @@ public enum Backend1 {
public func container<Storage>(app: Storage) -> SceneStorage where Storage: AppStorage {
print("Show \(id)")
let viewStorage = content.storage(modifiers: [], type: Storage.WidgetType.self)
let viewStorage = content.storage(modifiers: [], type: Storage.self)
return .init(id: id, pointer: nil, content: [.mainContent : [viewStorage]]) {
print("Make visible")
}
@ -101,7 +101,30 @@ public enum Backend1 {
guard let viewStorage = storage.content[.mainContent]?.first else {
return
}
content.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: Storage.WidgetType.self)
content.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: Storage.self)
}
}
public struct Wrapper: BackendWidget, Meta.Wrapper {
var content: Body
public init(@ViewBuilder content: @escaping () -> Body) {
self.content = content()
}
public func container<Storage>(modifiers: [(any Meta.AnyView) -> any Meta.AnyView], type: Storage.Type) -> Meta.ViewStorage where Storage : Meta.AppStorage {
let storage = ViewStorage(nil)
storage.content = [.mainContent: content.storages(modifiers: modifiers, type: type)]
return storage
}
public func update<Storage>(_ storage: Meta.ViewStorage, modifiers: [(any Meta.AnyView) -> any Meta.AnyView], updateProperties: Bool, type: Storage.Type) where Storage : Meta.AppStorage {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
}
@ -114,6 +137,7 @@ public enum Backend1 {
public typealias SceneElementType = BackendSceneElement
public typealias WidgetType = BackendWidget
public typealias WrapperType = Wrapper
public var app: () -> any App
public var sceneStorage: [SceneStorage] = []

View File

@ -6,14 +6,14 @@ public enum Backend2 {
public init() { }
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
public func container<Storage>(modifiers: [(AnyView) -> AnyView], type: Storage.Type) -> ViewStorage where Storage: AppStorage {
print("Init test widget 2")
let storage = ViewStorage(nil)
storage.fields["test"] = 0
return storage
}
public func update<WidgetType>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: WidgetType.Type) {
public func update<Storage>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Storage.Type) {
print("Update test widget 2 (#\(storage.fields["test"] ?? ""))")
storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1
}
@ -24,20 +24,43 @@ public enum Backend2 {
public init() { }
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
public func container<Storage>(modifiers: [(AnyView) -> AnyView], type: Storage.Type) -> ViewStorage where Storage: AppStorage {
print("Init test widget 4")
let storage = ViewStorage(nil)
storage.fields["test"] = 0
return storage
}
public func update<WidgetType>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: WidgetType.Type) {
public func update<Storage>(_ storage: ViewStorage, modifiers: [(AnyView) -> AnyView], updateProperties: Bool, type: Storage.Type) {
print("Update test widget 4 (#\(storage.fields["test"] ?? ""))")
storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1
}
}
public struct Wrapper: BackendWidget, Meta.Wrapper {
var content: Body
public init(@ViewBuilder content: @escaping () -> Body) {
self.content = content()
}
public func container<Storage>(modifiers: [(any Meta.AnyView) -> any Meta.AnyView], type: Storage.Type) -> Meta.ViewStorage where Storage : Meta.AppStorage {
let storage = ViewStorage(nil)
storage.content = [.mainContent: content.storages(modifiers: modifiers, type: type)]
return storage
}
public func update<Storage>(_ storage: Meta.ViewStorage, modifiers: [(any Meta.AnyView) -> any Meta.AnyView], updateProperties: Bool, type: Storage.Type) where Storage : Meta.AppStorage {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
}
}
public protocol BackendWidget: Widget { }
public protocol BackendSceneElement: SceneElement { }
@ -46,6 +69,7 @@ public enum Backend2 {
public typealias SceneElementType = BackendSceneElement
public typealias WidgetType = BackendWidget
public typealias WrapperType = Wrapper
public var app: () -> any App
public var sceneStorage: [SceneStorage] = []