Skip to content

Instantly share code, notes, and snippets.

@feresr
Created Jun 20, 2018
Embed
What would you like to do?
Presenter.kt
abstract class BasePresenter<I : MVI.Intent, S : MVI.ViewState> {
private val intents: PublishSubject<I> = PublishSubject.create<I>()
private var states: Observable<S>? = null
private var disposable: Disposable? = null
private var viewDisposable: Disposable? = null
fun onCreate() {
states = intents
.observeOn(Schedulers.computation())
.compose(this::transform)
.observeOn(AndroidSchedulers.mainThread())
.replay(1)
.autoConnect(0, { disposable = it })
}
/**
* Starts observing the view
*/
fun attachView(view: BaseView<I>) {
viewDisposable = view.intents()?.subscribe({ n -> intents.onNext(n) }, { Timber.e(it) })
}
/**
* Stops observing the view
*/
fun detachView() = viewDisposable?.dispose()
/**
* Provides a non-reactive way of feeding [Intent]s into this presenter
* This comes in handy when the non-reactive nature of android gets in the way
*/
fun processIntent(intent: I) = intents.onNext(intent)
/**
* Transforms a stream of [Intent]'s into a stream of [ViewState]'s
* To better separate the presentation logic from the business logic
* the intents should be mapped in this order:
* [Intent] -> [Action] -> [Result] -> [ViewState]
*/
abstract fun transform(intents: Observable<I>): Observable<S>
/**
* Exposes a stream of [ViewState]'s
* Note: Upon a new subscription, the last known State will be forwarded to
* the subscriber
*/
fun states(): Observable<S> {
return states ?: throw IllegalStateException("states is null, did you forget to call onCreate?")
}
fun onDestroy() = disposable?.dispose()
/**
* Classes implementing [BaseView] expose a stream of intents that
* the presenter will be able to observe and react to.
*/
interface BaseView<I : MVI.Intent> {
fun intents(): Observable<I>?
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment