diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt index 2dcac2393..02909696a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt @@ -348,6 +348,17 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state private var cache: BlockCapabilityCache? = null private val listeners = Listenable.Impl() + private val lookupProvider = Supplier { + if (isRemoved) + return@Supplier null + + val get = cache?.capability + provider = Supplier { get } + return@Supplier get + } + + private var provider: Supplier = lookupProvider + override fun addListener(listener: Consumer): Listenable.L { return listeners.addListener(listener) } @@ -358,23 +369,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state } override fun get(): T? { - if (isRemoved) - return null - - return cache?.capability + return provider.get() } val isPresent: Boolean - get() = cache?.capability != null + get() = get() != null val isEmpty: Boolean - get() = cache?.capability == null + get() = get() == null fun rebuildCache() { if (!SERVER_IS_LIVE) return val level = level as? ServerLevel val creationVersion = ++currentVersion + provider = lookupProvider if (level == null) { cache = null @@ -388,12 +397,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state { !isRemoved || creationVersion != currentVersion }, // IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!") // what a shame. - { if (SERVER_IS_LIVE) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) } }) + { + provider = lookupProvider + if (SERVER_IS_LIVE) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(get()) } + }) onceServer { - if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) + if (!isRemoved && creationVersion == currentVersion) listeners.accept(get()) } } + + fun removeCache() { + cache = null + currentVersion++ + provider = Supplier { null } + } } val syncher = SynchableGroup() @@ -424,6 +442,7 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state override fun setRemoved() { super.setRemoved() + capabilityCaches.forEach { it.removeCache() } unsubscribe() }