package com.github.libretube.api import java.util.* import kotlin.reflect.KProperty class ResettableLazyManager { // we synchronize to make sure the timing of a reset() call and new inits do not collide private val managedDelegates = LinkedList() fun register(managed: Resettable) { synchronized(managedDelegates) { managedDelegates.add(managed) } } fun reset() { synchronized(managedDelegates) { managedDelegates.forEach { it.reset() } managedDelegates.clear() } } } interface Resettable { fun reset() } class ResettableLazy(val manager: ResettableLazyManager, val init: () -> PROPTYPE) : Resettable { @Volatile var lazyHolder = makeInitBlock() operator fun getValue(thisRef: Any?, property: KProperty<*>): PROPTYPE { return lazyHolder.value } override fun reset() { lazyHolder = makeInitBlock() } private fun makeInitBlock(): Lazy { return lazy { manager.register(this) init() } } } fun resettableLazy( manager: ResettableLazyManager, init: () -> PROPTYPE ): ResettableLazy { return ResettableLazy(manager, init) } fun resettableManager(): ResettableLazyManager = ResettableLazyManager()