From 91078de1a7a4c0bbb16533965532092ff8656f55 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Fri, 26 Nov 2021 19:39:28 +0300 Subject: [PATCH] Replace PagingSource factory with Google's impl --- .../mealient/data/recipes/RecipeModule.kt | 11 +++++ .../recipes/impl/RecipePagingSourceFactory.kt | 45 ------------------- .../data/recipes/impl/RecipeRepoImpl.kt | 3 +- .../recipes/impl/RecipesRemoteMediator.kt | 7 +-- .../impl/RecipePagingSourceFactoryTest.kt | 35 --------------- 5 files changed, 15 insertions(+), 86 deletions(-) delete mode 100644 app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactory.kt delete mode 100644 app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactoryTest.kt diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeModule.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeModule.kt index 6659867..395c7ea 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeModule.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeModule.kt @@ -1,8 +1,10 @@ package gq.kirmanak.mealient.data.recipes import androidx.paging.ExperimentalPagingApi +import androidx.paging.InvalidatingPagingSourceFactory import dagger.Binds import dagger.Module +import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import gq.kirmanak.mealient.data.recipes.db.RecipeStorage @@ -12,6 +14,7 @@ import gq.kirmanak.mealient.data.recipes.impl.RecipeRepoImpl import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource import gq.kirmanak.mealient.data.recipes.network.RecipeDataSourceImpl import kotlinx.serialization.ExperimentalSerializationApi +import javax.inject.Singleton @ExperimentalPagingApi @ExperimentalSerializationApi @@ -29,4 +32,12 @@ interface RecipeModule { @Binds fun provideRecipeImageLoader(recipeImageLoaderImpl: RecipeImageLoaderImpl): RecipeImageLoader + + companion object { + @Provides + @Singleton + fun provideRecipePagingSourceFactory( + recipeStorage: RecipeStorage + ) = InvalidatingPagingSourceFactory { recipeStorage.queryRecipes() } + } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactory.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactory.kt deleted file mode 100644 index 0e7499d..0000000 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactory.kt +++ /dev/null @@ -1,45 +0,0 @@ -package gq.kirmanak.mealient.data.recipes.impl - -import androidx.paging.PagingSource -import gq.kirmanak.mealient.data.recipes.db.RecipeStorage -import gq.kirmanak.mealient.data.recipes.db.entity.RecipeSummaryEntity -import timber.log.Timber -import java.util.concurrent.ConcurrentSkipListSet -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RecipePagingSourceFactory @Inject constructor( - private val recipeStorage: RecipeStorage -) : () -> PagingSource { - private val sources: MutableSet> = - ConcurrentSkipListSet(PagingSourceComparator) - - override fun invoke(): PagingSource { - Timber.v("invoke() called") - val newSource = recipeStorage.queryRecipes() - sources.add(newSource) - return newSource - } - - fun invalidate() { - Timber.v("invalidate() called") - for (source in sources) { - if (!source.invalid) { - source.invalidate() - } - } - sources.removeAll { it.invalid } - } - - private object PagingSourceComparator : Comparator> { - override fun compare( - left: PagingSource?, - right: PagingSource? - ): Int { - val leftHash = left?.hashCode() ?: 0 - val rightHash = right?.hashCode() ?: 0 - return leftHash - rightHash - } - } -} \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt index 260dbef..5454820 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt @@ -1,6 +1,7 @@ package gq.kirmanak.mealient.data.recipes.impl import androidx.paging.ExperimentalPagingApi +import androidx.paging.InvalidatingPagingSourceFactory import androidx.paging.Pager import androidx.paging.PagingConfig import gq.kirmanak.mealient.data.recipes.RecipeRepo @@ -15,7 +16,7 @@ import javax.inject.Inject class RecipeRepoImpl @Inject constructor( private val mediator: RecipesRemoteMediator, private val storage: RecipeStorage, - private val pagingSourceFactory: RecipePagingSourceFactory, + private val pagingSourceFactory: InvalidatingPagingSourceFactory, private val dataSource: RecipeDataSource, ) : RecipeRepo { override fun createPager(): Pager { diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt index 809b0d5..e8a6e43 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt @@ -1,12 +1,9 @@ package gq.kirmanak.mealient.data.recipes.impl import androidx.annotation.VisibleForTesting -import androidx.paging.ExperimentalPagingApi -import androidx.paging.LoadType +import androidx.paging.* import androidx.paging.LoadType.PREPEND import androidx.paging.LoadType.REFRESH -import androidx.paging.PagingState -import androidx.paging.RemoteMediator import gq.kirmanak.mealient.data.recipes.db.RecipeStorage import gq.kirmanak.mealient.data.recipes.db.entity.RecipeSummaryEntity import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource @@ -18,7 +15,7 @@ import javax.inject.Inject class RecipesRemoteMediator @Inject constructor( private val storage: RecipeStorage, private val network: RecipeDataSource, - private val pagingSourceFactory: RecipePagingSourceFactory, + private val pagingSourceFactory: InvalidatingPagingSourceFactory, ) : RemoteMediator() { @VisibleForTesting diff --git a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactoryTest.kt b/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactoryTest.kt deleted file mode 100644 index 8c98a32..0000000 --- a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipePagingSourceFactoryTest.kt +++ /dev/null @@ -1,35 +0,0 @@ -package gq.kirmanak.mealient.data.recipes.impl - -import dagger.hilt.android.testing.HiltAndroidTest -import gq.kirmanak.mealient.data.recipes.db.RecipeStorage -import gq.kirmanak.mealient.test.HiltRobolectricTest -import kotlinx.coroutines.* -import org.junit.Before -import org.junit.Test -import javax.inject.Inject - -@ExperimentalCoroutinesApi -@HiltAndroidTest -class RecipePagingSourceFactoryTest : HiltRobolectricTest() { - @Inject - lateinit var storage: RecipeStorage - lateinit var subject: RecipePagingSourceFactory - - @Before - fun setUp() { - subject = RecipePagingSourceFactory(storage) - } - - @Test - fun `when modifying concurrently then doesn't throw`(): Unit = runBlocking { - (0..100).map { - async(Dispatchers.Default) { - for (i in 0..100) { - subject.invalidate() - subject.invoke() - } - } - }.awaitAll() - } - -} \ No newline at end of file