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

Fiber Reconciler fixes #525

Closed
wants to merge 17 commits into from
Closed

Fiber Reconciler fixes #525

wants to merge 17 commits into from

Conversation

ahti
Copy link
Contributor

@ahti ahti commented Oct 31, 2022

This is what I have done so far to make the example (with a little modification) from #523 work.

Currently, things work until returning to the initial state, after which pressing the button will leave an empty screen.

Some comments in no particular order:

  • The reproducer target is of course only for debugging and to be removed before merge.
  • I've left the logs as normal prints for now, since swift-log doesn't build on wasm rn, we can remove those as well if things get ready before swift-log is fixed.
  • Pay no attention to the individual commits, I'll clean those up once things look more mergeable.
  • The implementation of ReconcilePass.reconcile(_: , in:, caches:) obviously still needs to be refactored.
  • The reconciliation pass currently emits mutations that seem to assume replacing an element transfers any children to the replacement. I've adjusted the DOM and test renderers, but maybe the emitted mutations should be changed instead.
  • I tried turning the reproducer into a test case, but that fails one step earlier, while returning to the initial state, due to an out of range index in an insert mutation.
  • Another issue I observed: There are cases where a remove mutation is emitted with the wrong parent. The DOMRenderer doesn't use the parent, so it's not an issue there, but it does materialize with the test renderer.
  • The parent in the remove mutation is optional, but all places where such a value is created pass a non-nil parent. Is there a reason for this, or can this be turned non-optional?

@carson-katri carson-katri added bug Something isn't working Fiber Changes related to the FiberReconciler or a FiberRenderer labels Nov 1, 2022
@carson-katri
Copy link
Member

I don't recall specifically, but the parent may be be optional because the root of the hierarchy has no parent and could hypothetically be removed.

@carson-katri
Copy link
Member

Tested on a small project and didn't notice any regressions.

@carson-katri carson-katri linked an issue Nov 1, 2022 that may be closed by this pull request
@ahti
Copy link
Contributor Author

ahti commented Jan 1, 2023

I finally found some time and started refactoring ReconcilePass.reconcile (not quite done with that), and also fixed the empty screen when going through all the states of the reproducer and then from .a to .b again (nothing was inserted when a fiber that should have an element had an alternate, but the alternate didn't have an element).

There is still an issue with label content not being updated tho, which I'm going to look into next.

@ahti
Copy link
Contributor Author

ahti commented Jan 2, 2023

Fixed the stale label content as well.

The only issue left that I am aware of is the .remove mutation with wrong parent. I've extended the test to reproduce that one, too. Oh and the reconcile method could still be dryed a bit further.

I also changed the test renderer so that multiple changed fibers get batched like they do in real renderers. Without that, the test was kind of flaky and would randomly succeed or fail (before adding the part to reproduce the remove bug, that is).

Copy link
Member

@carson-katri carson-katri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice improvements, thank you. I used it on a test project of mine and it worked well.

Package.swift Outdated
@@ -15,6 +15,7 @@ let package = Package(
name: "TokamakDemo",
targets: ["TokamakDemo"]
),
.executable(name: "RecRep", targets: ["RecRep"]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should have this executable as part of the Tokamak package. It seems you have already adapted it to a test case, which should be enough.

Comment on lines 273 to 279
print("""
reconcile done
mutations were:
\(visitor.mutations.map { " \($0)" }.joined(separator: "\n"))
alternate is \(self.alternate.recursiveDescription)
current is \(current.recursiveDescription)
""")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clean up any print statements before merging? Better debug logging could be tackled in a separate PR.


invalidateCache(for: fiber, in: reconciler, caches: caches)

switch (fiber.element, node.newContent, fiber.alternate?.element) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice improvement here!

if let p = fiber.elementParent { caches.elementIndices[ObjectIdentifier(p)]? -= 1 }
return .remove(element: alt, parent: parent)

case let (element?, content, _) where fiber.alternate?.element == nil:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this be written as:

Suggested change
case let (element?, content, _) where fiber.alternate?.element == nil:
case let (element?, content, nil):

@carson-katri carson-katri changed the title [wip] fix #523 Fiber Reconciler fixes Feb 4, 2023
@ahti ahti mentioned this pull request Aug 16, 2023
@ahti
Copy link
Contributor Author

ahti commented Sep 3, 2023

superseeded by #542

@ahti ahti closed this Sep 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Fiber Changes related to the FiberReconciler or a FiberRenderer
Development

Successfully merging this pull request may close these issues.

Fiber layout/reconciliation issues
2 participants