More code based on Equatable props

This commit is contained in:
Max Desiatov 2018-10-03 15:46:30 +01:00
parent f96157340d
commit 4289c4ee88
No known key found for this signature in database
GPG Key ID: FE08EBF9CF58CBA2
1 changed files with 31 additions and 82 deletions

View File

@ -8,100 +8,49 @@
import UIKit
protocol KeyPathListable {
// require empty init as the implementation use the mirroring API, which require
// to be used on an instance. So we need to be able to create a new instance of the
// type.
init()
var _keyPathReadableFormat: [String: Any] { get }
static var allKeyPaths: [KeyPath<Foo, Any?>] { get }
protocol Default {
init()
}
extension KeyPathListable {
var _keyPathReadableFormat: [String: Any] {
let mirror = Mirror(reflecting: self)
var description: [String: Any] = [:]
for case let (label?, value) in mirror.children {
description[label] = value
}
return description
}
class BaseComponent<P: Equatable, S: Default> {
private(set) var props: P
private(set) var state: S
static var allKeyPaths: [KeyPath<Self, Any?>] {
var keyPaths: [KeyPath<Self, Any?>] = []
let instance = Self()
for (key, _) in instance._keyPathReadableFormat {
keyPaths.append(\Self._keyPathReadableFormat[key])
}
return keyPaths
}
init(props: P, state: S) {
self.props = props
self.state = state
}
static func node(_ p: P,
_ c: [NodeType] = []) -> NodeType {
return Node(component: self, props: p, children: c)
}
}
protocol Diffable: KeyPathListable {
protocol NodeType {
}
struct Foo: KeyPathListable {
var x: Int
var y: Int
struct Node<P, S>: NodeType
where P: Equatable, S: Default {
let component: BaseComponent<P, S>.Type
let props: P
let children: [NodeType]
}
protocol GluonProp: Hashable {
extension UIControl.State: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(rawValue)
}
}
protocol GluonState {
init()
}
final class Button: BaseComponent<Button.Props, Button.State> {
struct Props: Equatable {
let backgroundColor: UIColor
let titles: [UIControl.State: String]
}
protocol AnyBaseComponent {
}
protocol AnyComponent {
func render() -> AnyGluonNode
}
class BaseComponent<P: GluonProp, S: GluonState>: AnyBaseComponent {
var props: Set<P> = []
var state = S()
}
typealias Component<P: GluonProp, S: GluonState> = BaseComponent<P, S> & AnyComponent
// protocol Gluon: Component {
// func render() -> AnyGluonNode
// }
extension BaseComponent {
static func node(_ props: Set<P> = [],
_ children: [AnyGluonNode] = []) -> GluonNode<P> {
return GluonNode(self, props, children)
}
}
protocol AnyGluonNode {}
struct GluonNode<P>: AnyGluonNode
where P: GluonProp {
let component: AnyBaseComponent.Type
let props: Set<P>
let children: [AnyGluonNode]
init(_ component: AnyBaseComponent.Type,
_ props: Set<P>,
_ children: [AnyGluonNode]) {
self.component = component
self.props = props
self.children = children
}
}
extension String: AnyGluonNode {
}
enum ButtonProp: GluonProp {
case backgroundColor(UIColor)
case textColor(UIColor)
case disabled(Bool)
struct State: Default {
}
}
//final class Button: BaseComponent<ButtonProp> {