@@ -6,6 +6,9 @@ import com.alexdeww.reactiveviewmodel.core.property.Action
66import com.alexdeww.reactiveviewmodel.core.property.ConfirmationEvent
77import com.alexdeww.reactiveviewmodel.core.property.Event
88import com.alexdeww.reactiveviewmodel.core.property.State
9+ import io.reactivex.rxjava3.core.Completable
10+ import io.reactivex.rxjava3.core.Maybe
11+ import io.reactivex.rxjava3.core.Observable
912import io.reactivex.rxjava3.disposables.CompositeDisposable
1013import io.reactivex.rxjava3.disposables.Disposable
1114
@@ -14,8 +17,16 @@ import io.reactivex.rxjava3.disposables.Disposable
1417 * https://github.com/dmdevgo/RxPM
1518 */
1619
20+ const val DEF_PROGRESS_DEBOUNCE_INTERVAL = 500L // ms
21+ const val DEF_ACTION_DEBOUNCE_INTERVAL = 300L // ms
22+
1723abstract class ReactiveViewModel : ViewModel (), RvmComponent {
1824
25+ protected interface Invocable <T > {
26+ val isExecute: Boolean
27+ operator fun invoke (params : T )
28+ }
29+
1930 private val disposableList = CompositeDisposable ()
2031
2132 override fun onCleared () {
@@ -28,25 +39,108 @@ abstract class ReactiveViewModel : ViewModel(), RvmComponent {
2839 return this
2940 }
3041
31- protected fun <T : Any > state (initValue : T ? = null, debounceInterval : Long? = null): State <T > =
32- State (initValue, debounceInterval)
42+ protected fun <T : Any > state (
43+ initValue : T ? = null,
44+ debounceInterval : Long? = null
45+ ): State <T > = State (initValue, debounceInterval)
46+
47+ protected fun progressState (
48+ initValue : Boolean? = null,
49+ debounceInterval : Long = DEF_PROGRESS_DEBOUNCE_INTERVAL
50+ ): State <Boolean > = state(initValue, debounceInterval)
3351
3452 protected fun <T : Any > event (debounceInterval : Long? = null): Event <T > =
3553 Event (debounceInterval)
3654
3755 protected fun eventNone (debounceInterval : Long? = null): Event <Unit > =
38- Event (debounceInterval)
56+ event (debounceInterval)
3957
40- protected fun <T : Any > confirmationEvent (debounceInterval : Long? = null): ConfirmationEvent <T > =
41- ConfirmationEvent (debounceInterval)
58+ protected fun <T : Any > confirmationEvent (
59+ debounceInterval : Long? = null
60+ ): ConfirmationEvent <T > = ConfirmationEvent (debounceInterval)
4261
43- protected fun confirmationEventNone (debounceInterval : Long? = null): ConfirmationEvent <Unit > =
44- ConfirmationEvent (debounceInterval)
62+ protected fun confirmationEventNone (
63+ debounceInterval : Long? = null
64+ ): ConfirmationEvent <Unit > = confirmationEvent(debounceInterval)
4565
4666 protected fun <T : Any > action (debounceInterval : Long? = null): Action <T > =
4767 Action (debounceInterval)
4868
4969 protected fun actionNone (debounceInterval : Long? = null): Action <Unit > =
50- Action (debounceInterval)
70+ action(debounceInterval)
71+
72+ protected fun <T : Any > debouncedAction (
73+ debounceInterval : Long = DEF_ACTION_DEBOUNCE_INTERVAL
74+ ): Action <T > = action(debounceInterval)
75+
76+ protected fun debouncedActionNone (
77+ debounceInterval : Long = DEF_ACTION_DEBOUNCE_INTERVAL
78+ ): Action <Unit > = action(debounceInterval)
79+
80+ protected fun <T : Any , R : Any > Action<T>.bind (
81+ transformChainBlock : Observable <T >.() -> Observable <R >
82+ ) {
83+ observable
84+ .transformChainBlock()
85+ .applyDefaultErrorHandler()
86+ .retry()
87+ .subscribe()
88+ .disposeOnCleared()
89+ }
90+
91+ protected fun <T : Any > State<T>.bind (
92+ transformChainBlock : Observable <T >.() -> Observable <out Any >
93+ ) {
94+ observable
95+ .transformChainBlock()
96+ .applyDefaultErrorHandler()
97+ .retry()
98+ .subscribe()
99+ .disposeOnCleared()
100+ }
101+
102+ protected fun <T : Any > invocable (
103+ block : (params: T ) -> Completable
104+ ): Lazy <Invocable <T >> = lazy {
105+ val action = action<T >()
106+ var isExecute = false
107+ action.bind {
108+ this .switchMapCompletable { params -> block(params).bindProgress { isExecute = it } }
109+ .toObservable<Unit >()
110+ }
111+ object : Invocable <T > {
112+ override val isExecute: Boolean get() = isExecute
113+ override fun invoke (params : T ) = action.consumer.accept(params)
114+ }
115+ }
116+
117+ protected fun <T : Any > Observable<T>.untilOn (vararg action : Action <out Any >): Observable <T > =
118+ takeUntil(Observable .merge(action.map { it.observable }))
119+
120+ protected fun <T : Any > Observable<T>.untilOn (vararg event : Event <out Any >): Observable <T > =
121+ takeUntil(Observable .merge(event.map { it.observable }))
122+
123+ protected fun <T : Any > Observable<T>.untilOn (vararg observable : Observable <* >): Observable <T > =
124+ takeUntil(Observable .merge(observable.toList()))
125+
126+ protected fun <T : Any > Maybe<T>.untilOn (vararg action : Action <* >): Maybe <T > =
127+ takeUntil(Maybe .merge(action.map { it.observable.firstElement() }))
128+
129+ protected fun <T : Any > Maybe<T>.untilOn (vararg event : Event <* >): Maybe <T > =
130+ takeUntil(Maybe .merge(event.map { it.observable.firstElement() }))
131+
132+ protected fun <T : Any > Maybe<T>.untilOn (vararg maybe : Maybe <* >): Maybe <T > =
133+ takeUntil(Maybe .merge(maybe.toList()))
134+
135+ protected fun Completable.untilOn (vararg action : Action <* >): Completable =
136+ takeUntil(Completable .merge(action.map { it.observable.firstElement().ignoreElement() }))
137+
138+ protected fun Completable.untilOn (vararg event : Event <* >): Completable =
139+ takeUntil(Completable .merge(event.map { it.observable.firstElement().ignoreElement() }))
140+
141+ protected fun Completable.untilOn (vararg completable : Completable ): Completable =
142+ takeUntil(Completable .merge(completable.toList()))
143+
144+ protected open fun <T : Any > Observable<T>.applyDefaultErrorHandler (): Observable <T > = this
51145
52146}
0 commit comments