From 8892487394db557ef7efd91ac830624dc43d51b7 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 30 Sep 2022 00:04:16 +0700 Subject: [PATCH] even more optimize synchronizeToPlayers --- .../block/entity/SynchronizedBlockEntity.kt | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt index 4ac583892..b837f7629 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt @@ -30,7 +30,13 @@ import java.lang.ref.WeakReference import java.util.LinkedList import java.util.WeakHashMap -private data class Subscribers(val blockEntities: LinkedList> = LinkedList(), val players: LinkedList = LinkedList(), val level: WeakReference, val chunkPos: Long) { +private data class Subscribers( + val blockEntities: LinkedList> = LinkedList(), + val players: LinkedList = LinkedList(), + val level: WeakReference, + val chunkPos: Long, + var changeset: Int = 0 +) { fun cleanUpBlocks() { val listIterator = blockEntities.listIterator() @@ -49,6 +55,7 @@ private data class Subscribers(val blockEntities: LinkedList, p_155229_: playerMap.get(level)?.remove(subCache.chunkPos) } } + + lastSubscriptionChangeset = -1 } - private fun subscribe(): LinkedList { + private fun subscribe(): Subscribers { unsubscribe() val subs = playerMap.computeIfAbsent(level) { Long2ObjectAVLTreeMap() }.computeIfAbsent(ChunkPos(blockPos).toLong(), Long2ObjectFunction { Subscribers(level = WeakReference(level), chunkPos = ChunkPos(blockPos).toLong()) }) subs.subscribe(this) _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() { if (synchronizationRadius <= 0.0 || synchronizer.isEmpty) { @@ -127,10 +138,14 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: synchronizer.observe() - if (playerSubscribers.isEmpty()) { + val subscription = subscription + + if (subscription.players.isEmpty() || lastSubscriptionChangeset == subscription.changeset && !synchronizer.hasChanges) { return } + lastSubscriptionChangeset = subscription.changeset + val (xi, yi, zi) = blockPos val bx = xi + 0.5 val by = yi + 0.5 @@ -138,7 +153,7 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: val double = synchronizationRadius * synchronizationRadius - playerSubscribers.stream().filter { + subscription.players.stream().filter { if (!it.isAlive) { 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.") } else { 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.isEmpty) { playerMap.get(event.level)?.remove(event.pos.toLong()) + } else { + subs.changeset++ } } else { 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) { if (value === event.entity) { listIterator.remove() + entry.value.changeset++ } }