streamline tickers

This commit is contained in:
DBotThePony 2022-09-09 13:23:47 +07:00
parent 01e861032e
commit f80b913d61
Signed by: DBot
GPG Key ID: DCC23B5715498507
10 changed files with 101 additions and 126 deletions

View File

@ -115,42 +115,6 @@ fun onServerTick(event: ServerTickEvent) {
} }
} }
fun tickServerPre(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preServerTick.add(ticker)
}
fun tickServer(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postServerTick.add(ticker)
}
fun onceServerPre(ticker: ITickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preServerTick.add(ticker)
}
fun onceServer(ticker: ITickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postServerTick.add(ticker)
}
fun onWorldTick(event: LevelTickEvent) { fun onWorldTick(event: LevelTickEvent) {
if (event.phase === TickEvent.Phase.START) { if (event.phase === TickEvent.Phase.START) {
preWorldTick[event.level]?.tick() preWorldTick[event.level]?.tick()
@ -159,70 +123,88 @@ fun onWorldTick(event: LevelTickEvent) {
} }
} }
fun addPreWorldTicker(level: Level, ticker: IConditionalTickable) { fun onceServerPre(ticker: ITickable) {
if (SERVER_IS_DYING) { preServerTick.add(ticker, SERVER_IS_DYING, "Server is stopping")
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preWorldTick.computeIfAbsent(level) { TickList() }.add(ticker)
} }
fun addPostWorldTicker(level: Level, ticker: IConditionalTickable) { fun onceServer(ticker: ITickable) {
if (SERVER_IS_DYING) { postServerTick.add(ticker, SERVER_IS_DYING, "Server is stopping")
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postWorldTick.computeIfAbsent(level) { TickList() }.add(ticker)
} }
fun addPreWorldTickerOnce(level: Level, ticker: ITickable) { fun tickServerPre(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) { preServerTick.add(ticker, SERVER_IS_DYING, "Server is stopping")
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preWorldTick.computeIfAbsent(level) { TickList() }.add(ticker)
} }
fun addPostWorldTickerOnce(level: Level, ticker: ITickable) { fun tickServer(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) { postServerTick.add(ticker, SERVER_IS_DYING, "Server is stopping")
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postWorldTick.computeIfAbsent(level) { TickList() }.add(ticker)
} }
fun Level.until(ticker: () -> Boolean) { fun tickUntilServerPre(ticker: () -> Boolean) {
addPostWorldTicker(this, object : IConditionalTickable { preServerTick.until(ticker, SERVER_IS_DYING, "Server is stopping")
override var canTick: Boolean = true
private set
override fun tick() {
canTick = !ticker.invoke()
}
})
} }
fun Level.untilPre(ticker: () -> Boolean) { fun tickUntilServer(ticker: () -> Boolean) {
addPreWorldTicker(this, object : IConditionalTickable { postServerTick.until(ticker, SERVER_IS_DYING, "Server is stopping")
override var canTick: Boolean = true }
private set
override fun tick() { fun tickWhileServerPre(condition: () -> Boolean, ticker: () -> Unit) {
canTick = !ticker.invoke() preServerTick.`while`(condition, ticker, SERVER_IS_DYING, "Server is stopping")
} }
})
fun tickWhileServer(condition: () -> Boolean, ticker: () -> Unit) {
postServerTick.`while`(condition, ticker, SERVER_IS_DYING, "Server is stopping")
} }
fun Level.once(ticker: ITickable) { fun Level.once(ticker: ITickable) {
addPostWorldTickerOnce(this, ticker) if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postWorldTick.computeIfAbsent(this) { TickList() }.add(ticker)
} }
fun Level.oncePre(ticker: ITickable) { fun Level.oncePre(ticker: ITickable) {
addPreWorldTickerOnce(this, ticker) if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preWorldTick.computeIfAbsent(this) { TickList() }.add(ticker)
}
fun Level.addTicker(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
postWorldTick.computeIfAbsent(this) { TickList() }.add(ticker)
}
fun Level.addTickerPre(ticker: IConditionalTickable) {
if (SERVER_IS_DYING) {
LOGGER.error("Refusing to add ticker $ticker while server is dying", IllegalStateException("Server is stopping"))
return
}
preWorldTick.computeIfAbsent(this) { TickList() }.add(ticker)
}
fun Level.until(ticker: () -> Boolean) {
addTicker(IConditionalTickable.wrap(ticker))
}
fun Level.untilPre(ticker: () -> Boolean) {
addTickerPre(IConditionalTickable.wrap(ticker))
}
fun Level.`while`(condition: () -> Boolean, ticker: () -> Unit) {
addTicker(IConditionalTickable.wrap(condition, ticker))
}
fun Level.whilePre(condition: () -> Boolean, ticker: () -> Unit) {
addTickerPre(IConditionalTickable.wrap(condition, ticker))
} }
private fun clear() { private fun clear() {

View File

@ -18,7 +18,7 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPostWorldTickerOnce import ru.dbotthepony.mc.otm.once
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -76,10 +76,8 @@ class BatteryBankBlock : RotatableMatteryBlock(), EntityBlock {
movedByPiston: Boolean movedByPiston: Boolean
) { ) {
super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
val blockEntity = level.getBlockEntity(pos) as? BatteryBankBlockEntity ?: return val blockEntity = level.getBlockEntity(pos) as? BatteryBankBlockEntity ?: return
level.once { blockEntity.checkSurroundings(level) }
addPostWorldTickerOnce(level) { blockEntity.checkSurroundings(level) }
} }
companion object { companion object {

View File

@ -13,9 +13,9 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.oncePre
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -54,7 +54,7 @@ class ChemicalGeneratorBlock : RotatableMatteryBlock(), EntityBlock {
val tile = level.getBlockEntity(pos) val tile = level.getBlockEntity(pos)
if (tile is ChemicalGeneratorBlockEntity) { if (tile is ChemicalGeneratorBlockEntity) {
addPreWorldTickerOnce(level) { level.oncePre {
tile.checkSurroundings() tile.checkSurroundings()
} }
} }

View File

@ -22,12 +22,12 @@ import net.minecraft.world.level.material.MaterialColor
import net.minecraft.world.level.material.PushReaction import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.core.times import ru.dbotthepony.mc.otm.core.times
import ru.dbotthepony.mc.otm.oncePre
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MBlocks import ru.dbotthepony.mc.otm.registry.MBlocks
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -120,8 +120,8 @@ class BlockGravitationStabilizer : RotatableMatteryBlock(props), EntityBlock {
) { ) {
super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
addPreWorldTickerOnce(level) { level.oncePre {
if (level.getBlockState(pos).block !is BlockGravitationStabilizer) return@addPreWorldTickerOnce if (level.getBlockState(pos).block !is BlockGravitationStabilizer) return@oncePre
val bb = getBoundingBlock(level, state, pos) val bb = getBoundingBlock(level, state, pos)
if (bb.block !is BlockGravitationStabilizerLens) { if (bb.block !is BlockGravitationStabilizerLens) {
@ -181,8 +181,8 @@ class BlockGravitationStabilizerLens : RotatableMatteryBlock(props) {
) { ) {
super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
addPreWorldTickerOnce(level) { level.oncePre {
if (level.getBlockState(pos).block !is BlockGravitationStabilizerLens) return@addPreWorldTickerOnce if (level.getBlockState(pos).block !is BlockGravitationStabilizerLens) return@oncePre
val bb = getBoundingBlock(level, state, pos) val bb = getBoundingBlock(level, state, pos)
if (bb.block !is BlockGravitationStabilizer) { if (bb.block !is BlockGravitationStabilizer) {

View File

@ -21,9 +21,9 @@ import net.minecraft.nbt.StringTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.oncePre
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider { abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
var customDisplayName: Component? = null var customDisplayName: Component? = null
@ -69,33 +69,30 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
abstract override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? abstract override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu?
protected fun tickOnce(func: Runnable) { protected fun tickOnce(func: Runnable) {
val level = level level?.oncePre { if (!isRemoved) func.run() }
if (level != null) addPreWorldTickerOnce(level) { if (!isRemoved) func.run() }
} }
protected fun tickOnceServer(func: Runnable) { protected fun tickOnceServer(func: Runnable) {
val level = level (level as? ServerLevel)?.oncePre { if (!isRemoved) func.run() }
if (level is ServerLevel) addPreWorldTickerOnce(level) { if (!isRemoved) func.run() }
} }
protected fun tickOnceClient(func: Runnable) { protected fun tickOnceClient(func: Runnable) {
val level = level (level as? ClientLevel)?.oncePre { if (!isRemoved) func.run() }
if (level is ClientLevel) addPreWorldTickerOnce(level) { if (!isRemoved) func.run() }
} }
protected fun tickOnce(func: (Level) -> Unit) { protected fun tickOnce(func: (Level) -> Unit) {
val level = level val level = level
if (level != null) addPreWorldTickerOnce(level) { if (!isRemoved) func(level) } level?.oncePre { if (!isRemoved) func.invoke(level) }
} }
protected fun tickOnceServer(func: (ServerLevel) -> Unit) { protected fun tickOnceServer(func: (ServerLevel) -> Unit) {
val level = level val level = level as? ServerLevel ?: return
if (level is ServerLevel) addPreWorldTickerOnce(level) { if (!isRemoved) func(level) } level.oncePre { if (!isRemoved) func.invoke(level) }
} }
protected fun tickOnceClient(func: (ClientLevel) -> Unit) { protected fun tickOnceClient(func: (ClientLevel) -> Unit) {
val level = level val level = level as? ClientLevel ?: return
if (level is ClientLevel) addPreWorldTickerOnce(level) { if (!isRemoved) func(level) } level.oncePre { if (!isRemoved) func.invoke(level) }
} }
protected fun <T> getAndBind( protected fun <T> getAndBind(

View File

@ -15,7 +15,6 @@ import net.minecraft.world.phys.shapes.BooleanOp
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.StorageCableBlock import ru.dbotthepony.mc.otm.block.StorageCableBlock
@ -23,6 +22,7 @@ import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.core.unaryMinus import ru.dbotthepony.mc.otm.core.unaryMinus
import ru.dbotthepony.mc.otm.oncePre
class StorageBusBlock : RotatableMatteryBlock(), EntityBlock { class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
override val hasFreeRotation: Boolean get() = true override val hasFreeRotation: Boolean get() = true
@ -107,7 +107,7 @@ class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
val tile = level.getBlockEntity(pos) val tile = level.getBlockEntity(pos)
if (tile is StorageBusBlockEntity) { if (tile is StorageBusBlockEntity) {
addPreWorldTickerOnce(level) { level.oncePre {
tile.checkSurroundings() tile.checkSurroundings()
} }
} }

View File

@ -15,7 +15,6 @@ import net.minecraft.world.phys.shapes.BooleanOp
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.StorageCableBlock import ru.dbotthepony.mc.otm.block.StorageCableBlock
@ -24,6 +23,7 @@ import ru.dbotthepony.mc.otm.block.entity.storage.StorageImporterBlockEntity
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.core.unaryMinus import ru.dbotthepony.mc.otm.core.unaryMinus
import ru.dbotthepony.mc.otm.oncePre
class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock { class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
override val hasFreeRotation: Boolean get() = true override val hasFreeRotation: Boolean get() = true
@ -108,7 +108,7 @@ class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
val tile = level.getBlockEntity(pos) val tile = level.getBlockEntity(pos)
if (tile is StorageImporterBlockEntity) { if (tile is StorageImporterBlockEntity) {
addPreWorldTickerOnce(level) { level.oncePre {
tile.checkSurroundings() tile.checkSurroundings()
} }
} }
@ -199,7 +199,7 @@ class StorageExporterBlock : RotatableMatteryBlock(), EntityBlock {
val tile = level.getBlockEntity(pos) val tile = level.getBlockEntity(pos)
if (tile is StorageExporterBlockEntity) { if (tile is StorageExporterBlockEntity) {
addPreWorldTickerOnce(level) { level.oncePre {
tile.checkSurroundings() tile.checkSurroundings()
} }
} }

View File

@ -35,11 +35,7 @@ class TickList {
return return
} }
if (inTicker) { return add(ticker)
conditionalValveTime.add(ticker)
} else {
conditional.addFirst(ticker)
}
} }
fun add(ticker: ITickable, condition: Boolean, reason: String) { fun add(ticker: ITickable, condition: Boolean, reason: String) {
@ -48,13 +44,15 @@ class TickList {
return return
} }
if (inTicker) { return add(ticker)
onceValveTime.add(ticker)
} else {
once.addFirst(ticker)
}
} }
fun until(ticker: () -> Boolean) = add(IConditionalTickable.wrap(ticker))
fun `while`(tickerCondition: () -> Boolean, ticker: () -> Unit) = add(IConditionalTickable.wrap(tickerCondition, ticker))
fun until(ticker: () -> Boolean, condition: Boolean, reason: String) = add(IConditionalTickable.wrap(ticker), condition, reason)
fun `while`(tickerCondition: () -> Boolean, ticker: () -> Unit, condition: Boolean, reason: String) = add(IConditionalTickable.wrap(tickerCondition, ticker), condition, reason)
fun tick() { fun tick() {
if (inTicker) { if (inTicker) {
throw ConcurrentModificationException("Already ticking") throw ConcurrentModificationException("Already ticking")

View File

@ -6,8 +6,8 @@ import net.minecraft.core.SectionPos
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.core.IConditionalTickable import ru.dbotthepony.mc.otm.core.IConditionalTickable
import ru.dbotthepony.mc.otm.addPreWorldTicker
import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.addTicker
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
@ -92,7 +92,7 @@ abstract class Abstract6Graph<T> : IConditionalTickable {
nodeGetter: (BlockEntity) -> Graph6Node<T>?, nodeGetter: (BlockEntity) -> Graph6Node<T>?,
factory: () -> Abstract6Graph<T> factory: () -> Abstract6Graph<T>
) { ) {
addPreWorldTicker(level, object : IConditionalTickable { level.addTicker(object : IConditionalTickable {
override fun tick() { override fun tick() {
discovered = discover(level, blockPos, node, nodeGetter, factory) discovered = discover(level, blockPos, node, nodeGetter, factory)
} }

View File

@ -5,7 +5,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.addPreWorldTicker import ru.dbotthepony.mc.otm.addTickerPre
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.graph.Abstract6Graph import ru.dbotthepony.mc.otm.graph.Abstract6Graph
@ -51,7 +51,7 @@ class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGra
if (!addedTicker) { if (!addedTicker) {
addedTicker = true addedTicker = true
addPreWorldTicker(level, this) level.addTickerPre(this)
} }
} }