Delegate reconciling to ComponentWrapper
This commit is contained in:
parent
88a7a013c0
commit
707d696f25
|
@ -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) {
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue