Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Signpost Logging #174

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions BlueprintUI/Sources/Blueprint View/BlueprintView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,21 @@ public final class BlueprintView: UIView {

needsViewHierarchyUpdate = false
lastViewHierarchyUpdateBounds = bounds

let loggingInfo = SignpostLogger.Info(
type: BlueprintView.self,
components: ["\(self.bounds.width) x \(self.bounds.height)"]
)

/// Grab view descriptions
let viewNodes = element?
.layout(layoutAttributes: LayoutAttributes(frame: bounds), environment: makeEnvironment())
.resolve() ?? []
let viewNodes : [LayoutResultNode.ResolvedNodes] = SignpostLogger.log(
name: "BlueprintView: Layout & Resolve Element",
info: loggingInfo
) {
element?
.layout(layoutAttributes: LayoutAttributes(frame: bounds), environment: makeEnvironment())
.resolve() ?? []
}

rootController.view.frame = bounds

Expand All @@ -207,7 +217,13 @@ public final class BlueprintView: UIView {
let scale = window?.screen.scale ?? UIScreen.main.scale
rootNode.round(from: .zero, correction: .zero, scale: scale)

rootController.update(node: rootNode, appearanceTransitionsEnabled: hasUpdatedViewHierarchy)
SignpostLogger.log(
name: "BlueprintView: Update View Hierarchy",
info: loggingInfo
) {
rootController.update(node: rootNode, appearanceTransitionsEnabled: hasUpdatedViewHierarchy)
}

hasUpdatedViewHierarchy = true

isInsideUpdate = false
Expand Down Expand Up @@ -243,6 +259,7 @@ public final class BlueprintView: UIView {
}
}


extension BlueprintView {

final class NativeViewController {
Expand Down
150 changes: 96 additions & 54 deletions BlueprintUI/Sources/Element/ElementContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import UIKit
/// Represents the content of an element.
public struct ElementContent {

private let storage: ContentStorage
fileprivate let storage: ContentStorage

/// The key to use to cache measurement values.
private let measurementCachingKey : MeasurementCachingKey?
Expand Down Expand Up @@ -47,7 +47,7 @@ public struct ElementContent {
}

func performLayout(attributes: LayoutAttributes, environment: Environment) -> [(identifier: ElementIdentifier, node: LayoutResultNode)] {
return storage.performLayout(attributes: attributes, environment: environment)
storage.performLayout(attributes: attributes, environment: environment)
}
}

Expand Down Expand Up @@ -243,8 +243,13 @@ extension ElementContent {
}

func measure(in constraint: SizeConstraint, environment: Environment) -> CGSize {
let layoutItems = self.layoutItems(in: environment)
return layout.measure(in: constraint, items: layoutItems)
let items = self.layoutItems(in: environment)
SignpostLogger.log(
name: "Layout Element",
info: layout.loggingInfo(with: <#T##Measurable#>)
) {
layout.measure(in: constraint, items: items)
}
}

func performLayout(
Expand All @@ -257,38 +262,43 @@ extension ElementContent {
return []
}

let layoutItems = self.layoutItems(in: environment)
let childAttributes = layout.layout(size: attributes.bounds.size, items: layoutItems)

var result: [(identifier: ElementIdentifier, node: LayoutResultNode)] = []
result.reserveCapacity(children.count)

var identifierFactory = ElementIdentifier.Factory(elementCount: children.count)

for index in 0..<children.count {
let currentChildLayoutAttributes = childAttributes[index]
let currentChild = children[index]

let resultNode = LayoutResultNode(
element: currentChild.element,
layoutAttributes: currentChildLayoutAttributes,
content: currentChild.content,
environment: environment
)

let identifier = identifierFactory.nextIdentifier(
for: type(of: currentChild.element),
key: currentChild.key
)

result.append((identifier: identifier, node: resultNode))
return SignpostLogger.log(
name: "Layout Element",
info: .init(type: type(of: LayoutType.self))
) {
let layoutItems = self.layoutItems(in: environment)
let childAttributes = layout.layout(size: attributes.bounds.size, items: layoutItems)

var result: [(identifier: ElementIdentifier, node: LayoutResultNode)] = []
result.reserveCapacity(children.count)

var identifierFactory = ElementIdentifier.Factory(elementCount: children.count)

for index in 0..<children.count {
let currentChildLayoutAttributes = childAttributes[index]
let currentChild = children[index]

let resultNode = LayoutResultNode(
element: currentChild.element,
layoutAttributes: currentChildLayoutAttributes,
content: currentChild.content,
environment: environment
)

let identifier = identifierFactory.nextIdentifier(
for: type(of: currentChild.element),
key: currentChild.key
)

result.append((identifier: identifier, node: resultNode))
}

return result
}

return result
}

private func layoutItems(in environment: Environment) -> [(LayoutType.Traits, Measurable)] {
return children.map { ($0.traits, $0.content.measurable(in: environment)) }
children.map { ($0.traits, $0.content.measurable(in: environment)) }
}

fileprivate struct Child {
Expand Down Expand Up @@ -318,25 +328,36 @@ private struct EnvironmentAdaptingStorage: ContentStorage {
environment: Environment)
-> [(identifier: ElementIdentifier, node: LayoutResultNode)]
{
let environment = adapted(environment: environment)
SignpostLogger.log(
name: "Layout Element",
info: .init(type: type(of: child))
) {
let environment = adapted(environment: environment)

let childAttributes = LayoutAttributes(size: attributes.bounds.size)
let childAttributes = LayoutAttributes(size: attributes.bounds.size)

let identifier = ElementIdentifier(elementType: type(of: child), key: nil, count: 1)
let identifier = ElementIdentifier(elementType: type(of: child), key: nil, count: 1)

let node = LayoutResultNode(
element: child,
layoutAttributes: childAttributes,
content: child.content,
environment: environment)
let node = LayoutResultNode(
element: child,
layoutAttributes: childAttributes,
content: child.content,
environment: environment)

return [(identifier, node)]
return [(identifier, node)]
}
}

func measure(in constraint: SizeConstraint, environment: Environment) -> CGSize {
let environment = adapted(environment: environment)

SignpostLogger.log(
name: "Measure Element 2",
info: .init(type: type(of: child))
) {
let environment = adapted(environment: environment)

return child.content.measure(in: constraint, environment: environment)
return child.content.measure(in: constraint, environment: environment)
}
}

private func adapted(environment: Environment) -> Environment {
Expand All @@ -360,22 +381,36 @@ private struct LazyStorage: ContentStorage {
{
let constraint = SizeConstraint(attributes.bounds.size)
let child = buildChild(in: constraint, environment: environment)
let childAttributes = LayoutAttributes(size: attributes.bounds.size)

return SignpostLogger.log(
name: "Layout Element",
info: .init(type: type(of: child))
) {

let childAttributes = LayoutAttributes(size: attributes.bounds.size)

let identifier = ElementIdentifier(elementType: type(of: child), key: nil, count: 1)
let identifier = ElementIdentifier(elementType: type(of: child), key: nil, count: 1)

let node = LayoutResultNode(
element: child,
layoutAttributes: childAttributes,
content: child.content,
environment: environment)
let node = LayoutResultNode(
element: child,
layoutAttributes: childAttributes,
content: child.content,
environment: environment)

return [(identifier, node)]
return [(identifier, node)]
}
}

func measure(in constraint: SizeConstraint, environment: Environment) -> CGSize {

let child = buildChild(in: constraint, environment: environment)
return child.content.measure(in: constraint, environment: environment)

return SignpostLogger.log(
name: "Measure Element 3",
info: .init(type: type(of: child))
) {
child.content.measure(in: constraint, environment: environment)
}
}

private func buildChild(in constraint: SizeConstraint, environment: Environment) -> Element {
Expand All @@ -396,15 +431,19 @@ fileprivate struct SingleChildLayoutHost: Layout {

func measure(in constraint: SizeConstraint, items: [(traits: (), content: Measurable)]) -> CGSize {
precondition(items.count == 1)
return wrapped.measure(in: constraint, child: items.map { $0.content }.first!)
return wrapped.measure(in: constraint, child: items.first!.content)
}

func layout(size: CGSize, items: [(traits: (), content: Measurable)]) -> [LayoutAttributes] {
precondition(items.count == 1)
return [
wrapped.layout(size: size, child: items.map { $0.content }.first!)
wrapped.layout(size: size, child: items.first!.content)
]
}

func assString() -> SignpostLogger.Info {
.init(type: wrapped.childElementType)
}
}


Expand All @@ -419,6 +458,9 @@ fileprivate struct PassthroughLayout: SingleChildLayout {
return LayoutAttributes(size: size)
}

func elementType(for child: Measurable) -> Any.Type {
type(of: child)
}
}


Expand Down
4 changes: 3 additions & 1 deletion BlueprintUI/Sources/Internal/LayoutResultNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ extension LayoutResultNode {

extension LayoutResultNode {

typealias ResolvedNodes = (path: ElementPath, node: NativeViewNode)

/// Returns the flattened tree of view descriptions (any element that does not return
/// a view description will be skipped).
func resolve() -> [(path: ElementPath, node: NativeViewNode)] {
func resolve() -> [ResolvedNodes] {

let resolvedChildContent: [(path: ElementPath, node: NativeViewNode)] = children
.flatMap { identifier, layoutResultNode in
Expand Down
Loading