Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Created December 15, 2021 21:07
Show Gist options
  • Save oleksii-demedetskyi/2bf1f7a0bb0aa80ac5782dcf402dac82 to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/2bf1f7a0bb0aa80ac5782dcf402dac82 to your computer and use it in GitHub Desktop.
class Subscription<T> {
func perform(callback: () -> Void) {
}
func notify() {
}
}
class State<T> {
let subscription = Subscription<T>()
internal init(value: T) {
self.value = value
}
var value: T {
didSet {
// Set notification
}
}
}
class Counter {
var value = State(value: 0)
func increment() {
value.value += 1
}
func decrement() {
value.value -= 1
}
}
class Application {
let countersList = CountersList()
}
class CountersList {
var counters = State(value: [] as [Counter])
private(set) lazy var total = Selector<Int> { read in
if (read(self.counters).count > 100) { return 100 }
var sum = 0
for counter in read(self.counters) {
sum += read(counter.value)
}
return sum
}
func addCounter() {
counters.value.append(Counter())
}
}
struct Reader {
let callback: () -> ()
func callAsFunction<T>(_ state: State<T>) -> T {
state.subscription.perform(callback: callback)
return state.value
}
func callAsFunction<T>(_ selector: Selector<T>) -> T {
selector.subscription.perform(callback: callback)
return selector.value
}
}
class Selector<T> {
let subscription = Subscription<T>()
internal init(get: @escaping (Reader) -> T) {
self.get = get
}
var get: (Reader) -> T
private var cachedValue: T?
var value: T {
if let cachedValue = cachedValue { return cachedValue }
let reader = Reader(callback: onDependencyChanged)
cachedValue = get(reader)
return cachedValue!
}
private func onDependencyChanged() {
cachedValue = nil
subscription.notify()
}
}
class MyCountersUIViewController {
struct Props {
let total: Int
let counters: [Counter]
struct Counter {
let value: Int
let increment: () -> ()
}
}
var props = Props(total: 0, counters: [])
}
class MyCountersOperator {
internal init(state: Application) {
self.state = state
}
let state: Application
private(set) lazy var props = Selector<MyCountersUIViewController.Props> { read in
.init(total: read(self.state.countersList.total),
counters: read(self.state.countersList.counters).map { counter in
.init(value: read(counter.value), increment: counter.increment)
})
}
}
func connect(vc: MyCountersUIViewController, to op: MyCountersOperator) {
op.props.subscription.perform {
vc.props = op.props.value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment