Skip to content

Instantly share code, notes, and snippets.

@niorko
Created February 8, 2018 11:33
Show Gist options
  • Save niorko/75a88968d8c001747063df82a900cc52 to your computer and use it in GitHub Desktop.
Save niorko/75a88968d8c001747063df82a900cc52 to your computer and use it in GitHub Desktop.
ActivityIndicator.swift
/**
Enables monitoring of sequence computation.
If there is at least one sequence computation in progress, `true` will be sent.
When all activities complete `false` will be sent.
*/
class ActivityIndicator : DriverConvertibleType {
typealias E = Bool
fileprivate let _lock = NSRecursiveLock()
fileprivate let _variable = Variable(0)
fileprivate let _loading: Driver<Bool>
init() {
_loading = _variable.asObservable()
.map { $0 > 0 }
.distinctUntilChanged()
.asDriver { (error: Error) -> Driver<Bool> in
_ = fatalError("Loader can't fail")
return Driver.empty()
}
}
func trackActivity<O: ObservableConvertibleType>(_ source: O) -> Observable<O.E> {
ObservableConvertibleType
return Observable.using({ () -> ActivityToken<O.E> in
self.increment()
return ActivityToken(source: source.asObservable(), disposeAction: self.decrement)
}) { t in
return t.asObservable()
}
}
fileprivate func increment() {
_lock.lock()
_variable.value = _variable.value + 1
_lock.unlock()
}
fileprivate func decrement() {
_lock.lock()
_variable.value = _variable.value - 1
_lock.unlock()
}
func asDriver() -> Driver<E> {
return _loading
}
}
extension ObservableConvertibleType {
func trackActivity(_ activityIndicator: ActivityIndicator) -> Observable<E> {
return activityIndicator.trackActivity(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment