Use memorizing suppliers to considerably improve get() performance of CapabilityCache
This commit is contained in:
parent
8f9103ca48
commit
43c02b37a8
@ -348,6 +348,17 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
private var cache: BlockCapabilityCache<T, in Direction?>? = null
|
private var cache: BlockCapabilityCache<T, in Direction?>? = null
|
||||||
private val listeners = Listenable.Impl<T?>()
|
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 {
|
override fun addListener(listener: Consumer<T?>): Listenable.L {
|
||||||
return listeners.addListener(listener)
|
return listeners.addListener(listener)
|
||||||
}
|
}
|
||||||
@ -358,23 +369,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun get(): T? {
|
override fun get(): T? {
|
||||||
if (isRemoved)
|
return provider.get()
|
||||||
return null
|
|
||||||
|
|
||||||
return cache?.capability
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val isPresent: Boolean
|
val isPresent: Boolean
|
||||||
get() = cache?.capability != null
|
get() = get() != null
|
||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = cache?.capability == null
|
get() = get() == null
|
||||||
|
|
||||||
fun rebuildCache() {
|
fun rebuildCache() {
|
||||||
if (!SERVER_IS_LIVE) return
|
if (!SERVER_IS_LIVE) return
|
||||||
val level = level as? ServerLevel
|
val level = level as? ServerLevel
|
||||||
|
|
||||||
val creationVersion = ++currentVersion
|
val creationVersion = ++currentVersion
|
||||||
|
provider = lookupProvider
|
||||||
|
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
cache = null
|
cache = null
|
||||||
@ -388,12 +397,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
{ !isRemoved || creationVersion != currentVersion },
|
{ !isRemoved || creationVersion != currentVersion },
|
||||||
// IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!")
|
// IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!")
|
||||||
// what a shame.
|
// 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 {
|
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()
|
val syncher = SynchableGroup()
|
||||||
@ -424,6 +442,7 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
|
capabilityCaches.forEach { it.removeCache() }
|
||||||
unsubscribe()
|
unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user