-
-
Notifications
You must be signed in to change notification settings - Fork 113
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
Fix environment changes causing remounted scenes with lost state #223
Conversation
# Conflicts: # Sources/TokamakCore/App/_AnyScene.swift # Sources/TokamakCore/MountedViews/MountedApp.swift # Sources/TokamakCore/MountedViews/MountedElement.swift # Sources/TokamakCore/StackReconciler.swift
protocol ViewContainingScene { | ||
var anyContent: AnyView { get } | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There doesn't seem to be a difference between ViewContainingScene
and SceneDeferredToRenderer
, so I'm only keeping the latter.
@@ -34,49 +34,43 @@ final class MountedApp<R: Renderer>: MountedCompositeElement<R> { | |||
mountedChildren.forEach { $0.unmount(with: reconciler) } | |||
} | |||
|
|||
private func mountChild<S: Scene>(_ childBody: S) -> MountedElement<R> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice S
is always _AnyScene
here as everything is type-erased by this point, so no need for it to be generic.
updateChild: { $0.scene = _AnyScene(element) }, | ||
getElementType: { $0.type }, | ||
updateChild: { | ||
$0.environmentValues = environmentValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where environment was not passed from a parent to its children previously.
let parentTarget: R.TargetType | ||
|
||
var state = [Any]() | ||
var subscriptions = [AnyCancellable]() | ||
var environmentValues: EnvironmentValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both environmentValues
and mountedChildren
now live in the base MountedElement
superclass as all subclasses need them except the MountedEmptyView
. I think the overhead of MountedEmptyView
having empty children and environment containers on it is justified for now when considering the simplification we get here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Looks good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see no problems but I was also a tad distracted while reviewing
No problem, thanks for the review! |
Implements support for custom scenes by adding the new
MountedScene
type and fixes environment propagation from mounted parent to mounted child elements.This will unblock #136 and potentially #214. In the former scenes are always completely unmounted and remounted from scratch when root environment changes, which causes descendants to lose all
@State
values. I saw some environment propagation issues in the latter, but not sure if those were caused by the lack of correct scene updates, just wanted to tackle the usual suspects first.I've also improved reconciler-related doc comments to clarify some of the design desicions and naming.
Resolves #222.