Skip to content

Commit 6badb8b

Browse files
Optimize usage
1 parent a22d181 commit 6badb8b

File tree

62 files changed

+713
-103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+713
-103
lines changed

datastore-ktx/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ android {
2828
kotlinOptions {
2929
jvmTarget = '1.8'
3030
freeCompilerArgs += ['-module-name', "datastore-ktx"]
31-
freeCompilerArgs += "-Xcontext-receivers"
3231
}
3332
}
3433

3534
dependencies {
3635
api "androidx.datastore:datastore-preferences:$datastoreVersion"
36+
api "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
3737
implementation "androidx.startup:startup-runtime:$startupVersion"
38-
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleLiveDataVersion"
3938
androidTestImplementation "androidx.test.ext:junit:$junitExtVersion"
4039
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4"
4140
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"

datastore-ktx/src/androidTest/java/com/dylanc/datastore/DataStoreTest.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818
package com.dylanc.datastore
1919

2020
import androidx.test.ext.junit.runners.AndroidJUnit4
21-
import kotlinx.coroutines.flow.first
2221
import kotlinx.coroutines.test.runTest
2322
import org.junit.Assert
2423
import org.junit.Test
2524
import org.junit.runner.RunWith
2625

2726
@RunWith(AndroidJUnit4::class)
28-
class DataStoreTest : DataStoreOwner {
27+
class DataStoreTest : IDataStoreOwner {
2928

3029
private val i1 by intPreference()
3130

datastore-ktx/src/main/java/com/dylanc/datastore/DataStoreInitializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import androidx.startup.Initializer
2828
class DataStoreInitializer : Initializer<Unit> {
2929

3030
override fun create(context: Context) {
31-
DataStoreOwner.application = context as Application
31+
IDataStoreOwner.application = context as Application
3232
}
3333

3434
override fun dependencies() = emptyList<Class<Initializer<*>>>()

datastore-ktx/src/main/java/com/dylanc/datastore/DataStoreOwner.kt

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,49 +24,51 @@ import androidx.datastore.core.DataStore
2424
import androidx.datastore.preferences.core.*
2525
import androidx.datastore.preferences.preferencesDataStore
2626
import kotlin.properties.ReadOnlyProperty
27+
import kotlin.properties.ReadWriteProperty
2728
import kotlin.reflect.KProperty
2829

29-
interface DataStoreOwner {
30+
open class DataStoreOwner(name: String) : IDataStoreOwner {
31+
private val Context.dataStore by preferencesDataStore(name)
32+
override val dataStore get() = context.dataStore
33+
}
34+
35+
interface IDataStoreOwner {
3036
val context: Context get() = application
3137

32-
val dataStore: DataStore<Preferences> get() = context.default()
38+
val dataStore: DataStore<Preferences>
3339

34-
fun intPreference(default: Int? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Int>> =
40+
fun intPreference(default: Int? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Int>> =
3541
PreferenceProperty(::intPreferencesKey, default)
3642

37-
fun doublePreference(default: Double? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Double>> =
43+
fun doublePreference(default: Double? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Double>> =
3844
PreferenceProperty(::doublePreferencesKey, default)
3945

40-
fun longPreference(default: Long? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Long>> =
46+
fun longPreference(default: Long? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Long>> =
4147
PreferenceProperty(::longPreferencesKey, default)
4248

43-
fun floatPreference(default: Float? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Float>> =
49+
fun floatPreference(default: Float? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Float>> =
4450
PreferenceProperty(::floatPreferencesKey, default)
4551

46-
fun booleanPreference(default: Boolean? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Boolean>> =
52+
fun booleanPreference(default: Boolean? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Boolean>> =
4753
PreferenceProperty(::booleanPreferencesKey, default)
4854

49-
fun stringPreference(default: String? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<String>> =
55+
fun stringPreference(default: String? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<String>> =
5056
PreferenceProperty(::stringPreferencesKey, default)
5157

52-
fun stringSetPreference(default: Set<String>? = null): ReadOnlyProperty<DataStoreOwner, DataStorePreference<Set<String>>> =
58+
fun stringSetPreference(default: Set<String>? = null): ReadOnlyProperty<IDataStoreOwner, DataStorePreference<Set<String>>> =
5359
PreferenceProperty(::stringSetPreferencesKey, default)
5460

5561
class PreferenceProperty<V>(
5662
private val key: (String) -> Preferences.Key<V>,
5763
private val default: V? = null,
58-
) : ReadOnlyProperty<DataStoreOwner, DataStorePreference<V>> {
64+
) : ReadOnlyProperty<IDataStoreOwner, DataStorePreference<V>> {
5965
private var cache: DataStorePreference<V>? = null
6066

61-
override fun getValue(thisRef: DataStoreOwner, property: KProperty<*>): DataStorePreference<V> =
62-
cache ?: DataStorePreferenceImpl(thisRef.dataStore, key(property.name), default).also { cache = it }
67+
override fun getValue(thisRef: IDataStoreOwner, property: KProperty<*>): DataStorePreference<V> =
68+
cache ?: DataStorePreference(thisRef.dataStore, key(property.name), default).also { cache = it }
6369
}
6470

6571
companion object {
66-
private val Context.defaultDataStore by preferencesDataStore("default")
6772
internal lateinit var application: Application
68-
69-
@JvmStatic
70-
var default: Context.() -> DataStore<Preferences> = { defaultDataStore }
7173
}
7274
}

datastore-ktx/src/main/java/com/dylanc/datastore/DataStorePreference.kt

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
@file:Suppress("unused")
17+
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
1818

1919
package com.dylanc.datastore
2020

@@ -29,31 +29,13 @@ import kotlinx.coroutines.flow.map
2929

3030
operator fun <V> Preferences.get(preference: DataStorePreference<V>) = this[preference.key]
3131

32-
interface DataStorePreference<V> {
33-
val key: Preferences.Key<V>
34-
35-
val default: V?
36-
37-
fun asFlow(): Flow<V?>
38-
39-
fun asLiveData(): LiveData<V?> = asFlow().asLiveData()
40-
41-
suspend fun get(): V? = asFlow().first()
42-
43-
suspend fun getOrDefault(): V = get() ?: throw IllegalStateException("No default value")
44-
45-
suspend fun set(block: suspend V?.(Preferences) -> V?): Preferences
46-
47-
suspend fun set(value: V?): Preferences = set { value }
48-
}
49-
50-
open class DataStorePreferenceImpl<V>(
32+
open class DataStorePreference<V>(
5133
private val dataStore: DataStore<Preferences>,
52-
override val key: Preferences.Key<V>,
53-
override val default: V?
54-
) : DataStorePreference<V> {
34+
val key: Preferences.Key<V>,
35+
open val default: V?
36+
) {
5537

56-
override suspend fun set(block: suspend V?.(Preferences) -> V?): Preferences =
38+
suspend fun set(block: suspend V?.(Preferences) -> V?): Preferences =
5739
dataStore.edit { preferences ->
5840
val value = block(preferences[key] ?: default, preferences)
5941
if (value == null) {
@@ -63,6 +45,14 @@ open class DataStorePreferenceImpl<V>(
6345
}
6446
}
6547

66-
override fun asFlow(): Flow<V?> =
48+
suspend fun set(value: V?): Preferences = set { value }
49+
50+
fun asFlow(): Flow<V?> =
6751
dataStore.data.map { it[key] ?: default }
52+
53+
fun asLiveData(): LiveData<V?> = asFlow().asLiveData()
54+
55+
suspend fun get(): V? = asFlow().first()
56+
57+
suspend fun getOrDefault(): V = get() ?: throw IllegalStateException("No default value")
6858
}

datastore-rxjava2/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ android {
2828
kotlinOptions {
2929
jvmTarget = '1.8'
3030
freeCompilerArgs += ['-module-name', "datastore-rxjava2"]
31-
freeCompilerArgs += "-Xcontext-receivers"
3231
}
3332
}
3433

3534
dependencies {
3635
api "androidx.datastore:datastore-preferences-rxjava2:$datastoreVersion"
36+
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion"
3737
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlinCoroutinesVersion"
3838
implementation project(path: ':datastore-ktx')
3939
testImplementation 'junit:junit:4.13.2'

datastore-rxjava2/src/main/java/com/dylanc/datastore/rxjava2/RxDataStoreOwner.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import androidx.datastore.core.DataStore
2222
import androidx.datastore.preferences.core.*
2323
import androidx.datastore.rxjava2.RxDataStore
2424
import com.dylanc.datastore.DataStoreOwner
25+
import com.dylanc.datastore.IDataStoreOwner
26+
import com.dylanc.datastore.rxjava2.IRxDataStoreOwner.Companion.toRxDataStore
2527
import io.reactivex.Scheduler
2628
import io.reactivex.schedulers.Schedulers
2729
import kotlinx.coroutines.CoroutineScope
@@ -30,7 +32,12 @@ import kotlinx.coroutines.rx2.asCoroutineDispatcher
3032
import kotlin.properties.ReadOnlyProperty
3133
import kotlin.reflect.KProperty
3234

33-
interface RxDataStoreOwner : DataStoreOwner {
35+
open class RxDataStoreOwner(name: String) : DataStoreOwner(name), IRxDataStoreOwner {
36+
@Suppress("LeakingThis")
37+
override val rxDataStore: RxDataStore<Preferences> by dataStore.toRxDataStore()
38+
}
39+
40+
interface IRxDataStoreOwner : IDataStoreOwner {
3441

3542
val rxDataStore: RxDataStore<Preferences>
3643

@@ -56,14 +63,14 @@ interface RxDataStoreOwner : DataStoreOwner {
5663
RxPreferenceProperty(this, ::stringSetPreferencesKey, default ?: emptySet())
5764

5865
class RxPreferenceProperty<V>(
59-
private val owner: RxDataStoreOwner,
66+
private val owner: IRxDataStoreOwner,
6067
private val key: (String) -> Preferences.Key<V>,
6168
private val default: V
62-
) : ReadOnlyProperty<DataStoreOwner, RxDataStorePreference<V>> {
69+
) : ReadOnlyProperty<IDataStoreOwner, RxDataStorePreference<V>> {
6370
private var cache: RxDataStorePreference<V>? = null
6471

65-
override fun getValue(thisRef: DataStoreOwner, property: KProperty<*>): RxDataStorePreference<V> =
66-
cache ?: RxDataStorePreferenceImpl(thisRef.dataStore, key(property.name), default, owner.rxDataStore).also { cache = it }
72+
override fun getValue(thisRef: IDataStoreOwner, property: KProperty<*>): RxDataStorePreference<V> =
73+
cache ?: RxDataStorePreference(thisRef.dataStore , key(property.name), default, owner.rxDataStore ).also { cache = it }
6774
}
6875

6976
companion object {

datastore-rxjava2/src/main/java/com/dylanc/datastore/rxjava2/RxDataStorePreference.kt

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,56 @@ import androidx.datastore.core.DataStore
66
import androidx.datastore.preferences.core.Preferences
77
import androidx.datastore.rxjava2.RxDataStore
88
import com.dylanc.datastore.DataStorePreference
9-
import com.dylanc.datastore.DataStorePreferenceImpl
109
import io.reactivex.Flowable
1110
import io.reactivex.Single
1211
import kotlinx.coroutines.ExperimentalCoroutinesApi
1312

1413
operator fun <V> Preferences.get(preference: RxDataStorePreference<V>) = this[preference.key]
1514

16-
interface RxDataStorePreference<V> : DataStorePreference<V> {
17-
fun asFlowable(): Flowable<V>
15+
@OptIn(ExperimentalCoroutinesApi::class)
16+
class RxDataStorePreference<V>(
17+
dataStore: DataStore<Preferences>,
18+
key: Preferences.Key<V>,
19+
override val default: V,
20+
private val rxDataStore: RxDataStore<Preferences>
21+
) : DataStorePreference<V>(dataStore, key, default) {
1822

19-
fun getAsync(): Single<V> = asFlowable().first(default!!)
23+
fun asFlowable(): Flowable<V> =
24+
rxDataStore.data().map { it[key] ?: default }
2025

21-
fun setAsync(block: V.(preferences: Preferences) -> V?): Single<Preferences>
26+
fun getAsync(): Single<V> = asFlowable().first(default)
27+
28+
fun setAsync(block: V.(Preferences) -> V?) =
29+
rxDataStore.updateDataAsync {
30+
val preferences = it.toMutablePreferences()
31+
val value = block(preferences[key] ?: default, preferences)
32+
if (value == null) {
33+
preferences.remove(key)
34+
} else {
35+
preferences[key] = value
36+
}
37+
Single.just(preferences)
38+
}
2239

2340
fun setAsync(value: V?): Single<Preferences> = setAsync { value }
2441
}
2542

2643
@OptIn(ExperimentalCoroutinesApi::class)
27-
class RxDataStorePreferenceImpl<V>(
44+
class RxDataStorePreference2<V>(
2845
dataStore: DataStore<Preferences>,
2946
key: Preferences.Key<V>,
3047
override val default: V,
3148
private val rxDataStore: RxDataStore<Preferences>
32-
) : DataStorePreferenceImpl<V>(dataStore, key, default), RxDataStorePreference<V> {
49+
) : DataStorePreference<V>(dataStore, key, default) {
3350

34-
override fun asFlowable(): Flowable<V> =
51+
fun asFlowable(): Flowable<V> =
3552
rxDataStore.data().map { it[key] ?: default }
3653

37-
override fun setAsync(block: V.(Preferences) -> V?) =
54+
fun getAsync(): Single<V> = asFlowable().first(default)
55+
56+
fun setAsync(value: V?): Single<Preferences> =
3857
rxDataStore.updateDataAsync {
3958
val preferences = it.toMutablePreferences()
40-
val value = block(preferences[key] ?: default, preferences)
4159
if (value == null) {
4260
preferences.remove(key)
4361
} else {

datastore-rxjava3/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ android {
2828
kotlinOptions {
2929
jvmTarget = '1.8'
3030
freeCompilerArgs += ['-module-name', "datastore-rxjava3"]
31-
freeCompilerArgs += "-Xcontext-receivers"
3231
}
3332
}
3433

3534
dependencies {
3635
api "androidx.datastore:datastore-preferences-rxjava3:$datastoreVersion"
36+
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion"
3737
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx3:$kotlinCoroutinesVersion"
3838
implementation project(path: ':datastore-ktx')
3939
testImplementation 'junit:junit:4.13.2'

datastore-rxjava3/src/main/java/com/dylanc/datastore/rxjava3/RxDataStoreOwner.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import androidx.datastore.core.DataStore
2020
import androidx.datastore.preferences.core.*
2121
import androidx.datastore.rxjava3.RxDataStore
2222
import com.dylanc.datastore.DataStoreOwner
23+
import com.dylanc.datastore.IDataStoreOwner
24+
import com.dylanc.datastore.rxjava3.IRxDataStoreOwner.Companion.toRxDataStore
2325
import io.reactivex.rxjava3.core.Scheduler
2426
import io.reactivex.rxjava3.schedulers.Schedulers
2527
import kotlinx.coroutines.CoroutineScope
@@ -28,7 +30,12 @@ import kotlinx.coroutines.rx3.asCoroutineDispatcher
2830
import kotlin.properties.ReadOnlyProperty
2931
import kotlin.reflect.KProperty
3032

31-
interface RxDataStoreOwner : DataStoreOwner {
33+
open class RxDataStoreOwner(name: String) : DataStoreOwner(name), IRxDataStoreOwner {
34+
@Suppress("LeakingThis")
35+
override val rxDataStore: RxDataStore<Preferences> by dataStore.toRxDataStore()
36+
}
37+
38+
interface IRxDataStoreOwner : IDataStoreOwner {
3239

3340
val rxDataStore: RxDataStore<Preferences>
3441

@@ -54,14 +61,14 @@ interface RxDataStoreOwner : DataStoreOwner {
5461
RxPreferenceProperty(this, ::stringSetPreferencesKey, default ?: emptySet())
5562

5663
class RxPreferenceProperty<V : Any>(
57-
private val owner: RxDataStoreOwner,
64+
private val owner: IRxDataStoreOwner,
5865
private val key: (String) -> Preferences.Key<V>,
5966
private val default: V
60-
) : ReadOnlyProperty<DataStoreOwner, RxDataStorePreference<V>> {
67+
) : ReadOnlyProperty<IDataStoreOwner, RxDataStorePreference<V>> {
6168
private var cache: RxDataStorePreference<V>? = null
6269

63-
override fun getValue(thisRef: DataStoreOwner, property: KProperty<*>): RxDataStorePreference<V> =
64-
cache ?: RxDataStorePreferenceImpl(thisRef.dataStore, key(property.name), default, owner.rxDataStore).also { cache = it }
70+
override fun getValue(thisRef: IDataStoreOwner, property: KProperty<*>): RxDataStorePreference<V> =
71+
cache ?: RxDataStorePreference(thisRef.dataStore , key(property.name), default, owner.rxDataStore ).also { cache = it }
6572
}
6673

6774
companion object {

0 commit comments

Comments
 (0)