Skip to content

Instantly share code, notes, and snippets.

View tcw165's full-sized avatar
💭
building AI

TC Wang tcw165

💭
building AI
View GitHub Profile
/**
* Window type: an application window that serves as the "base" window
* of the overall application; all other application windows will
* appear on top of it.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_BASE_APPLICATION = 1;
/**
* Window type: a normal application window. The {@link #token} must be
fun setupCoffeeMachine(...) {
val debounceClicks: Observable<Unit> = btBrewCoffee.clicks()
.debounce(250L, TimeUnit.MILLISECONDS)
debounceClicks
.switchMapSingle {
brewCoffee() // Return Single<Coffee>
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
// Retry at position #1 <--------------------------------------
.retryWhen { errorObservable ->
clicks.switchMapSingle {
brewCoffee() // Return Single<Coffee>
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
// Redirect -------------------------------------------------->
.retryWhen { errors ->
errors.flatMap {
caughtErrorRelay.accept(err) // Redirect the error via a Subject or RxRelay
...
}
}
fun setupCoffeeMachine(...) {
clicks.switchMapSingle {
brewCoffee()
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
// To UI states ---------------------------------------------->
.toObservable()
.map { UiState.Done }
.startWith(UiState.IN_PROGRESS)
.onErrorReturn { err -> Observable.just(UiState.Error(err)) }
// <-----------------------------------------------------------
upstream
.retryWhen { errorObservable ->
errorObservable.map { error ->
throw error
}
}
fun setupCoffeeMachine(...) {
val clicks: Observable<Unit> = RxView.clicks(btBrewCoffee)
.map { Unit } // Could be replaced by Android Kotlin extension, i.e. btBrewCoffee.clicks().
.debounce(250L, TimeUnit.MILLISECONDS) // By default the debounce is running on the background thread.
clicks.switchMapSingle {
brewCoffee() // Return Single<Coffee>
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
// retryWhen() to the rescue --------------------------------->
.retryWhen { errorObservable ->
fun setupCoffeeMachine(...) {
val clicks: Observable<Unit> = btBrewCoffee.clicks()
.debounce(250L, TimeUnit.MILLISECONDS) // By default the clicks is observed on the background thread.
clicks.switchMapSingle {
brewCoffee() // Return Single<Coffee>
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
}
// retry() to the rescue --------------------------------------------->
.retry()
fun brewCoffee(): Single<Coffee> {
return Single
.fromCallable {
// Simulate the machine takes random time up to 5s to brew a coffee.
Thread.sleep(5 * 60 * 1000 * Math.random())
// The machine have chance to crash with no reason.
if (0.5f < Math.random()) throw RuntimeException()
return@Callable Coffee()
}
.subscribeOn(Schedulers.io())
fun setupCoffeeMachine(...) {
val clicks: Observable<Unit> = btBrewCoffee.clicks()
.debounce(250L, TimeUnit.MILLISECONDS) // By default the clicks is observed on the background thread.
clicks.switchMapSingle {
brewCoffee() // Return Single<Coffee>
.timeout(3, TimeUnit.MINUTES, Schedulers.computation())
}
.observeOn(AndroidSchedulers.mainThread()) // Most importantly, observe the values on the UI thread to avoid concurrent problem.
.subscribe({ coffee ->
val upstream = PublishSubject.create<Int>()
upstream.doOnDispose { Timber.d("Uh, the upstream gets disposed") } // This log will never print.
val tester = upstream
.flatMap { v ->
when (v) {
0 -> {
Timber.d("flatMap produces an empty")
Observable.empty<Int>()
}