From 27fcb08588e5691b3dd419bd23603d79f0af484c Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 5 Jul 2017 22:49:25 -0700 Subject: Create kpref single --- .../ca/allanwang/kau/kotlin/LazyResettable.kt | 8 +++- .../main/kotlin/ca/allanwang/kau/kpref/KPref.kt | 5 +- .../kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt | 24 ++++++---- .../ca/allanwang/kau/kpref/KPrefSingleDelegate.kt | 53 ++++++++++++++++++++++ 4 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt (limited to 'core/src/main') diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt index f8947f3..2981dda 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt @@ -13,11 +13,11 @@ internal object UNINITIALIZED fun lazyResettable(initializer: () -> T): LazyResettable = LazyResettable(initializer) -class LazyResettable(private val initializer: () -> T, lock: Any? = null) : Lazy, Serializable { +class LazyResettable(private val initializer: () -> T, lock: Any? = null) : ILazyResettable, Serializable { @Volatile private var _value: Any = UNINITIALIZED private val lock = lock ?: this - fun invalidate() { + override fun invalidate() { _value = UNINITIALIZED } @@ -48,4 +48,8 @@ class LazyResettable(private val initializer: () -> T, lock: Any? = nul operator fun setValue(any: Any, property: KProperty<*>, t: T) { _value = t } +} + +interface ILazyResettable : Lazy { + fun invalidate() } \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt index 7fd8955..fa6c5a9 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt @@ -2,6 +2,7 @@ package ca.allanwang.kau.kpref import android.content.Context import android.content.SharedPreferences +import ca.allanwang.kau.kotlin.ILazyResettable /** * Created by Allan Wang on 2017-06-07. @@ -24,12 +25,12 @@ open class KPref { c.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE) } - internal val prefMap: MutableMap> = mutableMapOf() + internal val prefMap: MutableMap> = mutableMapOf() fun reset() { prefMap.values.forEach { it.invalidate() } } - operator fun get(key: String): KPrefDelegate<*>? = prefMap[key] + operator fun get(key: String): ILazyResettable<*>? = prefMap[key] } \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt index 4d57ff1..74792e1 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt @@ -1,17 +1,19 @@ package ca.allanwang.kau.kpref +import ca.allanwang.kau.kotlin.ILazyResettable + /** * Created by Allan Wang on 2017-06-07. */ -private object UNINITIALIZED +object UNINITIALIZED -fun KPref.kpref(key: String, fallback: Boolean, postSetter: (value: Boolean) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback, this, postSetter) -fun KPref.kpref(key: String, fallback: Double, postSetter: (value: Float) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback.toFloat(), this, postSetter) -fun KPref.kpref(key: String, fallback: Float, postSetter: (value: Float) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback, this, postSetter) -fun KPref.kpref(key: String, fallback: Int, postSetter: (value: Int) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback, this, postSetter) -fun KPref.kpref(key: String, fallback: Long, postSetter: (value: Long) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback, this, postSetter) -fun KPref.kpref(key: String, fallback: Set, postSetter: (value: Set) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, StringSet(fallback), this, postSetter) -fun KPref.kpref(key: String, fallback: String, postSetter: (value: String) -> Unit = {}): KPrefDelegate = KPrefDelegate(key, fallback, this, postSetter) +fun KPref.kpref(key: String, fallback: Boolean, postSetter: (value: Boolean) -> Unit = {}) = KPrefDelegate(key, fallback, this, postSetter) +fun KPref.kpref(key: String, fallback: Double, postSetter: (value: Float) -> Unit = {}) = KPrefDelegate(key, fallback.toFloat(), this, postSetter) +fun KPref.kpref(key: String, fallback: Float, postSetter: (value: Float) -> Unit = {}) = KPrefDelegate(key, fallback, this, postSetter) +fun KPref.kpref(key: String, fallback: Int, postSetter: (value: Int) -> Unit = {}) = KPrefDelegate(key, fallback, this, postSetter) +fun KPref.kpref(key: String, fallback: Long, postSetter: (value: Long) -> Unit = {}) = KPrefDelegate(key, fallback, this, postSetter) +fun KPref.kpref(key: String, fallback: Set, postSetter: (value: Set) -> Unit = {}) = KPrefDelegate(key, StringSet(fallback), this, postSetter) +fun KPref.kpref(key: String, fallback: String, postSetter: (value: String) -> Unit = {}) = KPrefDelegate(key, fallback, this, postSetter) class StringSet(set: Collection) : LinkedHashSet(set) @@ -20,7 +22,9 @@ class StringSet(set: Collection) : LinkedHashSet(set) * Contains a unique key for the shared preference as well as a nonnull fallback item * Also contains an optional mutable postSetter that will be called every time a new value is given */ -class KPrefDelegate internal constructor(private val key: String, private val fallback: T, private val pref: KPref, var postSetter: (value: T) -> Unit = {}, lock: Any? = null) : Lazy, java.io.Serializable { +class KPrefDelegate internal constructor( + private val key: String, private val fallback: T, private val pref: KPref, var postSetter: (value: T) -> Unit = {}, lock: Any? = null +) : ILazyResettable, java.io.Serializable { @Volatile private var _value: Any = UNINITIALIZED private val lock = lock ?: this @@ -31,7 +35,7 @@ class KPrefDelegate internal constructor(private val key: String, priva pref.prefMap.put(key, this@KPrefDelegate) } - fun invalidate() { + override fun invalidate() { _value = UNINITIALIZED } diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt new file mode 100644 index 0000000..58e570f --- /dev/null +++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt @@ -0,0 +1,53 @@ +package ca.allanwang.kau.kpref + +import ca.allanwang.kau.kotlin.ILazyResettable + +/** + * Created by Allan Wang on 2017-06-07. + */ +fun KPref.kprefSingle(key: String) = KPrefSingleDelegate(key, this) + +/** + * Singular KPref Delegate for booleans + * When the shared pref is not initialized, it will return true then set the pref to false + * All subsequent retrievals will be false + * This is useful for one time toggles such as showcasing items + */ +class KPrefSingleDelegate internal constructor(private val key: String, private val pref: KPref, lock: Any? = null) : ILazyResettable { + + @Volatile private var _value: Boolean? = null + private val lock = lock ?: this + + init { + if (pref.prefMap.containsKey(key)) + throw KPrefException("$key is already used elsewhere in preference ${pref.PREFERENCE_NAME}") + pref.prefMap.put(key, this@KPrefSingleDelegate) + } + + override fun invalidate() { + _value = null + } + + override val value: Boolean + get() { + val _v1 = _value + if (_v1 != null) + return _v1 + + return synchronized(lock) { + val _v2 = _value + if (_v2 != null) { + _v2 + } else { + _value = pref.sp.getBoolean(key, true) + if (_value!!) pref.sp.edit().putBoolean(key, false).apply() + _value!! + } + } + } + + override fun isInitialized(): Boolean = _value != null + + override fun toString(): String = if (isInitialized()) value.toString() else "Lazy kPref $key not initialized yet." + +} \ No newline at end of file -- cgit v1.2.3