Created
January 26, 2017 17:15
-
-
Save bj0/f4871f90263bc7d2a71c13f6d61710b0 to your computer and use it in GitHub Desktop.
A modified version of Kotlin's lazy delegate that can be reset.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Brian Parma on 2/10/16. | |
* | |
* This is basically just the lazy delegate copy and pasted, then modified so that it can be | |
* reset by setting it equal to null | |
*/ | |
/** | |
* Represents a value with lazy initialization. | |
* | |
* To create an instance of [Cached] use the [cached] function. | |
*/ | |
interface Cached<T> { | |
/** | |
* Gets the lazily initialized value of the current Cached instance. | |
* Once the value was initialized it must not change during the rest of lifetime of this Cached instance. | |
*/ | |
var value: T? | |
/** | |
* Returns `true` if a value for this Cached instance has a value, and `false` otherwise. | |
*/ | |
fun isCached(): Boolean | |
} | |
//@kotlin.jvm.JvmVersion | |
fun <T> cached(initializer: () -> T): Cached<T> = SynchronizedCachedImpl(initializer) | |
//@kotlin.internal.InlineOnly | |
inline operator fun <T> Cached<T>.getValue(thisRef: Any?, property: KProperty<*>): T? = value | |
inline operator fun <T> Cached<T>.setValue(thisRef: Any?, property: KProperty<*>, new_value: T?) { value = new_value } | |
private class SynchronizedCachedImpl<T>(initializer: () -> T, lock: Any? = null) : Cached<T>, Serializable { | |
private var initializer: (() -> T)? = initializer | |
@Volatile private var _value: Any? = null | |
// final field is required to enable safe publication of constructed instance | |
private val lock = lock ?: this | |
override var value: T? | |
set(new_value) { | |
synchronized(lock){ | |
_value = new_value | |
} | |
} | |
get() { | |
val _v1 = _value | |
if (_v1 !== null) { | |
return _v1 as T | |
} | |
return synchronized(lock) { | |
val _v2 = _value | |
if (_v2 !== null) { | |
_v2 as T | |
} | |
else { | |
val typedValue = initializer!!() | |
_value = typedValue | |
// initializer = null | |
typedValue | |
} | |
} | |
} | |
override fun isCached(): Boolean = _value !== null | |
override fun toString(): String = if (isCached()) value.toString() else "Cached value is not set yet." | |
// private fun writeReplace(): Any = InitializedLazyImpl(value) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment