melatonina
09/09/2020, 3:17 PMfind
look up into the scope of the parent objects? Is there scope inheritance?melatonina
09/09/2020, 5:38 PMmelatonina
09/09/2020, 9:29 PMpackage com.aeyeonmovement.tornadofx
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KClass
import tornadofx.Component
import tornadofx.Scope
import tornadofx.find
class InheritingScope(val parent: Scope? = null) : Scope() {
companion object {
fun from(vararg instances : Any) =
InheritingScope().apply { put(*instances) }
}
private val map = mutableMapOf<KClass<*>, Any>()
fun put(type: KClass<*>, instance: Any) {
map[type] = instance
}
inline fun <reified T : Any> put(instance: T) =
put(T::class, instance)
fun put(vararg instances: Any) =
instances.forEach { put(it::class, it) }
@Suppress("UNCHECKED_CAST")
fun tryGetLocally0(type: KClass<*>) : Any? =
map[type]
@Suppress("UNCHECKED_CAST")
fun <T : Any> tryGetLocally(type: KClass<T>) : T? =
tryGetLocally0(type) as? T
fun tryGetInParent(type: KClass<*>) =
if (parent is InheritingScope) {
parent.tryGet(type)
} else {
null
}
@Suppress("UNCHECKED_CAST")
fun <T: Component> tryGetComponentInParent(type: KClass<T>) : T? =
if (parent is InheritingScope) {
parent.tryGet(type) as? T
} else if (parent != null) {
find(type, parent)
} else {
null
}
fun tryGet(type: KClass<*>) : Any? =
tryGetLocally(type) ?: tryGetInParent(type)
inline fun <reified T: Component> tryGetComponent(type: KClass<T>) : T? =
tryGetLocally(type) ?: tryGetComponentInParent(type)
inline fun <reified T : Any> tryGet() = tryGet(T::class) as? T
inline fun <reified T : Component> tryGetComponent() = tryGetComponent(T::class)
fun subscope() =
InheritingScope(this)
fun subscope(vararg instances : Any) =
subscope().apply { put(*instances) }
}
val Component.inheritingScope get() = scope as InheritingScope
inline fun <reified T : Any> inheritingInjection() =
object : ReadOnlyProperty<Component, T> {
override fun getValue(thisRef: Component, property: KProperty<*>): T =
thisRef.inheritingScope.tryGet<T>() ?: throw Exception("Value not set for type ${T::class.java}")
}
inline fun <reified T : Component> inheritingComponentInjection()=
object : ReadOnlyProperty<Component, T> {
override fun getValue(thisRef: Component, property: KProperty<*>): T =
thisRef.inheritingScope.tryGetComponent<T>() ?: throw Exception("Value not set for type ${T::class.java}")
}
fun Scope.inheritingScope(vararg instances: Any) =
InheritingScope(this).apply { put(*instances) }