Fix views with multiple backends not updating
This commit is contained in:
parent
133a4b02da
commit
c114bd32e9
@ -18,13 +18,7 @@ extension Array: AnyView where Element == AnyView {
|
||||
public func getBodyDebugTree<WidgetType>(parameters: Bool, type: WidgetType.Type) -> String {
|
||||
var description = ""
|
||||
for view in self where view.renderable(type: type) {
|
||||
let viewDescription: String
|
||||
if let widget = view as? Widget {
|
||||
viewDescription = widget.getViewDescription(parameters: parameters, type: type)
|
||||
} else {
|
||||
viewDescription = view.getDebugTree(parameters: parameters, type: type)
|
||||
}
|
||||
description += viewDescription + "\n"
|
||||
description += view.getDebugTree(parameters: parameters, type: type) + "\n"
|
||||
}
|
||||
if !description.isEmpty {
|
||||
description.removeLast()
|
||||
@ -61,7 +55,7 @@ extension Array: AnyView where Element == AnyView {
|
||||
updateProperties: Bool,
|
||||
type: WidgetType.Type
|
||||
) {
|
||||
for (index, element) in enumerated() where element.renderable(type: type) {
|
||||
for (index, element) in filter({ $0.renderable(type: type) }).enumerated() {
|
||||
if let storage = storage[safe: index] {
|
||||
element
|
||||
.widget(modifiers: modifiers)
|
||||
@ -70,26 +64,15 @@ extension Array: AnyView where Element == AnyView {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Array where Element == String {
|
||||
|
||||
/// Get the C version of the array.
|
||||
var cArray: UnsafePointer<UnsafePointer<CChar>?>? {
|
||||
let cStrings = self.map { $0.utf8CString }
|
||||
let cStringPointers = cStrings.map { $0.withUnsafeBufferPointer { $0.baseAddress } }
|
||||
let optionalCStringPointers = cStringPointers + [nil]
|
||||
var optionalCStringPointersCopy = optionalCStringPointers
|
||||
optionalCStringPointersCopy.withUnsafeMutableBufferPointer { bufferPointer in
|
||||
bufferPointer.baseAddress?.advanced(by: cStrings.count).pointee = nil
|
||||
}
|
||||
let flatArray = optionalCStringPointersCopy.compactMap { $0 }
|
||||
let pointer = UnsafeMutablePointer<UnsafePointer<CChar>?>.allocate(capacity: flatArray.count + 1)
|
||||
for (index, element) in flatArray.enumerated() {
|
||||
pointer.advanced(by: index).pointee = element
|
||||
}
|
||||
pointer.advanced(by: flatArray.count).pointee = nil
|
||||
return UnsafePointer(pointer)
|
||||
/// Get the view storages of a collection of views.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before generating the storages.
|
||||
/// - type: The type of the widgets.
|
||||
public func storages<WidgetType>(
|
||||
modifiers: [(AnyView) -> AnyView],
|
||||
type: WidgetType.Type
|
||||
) -> [ViewStorage] {
|
||||
compactMap { $0.renderable(type: type) ? $0.storage(modifiers: [], type: type) : nil }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,15 +16,28 @@ public protocol AnyView {
|
||||
extension AnyView {
|
||||
|
||||
/// Get the view's debug tree.
|
||||
/// - Parameter parameters: Whether the widget parameters should be included in the debug tree.
|
||||
/// - Parameters:
|
||||
/// - parameters: Whether the widget parameters should be included in the debug tree.
|
||||
/// - type: The widget type.
|
||||
/// - modifiers: Modify the view before getting the debug tree.
|
||||
/// - Returns: A textual description.
|
||||
public func getDebugTree<WidgetType>(parameters: Bool, type: WidgetType.Type) -> String {
|
||||
if let body = self as? Body {
|
||||
public func getDebugTree<WidgetType>(
|
||||
parameters: Bool,
|
||||
type: WidgetType.Type,
|
||||
modifiers: [(AnyView) -> AnyView] = []
|
||||
) -> String {
|
||||
if let body = getModified(modifiers: modifiers) as? Body {
|
||||
return body.getBodyDebugTree(parameters: parameters, type: type)
|
||||
} else if let widget = getModified(modifiers: modifiers) as? Widget {
|
||||
return widget.getViewDescription(parameters: parameters, type: type)
|
||||
}
|
||||
return """
|
||||
\(Self.self) {
|
||||
\(indented: viewContent.getBodyDebugTree(parameters: parameters, type: type))
|
||||
\(indented: viewContent
|
||||
.map { view in
|
||||
view.getModified(modifiers: modifiers)
|
||||
}
|
||||
.getBodyDebugTree(parameters: parameters, type: type))
|
||||
}
|
||||
"""
|
||||
}
|
||||
@ -49,13 +62,8 @@ extension AnyView {
|
||||
updateProperties: Bool,
|
||||
type: WidgetType.Type
|
||||
) {
|
||||
let modified = getModified(modifiers: modifiers)
|
||||
if let widget = modified as? Widget {
|
||||
widget.update(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
} else {
|
||||
Wrapper { viewContent }
|
||||
.update(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
widget(modifiers: modifiers)
|
||||
.update(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
/// Get a storage.
|
||||
@ -75,7 +83,7 @@ extension AnyView {
|
||||
if let peer = modified as? Widget {
|
||||
return peer
|
||||
}
|
||||
return Wrapper { viewContent }
|
||||
return Wrapper { viewContent.map { $0.getModified(modifiers: modifiers) } }
|
||||
}
|
||||
|
||||
/// Whether the view can be rendered in a certain environment.
|
||||
|
||||
@ -51,7 +51,7 @@ public struct Wrapper: ConvenienceWidget {
|
||||
/// - type: The type of the widgets.
|
||||
/// - Returns: The view storage.
|
||||
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
|
||||
ViewStorage(nil, content: [.mainContent: content.map { $0.storage(modifiers: [], type: type) }])
|
||||
.init(nil, content: [.mainContent: content.storages(modifiers: modifiers, type: type)])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ struct DemoView: SimpleView {
|
||||
@ViewBuilder
|
||||
var testContent: Body {
|
||||
Backend2.TestWidget2()
|
||||
Backend1.TestWidget1()
|
||||
Backend1.TestWidget3()
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,10 +25,10 @@ struct TestView: SimpleView {
|
||||
|
||||
}
|
||||
|
||||
print(DemoView().getDebugTree(parameters: true, type: Backend1.BackendWidget.self))
|
||||
print(DemoView().getDebugTree(parameters: true, type: Backend2.BackendWidget.self))
|
||||
let backendType = Backend1.BackendWidget.self
|
||||
|
||||
let storage = DemoView().storage(modifiers: [], type: Backend1.BackendWidget.self)
|
||||
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: Backend2.BackendWidget.self)
|
||||
DemoView().updateStorage(storage, modifiers: [], updateProperties: true, type: backendType)
|
||||
}
|
||||
|
||||
@ -28,6 +28,32 @@ public enum Backend1 {
|
||||
|
||||
}
|
||||
|
||||
public struct TestWidget3: BackendWidget {
|
||||
|
||||
public init() { }
|
||||
|
||||
public var debugTreeContent: [(String, body: Body)] {
|
||||
[]
|
||||
}
|
||||
|
||||
public var debugTreeParameters: [(String, value: CustomStringConvertible)] {
|
||||
[]
|
||||
}
|
||||
|
||||
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
|
||||
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) {
|
||||
print("Update test widget 3 (#\(storage.fields["test"] ?? ""))")
|
||||
storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public protocol BackendWidget: Widget { }
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,32 @@ public enum Backend2 {
|
||||
|
||||
}
|
||||
|
||||
public struct TestWidget4: BackendWidget {
|
||||
|
||||
public init() { }
|
||||
|
||||
public var debugTreeContent: [(String, body: Body)] {
|
||||
[]
|
||||
}
|
||||
|
||||
public var debugTreeParameters: [(String, value: CustomStringConvertible)] {
|
||||
[]
|
||||
}
|
||||
|
||||
public func container<WidgetType>(modifiers: [(AnyView) -> AnyView], type: WidgetType.Type) -> ViewStorage {
|
||||
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) {
|
||||
print("Update test widget 4 (#\(storage.fields["test"] ?? ""))")
|
||||
storage.fields["test"] = (storage.fields["test"] as? Int ?? 0) + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public protocol BackendWidget: Widget { }
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user