Use memorizing suppliers to considerably improve get() performance of CapabilityCache

This commit is contained in:
DBotThePony 2025-04-05 09:58:50 +07:00
parent 8f9103ca48
commit 43c02b37a8
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -348,6 +348,17 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
private var cache: BlockCapabilityCache<T, in Direction?>? = null
private val listeners = Listenable.Impl<T?>()
private val lookupProvider = Supplier<T?> {
if (isRemoved)
return@Supplier null
val get = cache?.capability
provider = Supplier { get }
return@Supplier get
}
private var provider: Supplier<T?> = lookupProvider
override fun addListener(listener: Consumer<T?>): 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()
}