diff --git a/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/QueueManager.kt b/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/QueueManager.kt new file mode 100644 index 000000000..567fae056 --- /dev/null +++ b/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/QueueManager.kt @@ -0,0 +1,18 @@ +package org.mobilenativefoundation.paging.core.impl + +import org.mobilenativefoundation.paging.core.PagingKey + +/** + * Represents a manager for the queue of pages to be loaded. + * + * @param K The type of the key used for paging. + * @param P The type of the parameters associated with each page of data. + */ +interface QueueManager { + /** + * Enqueues a page key to be loaded. + * + * @param key The [PagingKey] representing the page to be loaded. + */ + fun enqueue(key: PagingKey) +} diff --git a/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/RealQueueManager.kt b/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/RealQueueManager.kt new file mode 100644 index 000000000..6feef8528 --- /dev/null +++ b/paging/core/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/RealQueueManager.kt @@ -0,0 +1,59 @@ +package org.mobilenativefoundation.paging.core.impl + +import kotlinx.coroutines.flow.StateFlow +import org.mobilenativefoundation.paging.core.FetchingStrategy +import org.mobilenativefoundation.paging.core.Logger +import org.mobilenativefoundation.paging.core.PagingAction +import org.mobilenativefoundation.paging.core.PagingBuffer +import org.mobilenativefoundation.paging.core.PagingConfig +import org.mobilenativefoundation.paging.core.PagingKey + +class RealQueueManager, K : Any, P : Any, D : Any, E : Any, A : Any>( + pagingConfigInjector: Injector, + loggerInjector: OptionalInjector, + dispatcherInjector: Injector>, + private val fetchingStrategy: FetchingStrategy, + private val pagingBuffer: PagingBuffer, + private val anchorPosition: StateFlow>, + private val stateManager: StateManager, +) : QueueManager { + + private val logger = lazy { loggerInjector.inject() } + private val pagingConfig = lazy { pagingConfigInjector.inject() } + private val dispatcher = lazy { dispatcherInjector.inject() } + + private val queue: ArrayDeque> = ArrayDeque() + + override fun enqueue(key: PagingKey) { + logger.value?.log( + """ + Enqueueing: + Key: $key + """.trimIndent() + ) + + queue.addLast(key) + + processQueue() + } + + private fun processQueue() { + while (queue.isNotEmpty() && fetchingStrategy.shouldFetch( + anchorPosition = anchorPosition.value, + prefetchPosition = stateManager.state.value.prefetchPosition, + pagingConfig = pagingConfig.value, + pagingBuffer = pagingBuffer, + ) + ) { + val nextKey = queue.removeFirst() + + logger.value?.log( + """Dequeued: + Key: $nextKey + """.trimMargin(), + ) + + dispatcher.value.dispatch(PagingAction.Load(nextKey)) + } + } +} \ No newline at end of file