even more optimize synchronizeToPlayers

This commit is contained in:
DBotThePony 2022-09-30 00:04:16 +07:00
parent 177a380bf3
commit 8892487394
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -30,7 +30,13 @@ import java.lang.ref.WeakReference
import java.util.LinkedList import java.util.LinkedList
import java.util.WeakHashMap import java.util.WeakHashMap
private data class Subscribers(val blockEntities: LinkedList<WeakReference<BlockEntity>> = LinkedList(), val players: LinkedList<ServerPlayer> = LinkedList(), val level: WeakReference<Level>, val chunkPos: Long) { private data class Subscribers(
val blockEntities: LinkedList<WeakReference<BlockEntity>> = LinkedList(),
val players: LinkedList<ServerPlayer> = LinkedList(),
val level: WeakReference<Level>,
val chunkPos: Long,
var changeset: Int = 0
) {
fun cleanUpBlocks() { fun cleanUpBlocks() {
val listIterator = blockEntities.listIterator() val listIterator = blockEntities.listIterator()
@ -49,6 +55,7 @@ private data class Subscribers(val blockEntities: LinkedList<WeakReference<Block
} }
blockEntities.add(WeakReference(blockEntity)) blockEntities.add(WeakReference(blockEntity))
changeset++
} }
fun unsubscribe(blockEntity: BlockEntity): Boolean { fun unsubscribe(blockEntity: BlockEntity): Boolean {
@ -57,6 +64,7 @@ private data class Subscribers(val blockEntities: LinkedList<WeakReference<Block
for (value in listIterator) { for (value in listIterator) {
if (value.get() === blockEntity) { if (value.get() === blockEntity) {
listIterator.remove() listIterator.remove()
changeset++
break break
} }
} }
@ -106,17 +114,20 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
playerMap.get(level)?.remove(subCache.chunkPos) playerMap.get(level)?.remove(subCache.chunkPos)
} }
} }
lastSubscriptionChangeset = -1
} }
private fun subscribe(): LinkedList<ServerPlayer> { private fun subscribe(): Subscribers {
unsubscribe() unsubscribe()
val subs = playerMap.computeIfAbsent(level) { Long2ObjectAVLTreeMap() }.computeIfAbsent(ChunkPos(blockPos).toLong(), Long2ObjectFunction { Subscribers(level = WeakReference(level), chunkPos = ChunkPos(blockPos).toLong()) }) val subs = playerMap.computeIfAbsent(level) { Long2ObjectAVLTreeMap() }.computeIfAbsent(ChunkPos(blockPos).toLong(), Long2ObjectFunction { Subscribers(level = WeakReference(level), chunkPos = ChunkPos(blockPos).toLong()) })
subs.subscribe(this) subs.subscribe(this)
_subCache = subs _subCache = subs
return subs.players return subs
} }
private val playerSubscribers get() = _subCache?.players ?: subscribe() private val subscription get() = _subCache ?: subscribe()
private var lastSubscriptionChangeset = -1
fun synchronizeToPlayers() { fun synchronizeToPlayers() {
if (synchronizationRadius <= 0.0 || synchronizer.isEmpty) { if (synchronizationRadius <= 0.0 || synchronizer.isEmpty) {
@ -127,10 +138,14 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
synchronizer.observe() synchronizer.observe()
if (playerSubscribers.isEmpty()) { val subscription = subscription
if (subscription.players.isEmpty() || lastSubscriptionChangeset == subscription.changeset && !synchronizer.hasChanges) {
return return
} }
lastSubscriptionChangeset = subscription.changeset
val (xi, yi, zi) = blockPos val (xi, yi, zi) = blockPos
val bx = xi + 0.5 val bx = xi + 0.5
val by = yi + 0.5 val by = yi + 0.5
@ -138,7 +153,7 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
val double = synchronizationRadius * synchronizationRadius val double = synchronizationRadius * synchronizationRadius
playerSubscribers.stream().filter { subscription.players.stream().filter {
if (!it.isAlive) { if (!it.isAlive) {
return@filter false return@filter false
} }
@ -191,6 +206,7 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
LOGGER.error("Player ${event.player} started 'watching' chunk ${event.chunk} more than once.") LOGGER.error("Player ${event.player} started 'watching' chunk ${event.chunk} more than once.")
} else { } else {
players.add(event.player) players.add(event.player)
it.changeset++
} }
} }
} }
@ -201,6 +217,8 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
if (subs.players.remove(event.player)) { if (subs.players.remove(event.player)) {
if (subs.isEmpty) { if (subs.isEmpty) {
playerMap.get(event.level)?.remove(event.pos.toLong()) playerMap.get(event.level)?.remove(event.pos.toLong())
} else {
subs.changeset++
} }
} else { } else {
LOGGER.error("Player ${event.player} stopped 'watching' chunk at ${event.pos} before starting to watch it/stopped 'watching' more than once.") LOGGER.error("Player ${event.player} stopped 'watching' chunk at ${event.pos} before starting to watch it/stopped 'watching' more than once.")
@ -217,6 +235,7 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
for (value in listIterator) { for (value in listIterator) {
if (value === event.entity) { if (value === event.entity) {
listIterator.remove() listIterator.remove()
entry.value.changeset++
} }
} }