Delegate reconciling to ComponentWrapper

This commit is contained in:
Max Desiatov 2018-12-02 16:05:55 +00:00
parent 88a7a013c0
commit 707d696f25
No known key found for this signature in database
GPG Key ID: FE08EBF9CF58CBA2
4 changed files with 47 additions and 16 deletions

View File

@ -6,7 +6,7 @@
//
protocol ComponentWrapper {
func mount(with renderer: Renderer)
func mount(with renderer: Renderer, to target: Any)
func unmount(with renderer: Renderer)
@ -14,7 +14,7 @@ protocol ComponentWrapper {
}
final class CompositeComponentWrapper: ComponentWrapper {
private let node: Node
private var node: Node
private var mountedChildren = [ComponentWrapper]()
private let type: AnyCompositeComponent.Type
var state = [String: Any]()
@ -24,23 +24,33 @@ final class CompositeComponentWrapper: ComponentWrapper {
self.type = type
}
func mount(with: Renderer) {
func mount(with renderer: Renderer, to target: Any) {
let renderedNode = type.render(props: node.props, children: node.children)
mountedChildren = []
let child = renderedNode.makeComponentWrapper()
mountedChildren = [child]
child.mount(with: renderer, to: target)
}
func unmount(with renderer: Renderer) {
for child in mountedChildren {
child.unmount(with: renderer)
}
// FIXME: this is probably not needed, right?
mountedChildren = []
}
func update(with renderer: Renderer) {
let newNode = render()
if node.type == newNode.type {
}
}
func render() -> Node {
return type.render(props: node.props, children: node.children)
}
}
@ -48,17 +58,41 @@ final class HostComponentWrapper: ComponentWrapper {
private let node: Node
fileprivate var mountedChildren = [ComponentWrapper]()
private let type: AnyHostComponent.Type
var target: Any?
private var target: Any?
init(_ node: Node, _ type: AnyHostComponent.Type) {
self.type = type
self.node = node
}
func mount(with renderer: Renderer) {
func mount(with renderer: Renderer, to target: Any) {
self.target = renderer.mountTarget(to: target,
with: type,
props: node.props,
children: node.children)
switch node.children.value {
case let nodes as [Node]:
mountedChildren = nodes.map { $0.makeComponentWrapper() }
for child in mountedChildren {
child.mount(with: renderer, to: target)
}
case let node as Node:
let child = node.makeComponentWrapper()
mountedChildren = [child]
child.mount(with: renderer, to: target)
default:
// child type that can't be rendered, but still makes sense as a child
// (e.g. `String`)
()
}
}
func unmount(with renderer: Renderer) {
guard let target = target else { return }
renderer.unmount(target: target, with: type)
}
func update(with renderer: Renderer) {

View File

@ -7,7 +7,7 @@
public struct Node: Equatable {
/// Equatable can't be automatically derived for `type` property?
public static func == (lhs: Node, rhs: Node) -> Bool {
public static func ==(lhs: Node, rhs: Node) -> Bool {
return lhs.key == rhs.key &&
lhs.type == rhs.type &&
lhs.children == rhs.children &&

View File

@ -18,11 +18,8 @@ protocol Renderer: class {
props: AnyEquatable,
children: AnyEquatable)
func umount(target: Any,
from parent: Any,
with component: AnyHostComponent.Type,
props: AnyEquatable,
children: AnyEquatable)
func unmount(target: Any,
with component: AnyHostComponent.Type)
func removeAllChildren(from target: Any)
}

View File

@ -29,7 +29,7 @@ final class StackReconciler {
rootComponent = node.makeComponentWrapper()
rootComponent.mount(with: renderer)
rootComponent.mount(with: renderer, to: rootTarget)
}
func queue(state: Any, for component: CompositeComponentWrapper, id: String) {
@ -60,7 +60,7 @@ final class StackReconciler {
for (component, id, state) in queuedState {
component.state[id] = state
component.mount(with: renderer)
component.update(with: renderer)
}
}
}