Created
December 15, 2021 21:07
-
-
Save oleksii-demedetskyi/2bf1f7a0bb0aa80ac5782dcf402dac82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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