Skip to content

Commit 87db7e0

Browse files
committed
improve PylonEntityHolderBlock, some packet entity fixes, octree iterator
1 parent 71cc5ff commit 87db7e0

File tree

6 files changed

+79
-29
lines changed

6 files changed

+79
-29
lines changed

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/BlockStorage.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ object BlockStorage : Listener {
543543
blocksByKey[block.key]!!.add(phantomBlock)
544544
blocksByChunk[block.block.chunk.position]!!.remove(block)
545545
blocksByChunk[block.block.chunk.position]!!.add(phantomBlock)
546+
BlockTextureEngine.remove(block)
546547
}
547548

548549
@JvmSynthetic

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/base/PylonEntityHolderBlock.kt

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
package io.github.pylonmc.pylon.core.block.base
22

3+
import io.github.pylonmc.pylon.core.block.BlockStorage
4+
import io.github.pylonmc.pylon.core.block.PhantomBlock
35
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
46
import io.github.pylonmc.pylon.core.entity.EntityStorage
57
import io.github.pylonmc.pylon.core.entity.PylonEntity
8+
import io.github.pylonmc.pylon.core.event.PylonBlockBreakEvent
69
import io.github.pylonmc.pylon.core.event.PylonBlockDeserializeEvent
710
import io.github.pylonmc.pylon.core.event.PylonBlockSerializeEvent
811
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
12+
import io.github.pylonmc.pylon.core.util.position.position
913
import io.github.pylonmc.pylon.core.util.pylonKey
1014
import org.bukkit.Bukkit
11-
import org.bukkit.Keyed
12-
import org.bukkit.entity.BlockDisplay
15+
import org.bukkit.block.Block
1316
import org.bukkit.entity.Entity
14-
import org.bukkit.entity.ItemDisplay
1517
import org.bukkit.event.EventHandler
1618
import org.bukkit.event.Listener
19+
import org.bukkit.event.entity.EntityRemoveEvent
1720
import org.jetbrains.annotations.ApiStatus
18-
import org.jetbrains.annotations.MustBeInvokedByOverriders
1921
import java.util.IdentityHashMap
2022
import java.util.UUID
2123

@@ -26,14 +28,16 @@ import java.util.UUID
2628
*
2729
* Note that the Pylon entities may not be loaded at the same time that the block is loaded.
2830
*/
29-
interface PylonEntityHolderBlock : PylonBreakHandler {
31+
interface PylonEntityHolderBlock {
32+
val block: Block
3033

3134
@get:ApiStatus.NonExtendable
3235
val heldEntities: MutableMap<String, UUID>
3336
get() = holders.getOrPut(this) { mutableMapOf() }
3437

3538
fun addEntity(name: String, entity: Entity) {
3639
heldEntities[name] = entity.uniqueId
40+
entity.persistentDataContainer.set(blockKey, PylonSerializers.BLOCK_POSITION, block.position)
3741
}
3842

3943
fun addEntity(name: String, entity: PylonEntity<*>)
@@ -92,17 +96,10 @@ interface PylonEntityHolderBlock : PylonBreakHandler {
9296
@ApiStatus.NonExtendable
9397
fun areAllHeldEntitiesLoaded() = heldEntities.keys.all { isHeldEntityPresent(it) }
9498

95-
@MustBeInvokedByOverriders
96-
override fun postBreak() {
97-
// Best-effort removal; unlikely to cause issues
98-
for (name in heldEntities.keys) {
99-
getHeldEntity(name)?.remove()
100-
}
101-
}
102-
10399
@ApiStatus.Internal
104100
companion object : Listener {
105101
private val entityKey = pylonKey("entity_holder_entity_uuids")
102+
private val blockKey = pylonKey("entity_holder_block")
106103
private val entityType = PylonSerializers.MAP.mapTypeFrom(PylonSerializers.STRING, PylonSerializers.UUID)
107104

108105
private val holders = IdentityHashMap<PylonEntityHolderBlock, MutableMap<String, UUID>>()
@@ -128,5 +125,29 @@ interface PylonEntityHolderBlock : PylonBreakHandler {
128125
if (block !is PylonEntityHolderBlock) return
129126
holders.remove(block)
130127
}
128+
129+
@EventHandler
130+
private fun onBreak(event: PylonBlockBreakEvent) {
131+
val block = event.pylonBlock
132+
if (block is PylonEntityHolderBlock) {
133+
// Best-effort removal; unlikely to cause issues
134+
block.heldEntities.values.forEach {
135+
Bukkit.getEntity(it)?.let { if (it.isValid) it.remove() }
136+
}
137+
holders.remove(block)
138+
} else if (block is PhantomBlock) {
139+
block.pdc.get(entityKey, entityType)?.values?.forEach {
140+
Bukkit.getEntity(it)?.let { if (it.isValid) it.remove() }
141+
}
142+
}
143+
}
144+
145+
@EventHandler
146+
private fun onEntityRemove(event: EntityRemoveEvent) {
147+
if (event.cause == EntityRemoveEvent.Cause.UNLOAD || event.cause == EntityRemoveEvent.Cause.PLAYER_QUIT) return
148+
val blockPos = event.entity.persistentDataContainer.get(blockKey, PylonSerializers.BLOCK_POSITION) ?: return
149+
val block = BlockStorage.get(blockPos) as? PylonEntityHolderBlock ?: return
150+
holders[block]?.entries?.removeIf { it.value == event.entity.uniqueId }
151+
}
131152
}
132153
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/base/PylonTickingBlock.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.github.pylonmc.pylon.core.block.base
22

33
import io.github.pylonmc.pylon.core.config.PylonConfig
44
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
5+
import io.github.pylonmc.pylon.core.event.PylonBlockBreakEvent
56
import io.github.pylonmc.pylon.core.event.PylonBlockDeserializeEvent
67
import io.github.pylonmc.pylon.core.event.PylonBlockSerializeEvent
78
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
@@ -96,5 +97,13 @@ interface PylonTickingBlock {
9697
tickingBlocks.remove(block)
9798
}
9899
}
100+
101+
@EventHandler
102+
private fun onBreak(event: PylonBlockBreakEvent) {
103+
val block = event.pylonBlock
104+
if (block is PylonTickingBlock) {
105+
tickingBlocks.remove(block)
106+
}
107+
}
99108
}
100109
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/content/fluid/FluidPipeConnector.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.pylonmc.pylon.core.content.fluid
22

33
import io.github.pylonmc.pylon.core.block.PylonBlock
4+
import io.github.pylonmc.pylon.core.block.base.PylonBreakHandler
45
import io.github.pylonmc.pylon.core.block.base.PylonEntityHolderBlock
56
import io.github.pylonmc.pylon.core.block.context.BlockBreakContext
67
import io.github.pylonmc.pylon.core.block.context.BlockBreakContext.PlayerBreak
@@ -22,7 +23,7 @@ import org.jetbrains.annotations.ApiStatus
2223
* on pipe corners/junctions.
2324
*/
2425
@ApiStatus.Internal
25-
class FluidPipeConnector : PylonBlock, PylonEntityHolderBlock {
26+
class FluidPipeConnector : PylonBlock, PylonEntityHolderBlock, PylonBreakHandler {
2627

2728
@Suppress("unused")
2829
constructor(block: Block, context: BlockCreateContext) : super(block) {
@@ -47,8 +48,6 @@ class FluidPipeConnector : PylonBlock, PylonEntityHolderBlock {
4748
// can be null if called from two different location (eg two different connection points removing the display)
4849
pipeDisplay?.delete(true, player, drops)
4950
}
50-
51-
super<PylonEntityHolderBlock>.onBreak(drops, context)
5251
}
5352

5453
override fun getWaila(player: Player): WailaConfig?

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/resourcepack/block/BlockTextureEngine.kt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ object BlockTextureEngine : Listener {
143143
while (true) {
144144
val player = Bukkit.getPlayer(uuid)
145145
if (player == null || !player.hasCustomBlockTextures) {
146-
visible.forEach { it.blockTextureEntity?.removeViewer(uuid) }
147-
visible.clear()
146+
octrees.values.forEach { it.forEach { b -> b.blockTextureEntity?.removeViewer(uuid) } }
148147
jobs.remove(uuid)
149148
break
150149
}
@@ -264,15 +263,6 @@ object BlockTextureEngine : Listener {
264263
occludingCache.remove(ChunkPosition(event.chunk))
265264
}
266265

267-
@EventHandler(priority = EventPriority.MONITOR)
268-
private fun onPlayerQuit(event: PlayerQuitEvent) {
269-
jobs.remove(event.player.uniqueId)?.let {
270-
if (it.isActive) {
271-
it.cancel()
272-
}
273-
}
274-
}
275-
276266
private data class ChunkData(
277267
var timestamp: Long,
278268
val occluding: LoadingCache<BlockPosition, Boolean> = Caffeine.newBuilder()

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/util/Octree.kt

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ open class Octree<N>(
1111
private val bounds: BoundingBox,
1212
private val depth: Int,
1313
private val entryStrategy: (N) -> BoundingBox,
14-
) {
14+
) : Iterable<N> {
1515
private var entries: MutableList<N> = CopyOnWriteArrayList()
1616
private var children: Array<Octree<N>>? = null
1717

@@ -35,7 +35,7 @@ open class Octree<N>(
3535
}
3636
}
3737

38-
if (entries.size < DEFAULT_MAX_ENTRIES || depth >= DEFAULT_MAX_DEPTH) {
38+
if (entries.size < maxEntries || depth >= maxDepth) {
3939
entries.add(entry)
4040
return true
4141
}
@@ -127,9 +127,39 @@ open class Octree<N>(
127127
return children?.maxOfOrNull { it.maxDepth() } ?: depth
128128
}
129129

130+
override fun iterator(): Iterator<N> = OctreeIterator(this)
131+
130132
companion object {
131133
// LISTEN IF THESE ARE INSANE FIX THEM, THIS ISN'T MY STRONG SUIT - JustAHuman
132134
private const val DEFAULT_MAX_DEPTH = 2048
133135
private const val DEFAULT_MAX_ENTRIES = 128
134136
}
137+
138+
private class OctreeIterator<N>(root: Octree<N>) : Iterator<N> {
139+
private val stack = ArrayDeque<Octree<N>>()
140+
private var currentEntries: Iterator<N>? = null
141+
142+
init {
143+
stack.add(root)
144+
}
145+
146+
override fun hasNext(): Boolean {
147+
while (true) {
148+
if (currentEntries?.hasNext() == true) {
149+
return true
150+
}
151+
if (stack.isEmpty()) {
152+
return false
153+
}
154+
val node = stack.removeLast()
155+
currentEntries = node.entries.iterator()
156+
node.children?.let { stack.addAll(it) }
157+
}
158+
}
159+
160+
override fun next(): N {
161+
if (!hasNext()) throw NoSuchElementException()
162+
return currentEntries!!.next()
163+
}
164+
}
135165
}

0 commit comments

Comments
 (0)