Skip to content

Commit 50ad4b9

Browse files
committed
update base
1 parent dbf6f34 commit 50ad4b9

File tree

14 files changed

+62
-39
lines changed

14 files changed

+62
-39
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package com.hoc.flowmvi.core
22

3-
import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
3+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
44
import com.hoc.flowmvi.core_ui.navigator.Navigator
55
import org.koin.core.module.dsl.bind
66
import org.koin.core.module.dsl.singleOf
77
import org.koin.dsl.module
88

99
@JvmField
1010
val coreModule = module {
11-
singleOf(::DefaultCoroutineDispatchers) { bind<CoroutineDispatchers>() }
11+
singleOf(::DefaultAppCoroutineDispatchers) { bind<AppCoroutineDispatchers>() }
1212

1313
singleOf(::NavigatorImpl) { bind<Navigator>() }
1414
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.hoc.flowmvi.core
2+
3+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
4+
import kotlinx.coroutines.Dispatchers
5+
6+
internal class DefaultAppCoroutineDispatchers : AppCoroutineDispatchers {
7+
override val main get() = Dispatchers.Main
8+
override val mainImmediate get() = Dispatchers.Main.immediate
9+
override val io get() = Dispatchers.IO
10+
}

app/src/main/java/com/hoc/flowmvi/core/DefaultCoroutineDispatchers.kt

Lines changed: 0 additions & 10 deletions
This file was deleted.

core/src/main/java/com/hoc/flowmvi/core/dispatchers/CoroutineDispatchers.kt renamed to core/src/main/java/com/hoc/flowmvi/core/dispatchers/AppCoroutineDispatchers.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package com.hoc.flowmvi.core.dispatchers
22

33
import kotlinx.coroutines.CoroutineDispatcher
44

5-
interface CoroutineDispatchers {
5+
interface AppCoroutineDispatchers {
66
val main: CoroutineDispatcher
7+
val mainImmediate: CoroutineDispatcher
78
val io: CoroutineDispatcher
89
}

data/src/main/java/com/hoc/flowmvi/data/UserRepositoryImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import arrow.core.leftWiden
77
import arrow.core.right
88
import arrow.core.valueOr
99
import com.hoc.flowmvi.core.Mapper
10-
import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
10+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
1111
import com.hoc.flowmvi.data.remote.UserApiService
1212
import com.hoc.flowmvi.data.remote.UserBody
1313
import com.hoc.flowmvi.data.remote.UserResponse
@@ -39,7 +39,7 @@ import arrow.core.Either.Companion.catch as catchEither
3939
@ExperimentalCoroutinesApi
4040
internal class UserRepositoryImpl(
4141
private val userApiService: UserApiService,
42-
private val dispatchers: CoroutineDispatchers,
42+
private val dispatchers: AppCoroutineDispatchers,
4343
private val responseToDomain: Mapper<UserResponse, ValidatedNel<UserValidationError, User>>,
4444
private val domainToBody: Mapper<User, UserBody>,
4545
private val errorMapper: Mapper<Throwable, UserError>,

data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplRealAPITest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.hoc.flowmvi.data
22

33
import android.util.Log
4-
import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
4+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
55
import com.hoc.flowmvi.domain.repository.UserRepository
66
import com.hoc.flowmvi.test_utils.getOrThrow
77
import kotlinx.coroutines.CoroutineDispatcher
@@ -38,10 +38,11 @@ class UserRepositoryImplRealAPITest : KoinTest {
3838
modules(
3939
dataModule,
4040
module {
41-
factory<CoroutineDispatchers> {
42-
object : CoroutineDispatchers {
41+
factory<AppCoroutineDispatchers> {
42+
object : AppCoroutineDispatchers {
4343
override val main: CoroutineDispatcher get() = Main
4444
override val io: CoroutineDispatcher get() = IO
45+
override val mainImmediate: CoroutineDispatcher get() = Main.immediate
4546
}
4647
}
4748
}

data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import com.hoc.flowmvi.data.remote.UserResponse
1010
import com.hoc.flowmvi.domain.model.User
1111
import com.hoc.flowmvi.domain.model.UserError
1212
import com.hoc.flowmvi.domain.model.UserValidationError
13+
import com.hoc.flowmvi.test_utils.TestAppCoroutineDispatchers
1314
import com.hoc.flowmvi.test_utils.TestCoroutineDispatcherRule
14-
import com.hoc.flowmvi.test_utils.TestDispatchers
1515
import com.hoc.flowmvi.test_utils.getOrThrow
1616
import com.hoc.flowmvi.test_utils.leftOrThrow
1717
import com.hoc.flowmvi.test_utils.valueOrThrow
@@ -121,7 +121,7 @@ class UserRepositoryImplTest {
121121

122122
repo = UserRepositoryImpl(
123123
userApiService = userApiService,
124-
dispatchers = TestDispatchers(coroutineRule.testDispatcher),
124+
dispatchers = TestAppCoroutineDispatchers(coroutineRule.testDispatcher),
125125
responseToDomain = responseToDomain,
126126
domainToBody = domainToBody,
127127
errorMapper = errorMapper

feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddVM.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.hoc.flowmvi.ui.add
33
import androidx.lifecycle.SavedStateHandle
44
import androidx.lifecycle.viewModelScope
55
import arrow.core.orNull
6+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
67
import com.hoc.flowmvi.domain.model.User
78
import com.hoc.flowmvi.domain.usecase.AddUserUseCase
89
import com.hoc.flowmvi.mvi_base.AbstractMviViewModel
@@ -33,7 +34,8 @@ import timber.log.Timber
3334
class AddVM(
3435
private val addUser: AddUserUseCase,
3536
savedStateHandle: SavedStateHandle,
36-
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>() {
37+
appCoroutineDispatchers: AppCoroutineDispatchers,
38+
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>(appCoroutineDispatchers) {
3739

3840
override val viewState: StateFlow<ViewState>
3941

feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainVM.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.hoc.flowmvi.ui.main
22

33
import androidx.lifecycle.viewModelScope
44
import arrow.core.flatMap
5+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
56
import com.hoc.flowmvi.domain.usecase.GetUsersUseCase
67
import com.hoc.flowmvi.domain.usecase.RefreshGetUsersUseCase
78
import com.hoc.flowmvi.domain.usecase.RemoveUserUseCase
@@ -36,7 +37,8 @@ class MainVM(
3637
private val getUsersUseCase: GetUsersUseCase,
3738
private val refreshGetUsers: RefreshGetUsersUseCase,
3839
private val removeUser: RemoveUserUseCase,
39-
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>() {
40+
appCoroutineDispatchers: AppCoroutineDispatchers,
41+
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>(appCoroutineDispatchers) {
4042

4143
override val viewState: StateFlow<ViewState>
4244

feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchVM.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.hoc.flowmvi.ui.search
22

33
import androidx.lifecycle.SavedStateHandle
44
import androidx.lifecycle.viewModelScope
5+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
56
import com.hoc.flowmvi.domain.usecase.SearchUsersUseCase
67
import com.hoc.flowmvi.mvi_base.AbstractMviViewModel
78
import com.hoc081098.flowext.flatMapFirst
@@ -36,7 +37,8 @@ import kotlin.time.ExperimentalTime
3637
class SearchVM(
3738
private val searchUsersUseCase: SearchUsersUseCase,
3839
private val savedStateHandle: SavedStateHandle,
39-
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>() {
40+
appCoroutineDispatchers: AppCoroutineDispatchers,
41+
) : AbstractMviViewModel<ViewIntent, ViewState, SingleEvent>(appCoroutineDispatchers) {
4042

4143
override val viewState: StateFlow<ViewState>
4244

mvi/mvi-base/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies {
3838
implementation(deps.coroutines.core)
3939

4040
implementation(coreUi)
41+
implementation(core)
4142
implementation(deps.timber)
4243

4344
addUnitTest()

mvi/mvi-base/src/main/java/com/hoc/flowmvi/mvi_base/AbstractMviViewModel.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import android.os.Build
44
import androidx.annotation.CallSuper
55
import androidx.lifecycle.ViewModel
66
import androidx.lifecycle.viewModelScope
7+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
78
import kotlinx.coroutines.channels.Channel
9+
import kotlinx.coroutines.currentCoroutineContext
810
import kotlinx.coroutines.flow.Flow
911
import kotlinx.coroutines.flow.MutableSharedFlow
1012
import kotlinx.coroutines.flow.SharedFlow
@@ -14,11 +16,16 @@ import kotlinx.coroutines.flow.onEach
1416
import kotlinx.coroutines.flow.receiveAsFlow
1517
import kotlinx.coroutines.flow.shareIn
1618
import kotlinx.coroutines.flow.stateIn
19+
import kotlinx.coroutines.withContext
1720
import timber.log.Timber
21+
import kotlin.LazyThreadSafetyMode.PUBLICATION
22+
import kotlin.coroutines.ContinuationInterceptor
1823

19-
abstract class AbstractMviViewModel<I : MviIntent, S : MviViewState, E : MviSingleEvent> :
24+
abstract class AbstractMviViewModel<I : MviIntent, S : MviViewState, E : MviSingleEvent>(
25+
private val appCoroutineDispatchers: AppCoroutineDispatchers,
26+
) :
2027
MviViewModel<I, S, E>, ViewModel() {
21-
protected val logTag by lazy(LazyThreadSafetyMode.PUBLICATION) {
28+
protected val logTag by lazy(PUBLICATION) {
2229
this::class.java.simpleName.let { tag: String ->
2330
// Tag length limit was removed in API 26.
2431
if (tag.length <= MAX_TAG_LENGTH || Build.VERSION.SDK_INT >= 26) {
@@ -43,7 +50,14 @@ abstract class AbstractMviViewModel<I : MviIntent, S : MviViewState, E : MviSing
4350

4451
// Send event and access intent flow.
4552

46-
protected suspend fun sendEvent(event: E) = eventChannel.send(event)
53+
protected suspend fun sendEvent(event: E) {
54+
if (currentCoroutineContext()[ContinuationInterceptor] === appCoroutineDispatchers.mainImmediate) {
55+
eventChannel.send(event)
56+
} else {
57+
withContext(appCoroutineDispatchers.mainImmediate) { eventChannel.send(event) }
58+
}
59+
}
60+
4761
protected val intentFlow: SharedFlow<I> get() = intentMutableFlow
4862

4963
// Extensions on Flow using viewModelScope.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.hoc.flowmvi.test_utils
2+
3+
import com.hoc.flowmvi.core.dispatchers.AppCoroutineDispatchers
4+
import kotlinx.coroutines.ExperimentalCoroutinesApi
5+
import kotlinx.coroutines.test.TestDispatcher
6+
7+
@ExperimentalCoroutinesApi
8+
class TestAppCoroutineDispatchers(private val testCoroutineDispatcher: TestDispatcher) :
9+
AppCoroutineDispatchers {
10+
override val main get() = testCoroutineDispatcher
11+
override val mainImmediate get() = testCoroutineDispatcher
12+
override val io get() = testCoroutineDispatcher
13+
}

test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestDispatchers.kt

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)