selector docs and several refactorings

This commit is contained in:
InsanusMokrassar 2020-12-14 19:36:07 +06:00
parent 12e37184e1
commit 80bc226ee1

View File

@ -3,6 +3,9 @@ package dev.inmo.micro_utils.selector
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
/**
* Unified interface which can be used in any system which require some selection functionality
*/
interface Selector<T> {
val selectedItems: List<T>
val itemSelected: SharedFlow<T>
@ -16,9 +19,18 @@ inline operator fun <T> Selector<T>.contains(element: T) = selectedItems.contain
@Suppress("NOTHING_TO_INLINE")
inline fun <T> Selector<T>.nothingSelected(): Boolean = selectedItems.isEmpty()
/**
* Realization of [Selector] with one or without selected element. This realization will always have empty
* [selectedItems] when nothing selected and one element in [selectedItems] when something selected. Contains
* [selectedItem] value for simple access to currently selected item.
*
* On calling of [toggleSelection] previous selection will be erased and [itemUnselected] will emit this element.
*
* @param safeChanges Set to false to disable using of [mutex] for synchronizing changes on [toggleSelection]
*/
class SingleSelector<T>(
selectedItem: T? = null,
useMutex: Boolean = true
safeChanges: Boolean = true
) : Selector<T> {
var selectedItem: T? = selectedItem
private set
@ -30,7 +42,7 @@ class SingleSelector<T>(
private val _itemUnselected = MutableSharedFlow<T>()
override val itemUnselected: SharedFlow<T> = _itemUnselected.asSharedFlow()
private val mutex = if (useMutex) {
private val mutex = if (safeChanges) {
Mutex()
} else {
null
@ -54,9 +66,15 @@ class SingleSelector<T>(
}
}
/**
* Realization of [Selector] with multiple selected elements. On calling of [toggleSelection] this realization will select passed element OR deselect it if it is already in
* [selectedItems]
*
* @param safeChanges Set to false to disable using of [mutex] for synchronizing changes on [toggleSelection]
*/
class MultipleSelector<T>(
selectedItems: List<T>,
useMutex: Boolean = true
selectedItems: List<T> = emptyList(),
safeChanges: Boolean = true
) : Selector<T> {
private val _selectedItems: MutableList<T> = selectedItems.toMutableList()
override val selectedItems: List<T> = _selectedItems
@ -66,7 +84,7 @@ class MultipleSelector<T>(
private val _itemUnselected = MutableSharedFlow<T>()
override val itemUnselected: SharedFlow<T> = _itemUnselected.asSharedFlow()
private val mutex = if (useMutex) {
private val mutex = if (safeChanges) {
Mutex()
} else {
null
@ -83,3 +101,13 @@ class MultipleSelector<T>(
mutex ?.unlock()
}
}
@Suppress("FunctionName", "NOTHING_TO_INLINE")
inline fun <T> Selector(
multiple: Boolean,
safeChanges: Boolean = true
): Selector<T> = if (multiple) {
MultipleSelector(safeChanges = safeChanges)
} else {
SingleSelector(safeChanges = safeChanges)
}