Skip to content

Commit defea60

Browse files
authored
Merge pull request #660 from pylonmc/human/performance-and-misc-stuff
Performance Improvements & Bug Fixes
2 parents da3ab3b + 070c2d5 commit defea60

57 files changed

Lines changed: 423 additions & 233 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

nms/src/main/kotlin/io/github/pylonmc/rebar/i18n/packet/PlayerPacketHandler.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package io.github.pylonmc.rebar.i18n.packet
55
import io.github.pylonmc.rebar.Rebar
66
import io.github.pylonmc.rebar.i18n.PlayerTranslationHandler
77
import io.github.pylonmc.rebar.item.RebarItem
8+
import io.github.pylonmc.rebar.item.RebarItemSchema
89
import io.github.pylonmc.rebar.util.editData
910
import io.netty.channel.ChannelDuplexHandler
1011
import io.netty.channel.ChannelHandlerContext
@@ -245,8 +246,8 @@ class PlayerPacketHandler(private val player: ServerPlayer, val handler: PlayerT
245246
private fun reset(stack: ItemStack): ItemStack {
246247
if (stack.isEmpty) return stack
247248
val bukkitStack = CraftItemStack.asCraftMirror(stack)
248-
val item = RebarItem.fromStack(bukkitStack) ?: return stack
249-
val prototype = item.schema.getItemStack()
249+
val schema = RebarItemSchema.fromStack(bukkitStack) ?: return stack
250+
val prototype = schema.getItemStack()
250251
prototype.copyDataFrom(bukkitStack) { it != DataComponentTypes.ITEM_NAME && it != DataComponentTypes.LORE }
251252
prototype.editPersistentDataContainer { it.remove(PlayerTranslationHandler.FOOTER_APPENDED) }
252253
prototype.amount = bukkitStack.amount

nms/src/main/kotlin/io/github/pylonmc/rebar/nms/NmsAccessorImpl.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import org.bukkit.block.Block
2424
import org.bukkit.craftbukkit.CraftEquipmentSlot
2525
import org.bukkit.craftbukkit.CraftWorld
2626
import org.bukkit.craftbukkit.block.CraftBlock
27+
import org.bukkit.craftbukkit.entity.CraftEntity
2728
import org.bukkit.craftbukkit.entity.CraftLivingEntity
2829
import org.bukkit.craftbukkit.entity.CraftPlayer
2930
import org.bukkit.craftbukkit.inventory.CraftItemStack
3031
import org.bukkit.craftbukkit.inventory.CraftItemType
3132
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
3233
import org.bukkit.craftbukkit.util.CraftNamespacedKey
34+
import org.bukkit.entity.Entity
3335
import org.bukkit.entity.LivingEntity
3436
import org.bukkit.entity.Player
3537
import org.bukkit.inventory.EquipmentSlot
@@ -141,4 +143,9 @@ object NmsAccessorImpl : NmsAccessor {
141143
}
142144
}
143145
}
146+
147+
override fun hasTracker(entity: Entity): Boolean {
148+
val id = entity.entityId
149+
return (entity.world as CraftWorld).handle.chunkSource.chunkMap.entityMap.get(id)?.seenBy?.isNotEmpty() ?: false
150+
}
144151
}

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/BlockStorage.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ object BlockStorage : Listener {
8282

8383
@JvmStatic
8484
val loadedBlockPositions: Set<BlockPosition>
85-
get() = lockBlockRead { blocks.keys }
85+
get() = lockBlockRead { blocks.keys.toSet() }
8686

8787
@JvmStatic
8888
val loadedChunks: Set<ChunkPosition>
89-
get() = lockBlockRead { blocksByChunk.keys }
89+
get() = lockBlockRead { blocksByChunk.keys.toSet() }
9090

9191
@JvmStatic
9292
val loadedRebarBlocks: Collection<RebarBlock>
93-
get() = lockBlockRead { blocks.values }
93+
get() = lockBlockRead { blocks.values.toSet() }
9494

9595
/**
9696
* Returns the Rebar block at the given [blockPosition], or null if the block does not exist
@@ -189,7 +189,7 @@ object BlockStorage : Listener {
189189
@JvmStatic
190190
fun getByChunk(chunkPosition: ChunkPosition): Collection<RebarBlock> {
191191
require(chunkPosition.isLoaded) { "You can only get Rebar blocks in loaded chunks" }
192-
return lockBlockRead { blocksByChunk[chunkPosition].orEmpty() }
192+
return lockBlockRead { blocksByChunk[chunkPosition].orEmpty().toSet() }
193193
}
194194

195195
/**
@@ -199,7 +199,7 @@ object BlockStorage : Listener {
199199
fun getByKey(key: NamespacedKey): Collection<RebarBlock> =
200200
if (RebarRegistry.BLOCKS.contains(key)) {
201201
lockBlockRead {
202-
blocksByKey[key].orEmpty()
202+
blocksByKey[key].orEmpty().toSet()
203203
}
204204
} else {
205205
emptySet()

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarFluidBufferBlock.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.github.pylonmc.rebar.event.RebarBlockDeserializeEvent
55
import io.github.pylonmc.rebar.event.RebarBlockSerializeEvent
66
import io.github.pylonmc.rebar.event.RebarBlockUnloadEvent
77
import io.github.pylonmc.rebar.fluid.RebarFluid
8+
import io.github.pylonmc.rebar.util.FLUID_EPSILON
89
import io.github.pylonmc.rebar.util.rebarKey
910
import org.bukkit.event.EventHandler
1011
import org.bukkit.event.Listener
@@ -93,7 +94,7 @@ interface RebarFluidBufferBlock : RebarFluidBlock {
9394
* the corresponding buffer.
9495
*/
9596
fun canSetFluid(fluid: RebarFluid, amount: Double): Boolean
96-
= amount >= 0 && amount <= fluidData(fluid).capacity + 1.0e-6
97+
= amount >= 0 && amount <= fluidData(fluid).capacity + FLUID_EPSILON
9798

9899
/**
99100
* Sets a fluid buffer only if the new amount of fluid is greater

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarFluidTank.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.github.pylonmc.rebar.event.RebarBlockDeserializeEvent
55
import io.github.pylonmc.rebar.event.RebarBlockSerializeEvent
66
import io.github.pylonmc.rebar.event.RebarBlockUnloadEvent
77
import io.github.pylonmc.rebar.fluid.RebarFluid
8+
import io.github.pylonmc.rebar.util.FLUID_EPSILON
89
import io.github.pylonmc.rebar.util.rebarKey
910
import org.bukkit.event.EventHandler
1011
import org.bukkit.event.Listener
@@ -71,7 +72,7 @@ interface RebarFluidTank : RebarFluidBlock {
7172
* Sets the capacity of the fluid tank
7273
*/
7374
fun setCapacity(capacity: Double) {
74-
check(capacity > -1.0e-6)
75+
check(capacity > -FLUID_EPSILON)
7576
fluidData.capacity = max(0.0, capacity)
7677
}
7778

@@ -80,7 +81,7 @@ interface RebarFluidTank : RebarFluidBlock {
8081
* the tank.
8182
*/
8283
fun canSetFluid(amount: Double): Boolean
83-
= amount > -1.0e-6 && amount < fluidData.capacity + 1.0e-6
84+
= amount > -FLUID_EPSILON && amount < fluidData.capacity + FLUID_EPSILON
8485

8586
/**
8687
* Checks if adding a certain amount of fluid would result in a valid
@@ -107,7 +108,7 @@ interface RebarFluidTank : RebarFluidBlock {
107108
val original = fluidData.amount
108109
fluidData.amount = max(0.0, amount)
109110

110-
if (original > amount && amount < 1.0e-6) {
111+
if (original > amount && amount < FLUID_EPSILON) {
111112
setFluidType(null)
112113
setFluid(0.0)
113114
}
@@ -144,7 +145,7 @@ interface RebarFluidTank : RebarFluidBlock {
144145
val fluidData = this.fluidData // local variable to save calling fluidData getter multiple times
145146
return if (fluidData.fluid == null) {
146147
fluidData.capacity
147-
} else if (fluid == fluidData.fluid && fluidData.amount <= fluidData.capacity - 1.0e-6) {
148+
} else if (fluid == fluidData.fluid && fluidData.amount <= fluidData.capacity - FLUID_EPSILON) {
148149
fluidData.capacity - fluidData.amount
149150
} else {
150151
0.0

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarHopper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface RebarHopper {
1818
companion object : MultiListener {
1919
@UniversalHandler
2020
private fun onInventoryPickup(event: InventoryPickupItemEvent, priority: EventPriority) {
21-
val holder = event.inventory.holder
21+
val holder = event.inventory.getHolder(false)
2222
if (holder is Hopper) {
2323
val rebarBlock = BlockStorage.get(holder.block)
2424
if (rebarBlock is RebarHopper) {

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarNoVanillaContainerBlock.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package io.github.pylonmc.rebar.block.base
22

3+
import io.github.pylonmc.rebar.logistics.LogisticGroup
34
import org.bukkit.event.EventPriority
45
import org.bukkit.event.inventory.InventoryMoveItemEvent
56
import org.bukkit.event.inventory.InventoryOpenEvent
67

8+
/**
9+
* A [RebarVanillaContainerBlock] that cancels all inventory open and move events, effectively preventing any vanilla interaction with the container.
10+
* Also prevents [LogisticGroup.getVanillaLogisticSlots] from working on the block.
11+
*/
712
interface RebarNoVanillaContainerBlock : RebarVanillaContainerBlock {
813
override fun onInventoryOpen(event: InventoryOpenEvent, priority: EventPriority) = event.run { isCancelled = true }
914
override fun onItemMoveTo(event: InventoryMoveItemEvent, priority: EventPriority) = event.run { isCancelled = true }

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarRecipeProcessor.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,25 @@ import java.util.IdentityHashMap
2626
interface RebarRecipeProcessor<T: RebarRecipe> {
2727

2828
@ApiStatus.Internal
29-
data class RecipeProcessorData(
29+
data class RecipeProcessorData<T: RebarRecipe>(
3030
var recipeType: RecipeType<*>?,
31-
var currentRecipe: RebarRecipe?,
31+
var currentRecipe: T?,
3232
var recipeTimeTicks: Int?,
3333
var recipeTicksRemaining: Int?,
3434
var progressItem: ProgressItem?,
35+
var lastRecipe: T?
3536
)
3637

37-
private val recipeProcessorData: RecipeProcessorData
38-
@ApiStatus.NonExtendable
39-
get() = recipeProcessorBlocks.getOrPut(this) { RecipeProcessorData(null, null, null, null, null)}
38+
private val recipeProcessorData: RecipeProcessorData<T>
39+
@Suppress("UNCHECKED_CAST")
40+
get() = recipeProcessorBlocks.getOrPut(this) {
41+
RecipeProcessorData(null, null, null, null, null, null)
42+
} as RecipeProcessorData<T>
4043

41-
@Suppress("UNCHECKED_CAST")
4244
val currentRecipe: T?
43-
@Suppress("UNCHECKED_CAST")
4445
@ApiStatus.NonExtendable
4546
// cast should always be safe due to type restriction when starting recipe
46-
get() = recipeProcessorData.currentRecipe as T?
47+
get() = recipeProcessorData.currentRecipe
4748

4849
val recipeTicksRemaining: Int?
4950
@ApiStatus.NonExtendable
@@ -59,6 +60,10 @@ interface RebarRecipeProcessor<T: RebarRecipe> {
5960
recipeProcessorData.progressItem = progressItem
6061
}
6162

63+
val lastRecipe: T?
64+
@ApiStatus.NonExtendable
65+
get() = recipeProcessorData.lastRecipe
66+
6267
/**
6368
* Set the progress item that should be updated as the recipe progresses. Optional.
6469
*
@@ -79,6 +84,7 @@ interface RebarRecipeProcessor<T: RebarRecipe> {
7984
recipeProcessorData.recipeTicksRemaining = ticks
8085
recipeProcessorData.progressItem?.setTotalTimeTicks(ticks)
8186
recipeProcessorData.progressItem?.setRemainingTimeTicks(ticks)
87+
recipeProcessorData.lastRecipe = recipe
8288
}
8389

8490
fun stopRecipe() {
@@ -117,7 +123,7 @@ interface RebarRecipeProcessor<T: RebarRecipe> {
117123

118124
private val recipeProcessorKey = rebarKey("recipe_processor_data")
119125

120-
private val recipeProcessorBlocks = IdentityHashMap<RebarRecipeProcessor<*>, RecipeProcessorData>()
126+
private val recipeProcessorBlocks = IdentityHashMap<RebarRecipeProcessor<*>, RecipeProcessorData<*>>()
121127

122128
@EventHandler
123129
private fun onDeserialize(event: RebarBlockDeserializeEvent) {

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarSimpleMultiblock.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ interface RebarSimpleMultiblock : RebarMultiblock, RebarEntityHolderBlock, Rebar
434434
* will be considered complete.
435435
*/
436436
fun validStructures(): List<Map<Vector3i, MultiblockComponent>> {
437+
// TODO: consider caching this
437438
val facing = simpleMultiblockData.direction
438439
return if (facing == null) {
439440
listOf(

rebar/src/main/kotlin/io/github/pylonmc/rebar/block/base/RebarTickingBlock.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.github.pylonmc.rebar.block.base
22

33
import io.github.pylonmc.rebar.Rebar
4-
import io.github.pylonmc.rebar.async.BukkitMainThreadDispatcher
54
import io.github.pylonmc.rebar.async.ChunkScope
65
import io.github.pylonmc.rebar.block.BlockListener
76
import io.github.pylonmc.rebar.block.BlockListener.logEventHandleErr
@@ -161,7 +160,7 @@ interface RebarTickingBlock {
161160
val rebarBlock = tickingBlock as RebarBlock
162161
val dispatcher = dispatchers.getOrPut(rebarBlock.schema) {
163162
if (tickingBlock.isAsync) Dispatchers.Default
164-
else BukkitMainThreadDispatcher(Rebar, 1)
163+
else Rebar.mainThreadDispatcher
165164
}
166165
val scope = ChunkScope(Rebar.scope.coroutineContext.createChildContext(), rebarBlock.block.chunk.position)
167166
tickingBlocks[tickingBlock]?.job = scope.launch(dispatcher) {

0 commit comments

Comments
 (0)