diff --git a/Sources/OpenSwiftUICore/View/VariadicView_Children.swift b/Sources/OpenSwiftUICore/View/Input/ViewListView.swift similarity index 74% rename from Sources/OpenSwiftUICore/View/VariadicView_Children.swift rename to Sources/OpenSwiftUICore/View/Input/ViewListView.swift index e04cb5df9..990edd9a5 100644 --- a/Sources/OpenSwiftUICore/View/VariadicView_Children.swift +++ b/Sources/OpenSwiftUICore/View/Input/ViewListView.swift @@ -1,5 +1,5 @@ // -// VariadicView_Children.swift +// ViewListView.swift // OpenSwiftUICore // // Audited for 6.0.87 @@ -9,77 +9,6 @@ package import OpenAttributeGraphShims -// MARK: - _VariadicView.Children + View [WIP] - -@available(OpenSwiftUI_v1_0, *) -extension _VariadicView.Children: View, MultiView, PrimitiveView { - nonisolated public static func _makeViewList( - view: _GraphValue, - inputs: _ViewListInputs - ) -> _ViewListOutputs { - let child = _GraphValue(Child(children: view.value)) - return ForEach._makeViewList(view: child, inputs: inputs) - } - - @available(OpenSwiftUI_v2_0, *) - nonisolated public static func _viewListCount( - inputs: _ViewListCountInputs - ) -> Int? { - nil - } - - private struct Child: Rule, AsyncAttribute { - typealias Value = ForEach<_VariadicView.Children, AnyHashable, _VariadicView.Children.Element> - - @Attribute var children: _VariadicView.Children - - var value: Value { - _openSwiftUIUnimplementedFailure() - } - } -} - -// MARK: - _VariadicView.Children + RandomAccessCollection [WIP] - -@available(OpenSwiftUI_v1_0, *) -extension _VariadicView.Children: RandomAccessCollection { - public struct Element: PrimitiveView, UnaryView, Identifiable { - var view: ViewList.View - var traits: ViewTraitCollection - - public var id: AnyHashable { - _openSwiftUIUnimplementedFailure() - - } - public func id(as _: ID.Type = ID.self) -> ID? where ID : Hashable { - _openSwiftUIUnimplementedFailure() - } - - /// The value of each trait associated with the view. Changing - /// the traits will not affect the view in any way. - public subscript(key: Trait.Type) -> Trait.Value { - get { traits[key] } - set { traits[key] = newValue } - } - - public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { - _openSwiftUIUnimplementedFailure() - } - } - - public var startIndex: Int { - _openSwiftUIUnimplementedFailure() - } - - public var endIndex: Int { - _openSwiftUIUnimplementedFailure() - } - - public subscript(index: Int) -> Element { - _openSwiftUIUnimplementedFailure() - } -} - // MARK: - ViewListVisitor package protocol ViewListVisitor { @@ -142,6 +71,16 @@ package struct _ViewList_View: PrimitiveView, View, UnaryView { var count: Int var contentSubgraph: Subgraph? + @inline(__always) + init(emptyViewID implicitID: Int) { + self.elements = EmptyViewListElements() + self.releaseElements = nil + self.id = .init(implicitID: implicitID) + self.index = .zero + self.count = .zero + self.contentSubgraph = nil + } + package init( elements: any ViewList.Elements, id: ViewList.ID, @@ -150,6 +89,7 @@ package struct _ViewList_View: PrimitiveView, View, UnaryView { contentSubgraph: Subgraph ) { self.elements = elements + releaseElements = elements.retain() self.id = id self.index = index self.count = count diff --git a/Sources/OpenSwiftUICore/View/VariadicView.swift b/Sources/OpenSwiftUICore/View/VariadicView/VariadicView.swift similarity index 100% rename from Sources/OpenSwiftUICore/View/VariadicView.swift rename to Sources/OpenSwiftUICore/View/VariadicView/VariadicView.swift diff --git a/Sources/OpenSwiftUICore/View/VariadicView/VariadicViewChildren.swift b/Sources/OpenSwiftUICore/View/VariadicView/VariadicViewChildren.swift new file mode 100644 index 000000000..d681fd328 --- /dev/null +++ b/Sources/OpenSwiftUICore/View/VariadicView/VariadicViewChildren.swift @@ -0,0 +1,112 @@ +// +// VariadicViewChildren.swift +// OpenSwiftUICore +// +// Audited for 6.5.4 +// Status: Complete + +import OpenAttributeGraphShims + +// MARK: - _VariadicView.Children + View + +@available(OpenSwiftUI_v1_0, *) +extension _VariadicView.Children: View, MultiView, PrimitiveView { + nonisolated public static func _makeViewList( + view: _GraphValue, + inputs: _ViewListInputs + ) -> _ViewListOutputs { + let child = _GraphValue(Child(children: view.value)) + return ForEach._makeViewList(view: child, inputs: inputs) + } + + @available(OpenSwiftUI_v2_0, *) + nonisolated public static func _viewListCount( + inputs: _ViewListCountInputs + ) -> Int? { + nil + } + + private struct Child: Rule, AsyncAttribute { + typealias Value = ForEach<_VariadicView.Children, AnyHashable, _VariadicView.Children.Element> + + @Attribute var children: _VariadicView.Children + + var value: Value { + ForEach(children) { $0 } + } + } +} + +// MARK: - _VariadicView.Children + RandomAccessCollection + +@available(OpenSwiftUI_v1_0, *) +extension _VariadicView.Children: RandomAccessCollection { + + public struct Element: PrimitiveView, UnaryView, Identifiable { + var view: ViewList.View + var traits: ViewTraitCollection + + public var id: AnyHashable { + view.viewID + } + + public func id(as _: ID.Type = ID.self) -> ID? where ID: Hashable { + view.id.primaryExplicitID.flatMap{ $0.as(type: ID.self) } + } + + /// The value of each trait associated with the view. Changing + /// the traits will not affect the view in any way. + public subscript(key: Trait.Type) -> Trait.Value { + get { traits[key] } + set { traits[key] = newValue } + } + + public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + ViewList.View._makeView( + view: view[\.view], + inputs: inputs + ) + } + } + + public var startIndex: Int { .zero } + + public var endIndex: Int { Update.ensure { list.count } } + + public subscript(index: Int) -> Element { + var element: Element? + Update.ensure { + var start = index + var transform = transform + list.applySublists( + from: &start, + list: nil, + transform: &transform + ) { sublist in + let index = sublist.start + let count = sublist.count + if index < count { + element = Element( + view: .init( + elements: sublist.elements, + id: sublist.id, + index: index, + count: count, + contentSubgraph: contentSubgraph + ), + traits: sublist.traits + ) + } + return index >= count + } + } + guard let element else { + Log.internalError("Accessing invalid variadic view child at index %d", index) + return Element( + view: .init(emptyViewID: index), + traits: .init() + ) + } + return element + } +}