Clarify renderer API, add ChildrenType

This commit is contained in:
Max Desiatov 2018-11-27 09:34:51 +00:00
parent 8893dfdb9d
commit 819cb6fa13
No known key found for this signature in database
GPG Key ID: FE08EBF9CF58CBA2
3 changed files with 53 additions and 31 deletions

View File

@ -31,6 +31,8 @@ import Gluon
//}
struct Counter: LeafComponent {
typealias Props = NoProps
static func render(props: NoProps) -> Node {
let (count, setCount) = hooks.state(0)

View File

@ -7,16 +7,28 @@
import Foundation
extension Never: Equatable {
public static func == (lhs: Never, rhs: Never) -> Bool {
switch (lhs, rhs) {
}
}
}
/// Type-erased version of Component to work around
/// the lack of generalized existentials in Swift
public protocol _Component {
}
/// Conforming to this protocol, but implementing support for these new types
/// in a renderer would make that renderer skip unknown types of children.
public protocol ChildrenType {
}
/// You should never directly conform to this protocol, use `HostComponent`
/// for host components and `Component` for composite components.
public protocol BaseComponent: _Component {
associatedtype Props: Equatable
associatedtype Children: Equatable
associatedtype Children: ChildrenType & Equatable
var children: Children { get }
var props: Props { get }
@ -26,16 +38,16 @@ public protocol Component: _Component {
associatedtype Props: Equatable
associatedtype Children: Equatable
static func render(props: Props, children: Children)
static func render(props: Props, children: Children) -> Node
}
public protocol LeafComponent: Component where Children == NoProps {
static func render(props: Props)
public protocol LeafComponent: Component where Children == Never {
static func render(props: Props) -> Node
}
extension LeafComponent {
static func render(props: Props, children: NoProps) {
render(props: props)
public extension LeafComponent {
public static func render(props: Props, children: Children) -> Node {
return render(props: props)
}
}
@ -55,37 +67,43 @@ extension Component {
}
public struct Node: Equatable {
/// Equatable can't be automatically derived for recursive types
/// Equatable can't be automatically derived for `type` property?
public static func == (lhs: Node, rhs: Node) -> Bool {
return lhs.type == rhs.type &&
return lhs.key == rhs.key &&
lhs.type == rhs.type &&
lhs.children == rhs.children &&
lhs.props == rhs.props
}
let key: String?
let props: AnyEquatable
let children: [Node]
let children: AnyEquatable
let type: _Component.Type
}
public protocol Child {
}
extension BaseComponent {
// init?(props: AnyEquatable, children: [Node]) {
// guard let props = props.value as? Props else {
// return nil
// }
//
// self.init(props: props, children: children)
// }
public static func node(_ props: Props, _ children: Children) -> Node {
return Node(props: AnyEquatable(props), children: children, type: self.self)
public static func node(key: String? = nil,
_ props: Props,
_ children: Children) -> Node {
return Node(key: key,
props: AnyEquatable(props),
children: AnyEquatable(children),
type: self.self)
}
}
extension Node: ChildrenType {
}
extension Array: ChildrenType where Element == Node {
}
extension String: ChildrenType {
}
public struct View: BaseComponent {
public typealias Children = [Node]
public let props: Props
public let children: [Node]
@ -94,11 +112,8 @@ public struct View: BaseComponent {
}
public struct Label: BaseComponent {
public let props: Props
public let children: [Node]
public struct Props: Equatable {
}
public let props: NoProps
public let children: String
}
public struct Button: BaseComponent {

View File

@ -8,17 +8,22 @@
import Foundation
protocol Renderer {
func mountTarget(to parent: Any, with component: RendererBaseComponent) -> Any
func update(target: Any, with component: RendererBaseComponent)
func umount(target: Any, from parent: Any, with component: RendererBaseComponent)
}
protocol Reconciler {
}
protocol UIKitBaseComponent {
protocol RendererBaseComponent {
}
protocol UIKitBaseComponent: RendererBaseComponent {
}
class UIKitRenderer {
}