From 0055f160f15b216f22ecca43faf49c236165da6c Mon Sep 17 00:00:00 2001 From: Space Walker Date: Mon, 8 May 2023 00:22:04 +0200 Subject: [PATCH] update SubTick compat --- .../interfaces/mixin/BlockEventListener.java | 11 +++ .../interfaces/mixin/ILevelTicks.java | 8 +-- .../mixin/ScheduledTickListener.java | 11 +++ .../mixin/common/LevelTicksMixin.java | 23 +++---- .../mixin/common/ServerLevelMixin.java | 68 ++++++++++++------- .../compat/subtick/BlockEventQueueMixin.java | 68 +++++++++++++++++++ .../subtick/ScheduledTickQueueMixin.java | 41 +++++++++++ src/main/resources/rsmm_fabric.mixins.json | 2 + 8 files changed, 189 insertions(+), 43 deletions(-) create mode 100644 src/main/java/redstone/multimeter/interfaces/mixin/BlockEventListener.java create mode 100644 src/main/java/redstone/multimeter/interfaces/mixin/ScheduledTickListener.java create mode 100644 src/main/java/redstone/multimeter/mixin/common/compat/subtick/BlockEventQueueMixin.java create mode 100644 src/main/java/redstone/multimeter/mixin/common/compat/subtick/ScheduledTickQueueMixin.java diff --git a/src/main/java/redstone/multimeter/interfaces/mixin/BlockEventListener.java b/src/main/java/redstone/multimeter/interfaces/mixin/BlockEventListener.java new file mode 100644 index 00000000..ca44d80c --- /dev/null +++ b/src/main/java/redstone/multimeter/interfaces/mixin/BlockEventListener.java @@ -0,0 +1,11 @@ +package redstone.multimeter.interfaces.mixin; + +public interface BlockEventListener { + + void rsmm$startBlockEvents(); + + void rsmm$nextBlockEvent(); + + void rsmm$endBlockEvents(); + +} diff --git a/src/main/java/redstone/multimeter/interfaces/mixin/ILevelTicks.java b/src/main/java/redstone/multimeter/interfaces/mixin/ILevelTicks.java index 04c2a5b4..b7560a57 100644 --- a/src/main/java/redstone/multimeter/interfaces/mixin/ILevelTicks.java +++ b/src/main/java/redstone/multimeter/interfaces/mixin/ILevelTicks.java @@ -1,13 +1,9 @@ package redstone.multimeter.interfaces.mixin; -import java.util.function.Consumer; - -import net.minecraft.world.ticks.ScheduledTick; - public interface ILevelTicks { - public void rsmm$setScheduleListener(Consumer> listener); + void rsmm$setListener(ScheduledTickListener listener); - public void rsmm$setTickListener(Consumer> listener); + ScheduledTickListener rsmm$getListener(); } diff --git a/src/main/java/redstone/multimeter/interfaces/mixin/ScheduledTickListener.java b/src/main/java/redstone/multimeter/interfaces/mixin/ScheduledTickListener.java new file mode 100644 index 00000000..33e06b6e --- /dev/null +++ b/src/main/java/redstone/multimeter/interfaces/mixin/ScheduledTickListener.java @@ -0,0 +1,11 @@ +package redstone.multimeter.interfaces.mixin; + +import net.minecraft.world.ticks.ScheduledTick; + +public interface ScheduledTickListener { + + void rsmm$scheduleTick(ScheduledTick scheduledTick); + + void rsmm$runTick(ScheduledTick scheduledTick); + +} diff --git a/src/main/java/redstone/multimeter/mixin/common/LevelTicksMixin.java b/src/main/java/redstone/multimeter/mixin/common/LevelTicksMixin.java index d46841c1..d66a0755 100644 --- a/src/main/java/redstone/multimeter/mixin/common/LevelTicksMixin.java +++ b/src/main/java/redstone/multimeter/mixin/common/LevelTicksMixin.java @@ -1,11 +1,9 @@ package redstone.multimeter.mixin.common; import java.util.function.BiConsumer; -import java.util.function.Consumer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -15,12 +13,12 @@ import net.minecraft.world.ticks.ScheduledTick; import redstone.multimeter.interfaces.mixin.ILevelTicks; +import redstone.multimeter.interfaces.mixin.ScheduledTickListener; @Mixin(LevelTicks.class) public class LevelTicksMixin implements ILevelTicks { - private Consumer> rsmm$scheduleListener; - private Consumer> rsmm$tickListener; + private ScheduledTickListener rsmm$listener; @Inject( method = "schedule(Lnet/minecraft/world/ticks/ScheduledTick;)V", @@ -29,8 +27,8 @@ public class LevelTicksMixin implements ILevelTicks { ) ) private void logSchedule(ScheduledTick scheduledTick, CallbackInfo ci) { - if (rsmm$scheduleListener != null) { - rsmm$scheduleListener.accept(scheduledTick); + if (rsmm$listener != null) { + rsmm$listener.rsmm$scheduleTick(scheduledTick); } } @@ -39,23 +37,22 @@ private void logSchedule(ScheduledTick scheduledTick, CallbackInfo ci) { locals = LocalCapture.CAPTURE_FAILHARD, at = @At( value = "INVOKE", - shift = Shift.BEFORE, target = "Ljava/util/function/BiConsumer;accept(Ljava/lang/Object;Ljava/lang/Object;)V" ) ) private void logTick(BiConsumer ticker, CallbackInfo ci, ScheduledTick scheduledTick) { - if (rsmm$tickListener != null) { - rsmm$tickListener.accept(scheduledTick); + if (rsmm$listener != null) { + rsmm$listener.rsmm$runTick(scheduledTick); } } @Override - public void rsmm$setScheduleListener(Consumer> listener) { - this.rsmm$scheduleListener = listener; + public void rsmm$setListener(ScheduledTickListener listener) { + this.rsmm$listener = listener; } @Override - public void rsmm$setTickListener(Consumer> listener) { - this.rsmm$tickListener = listener; + public ScheduledTickListener rsmm$getListener() { + return rsmm$listener; } } diff --git a/src/main/java/redstone/multimeter/mixin/common/ServerLevelMixin.java b/src/main/java/redstone/multimeter/mixin/common/ServerLevelMixin.java index 08d63710..61616c7f 100644 --- a/src/main/java/redstone/multimeter/mixin/common/ServerLevelMixin.java +++ b/src/main/java/redstone/multimeter/mixin/common/ServerLevelMixin.java @@ -33,13 +33,15 @@ import net.minecraft.world.ticks.ScheduledTick; import redstone.multimeter.common.TickTask; +import redstone.multimeter.interfaces.mixin.BlockEventListener; import redstone.multimeter.interfaces.mixin.ILevelTicks; import redstone.multimeter.interfaces.mixin.IMinecraftServer; import redstone.multimeter.interfaces.mixin.IServerLevel; +import redstone.multimeter.interfaces.mixin.ScheduledTickListener; import redstone.multimeter.server.MultimeterServer; @Mixin(ServerLevel.class) -public abstract class ServerLevelMixin extends Level implements IServerLevel { +public abstract class ServerLevelMixin extends Level implements IServerLevel, ScheduledTickListener, BlockEventListener { @Shadow @Final private MinecraftServer server; @Shadow @Final private LevelTicks blockTicks; @@ -62,19 +64,9 @@ private ServerLevelMixin(WritableLevelData data, ResourceKey key, Registr value = "TAIL" ) ) - private void setScheduledTickListeners(CallbackInfo ci) { - ((ILevelTicks)blockTicks).rsmm$setScheduleListener(scheduledTick -> { - getMultimeter().logScheduledTick(this, scheduledTick.pos(), scheduledTick.priority(), true); - }); - ((ILevelTicks)blockTicks).rsmm$setTickListener(scheduledTick -> { - this.rsmm$nextScheduledTick = scheduledTick; - }); - ((ILevelTicks)fluidTicks).rsmm$setScheduleListener(scheduledTick -> { - getMultimeter().logScheduledTick(this, scheduledTick.pos(), scheduledTick.priority(), true); - }); - ((ILevelTicks)fluidTicks).rsmm$setTickListener(scheduledTick -> { - this.rsmm$nextScheduledTick = scheduledTick; - }); + private void init(CallbackInfo ci) { + ((ILevelTicks)this.blockTicks).rsmm$setListener(this); + ((ILevelTicks)this.fluidTicks).rsmm$setListener(this); } @Inject( @@ -450,8 +442,7 @@ private void postBlockEvent(BlockPos pos, Block block, int type, int data, Callb ) ) private void onRunBlockEvents(CallbackInfo ci) { - rsmm$currentDepth = 0; - rsmm$currentBatch = blockEvents.size(); + rsmm$startBlockEvents(); } @Inject( @@ -462,12 +453,7 @@ private void onRunBlockEvents(CallbackInfo ci) { ) ) private void onRunBlockEvent(CallbackInfo ci) { - if (rsmm$currentBatch == 0) { - rsmm$currentDepth++; - rsmm$currentBatch = blockEvents.size(); - } - - rsmm$currentBatch--; + rsmm$nextBlockEvent(); } @Inject( @@ -477,8 +463,7 @@ private void onRunBlockEvent(CallbackInfo ci) { ) ) private void postRunBlockEvents(CallbackInfo ci) { - rsmm$currentDepth = -1; - rsmm$currentBatch = 0; + rsmm$endBlockEvents(); } @Inject( @@ -497,6 +482,41 @@ public MultimeterServer getMultimeterServer() { return ((IMinecraftServer)server).getMultimeterServer(); } + @Override + public void rsmm$scheduleTick(ScheduledTick scheduledTick) { + getMultimeter().logScheduledTick(this, scheduledTick.pos(), scheduledTick.priority(), true); + } + + @Override + public void rsmm$runTick(ScheduledTick scheduledTick) { + // there is an extra check for the correct block/fluid state + // that is run after this method is called, so we cache this + // scheduled tick and log it if that check is successful + rsmm$nextScheduledTick = scheduledTick; + } + + @Override + public void rsmm$startBlockEvents() { + rsmm$currentDepth = 0; + rsmm$currentBatch = blockEvents.size(); + } + + @Override + public void rsmm$nextBlockEvent() { + if (rsmm$currentBatch == 0) { + rsmm$currentDepth++; + rsmm$currentBatch = blockEvents.size(); + } + + rsmm$currentBatch--; + } + + @Override + public void rsmm$endBlockEvents() { + rsmm$currentDepth = -1; + rsmm$currentBatch = 0; + } + private void rsmm$logNextScheduledTick() { ScheduledTick scheduledTick = rsmm$nextScheduledTick; rsmm$nextScheduledTick = null; diff --git a/src/main/java/redstone/multimeter/mixin/common/compat/subtick/BlockEventQueueMixin.java b/src/main/java/redstone/multimeter/mixin/common/compat/subtick/BlockEventQueueMixin.java new file mode 100644 index 00000000..b49a7534 --- /dev/null +++ b/src/main/java/redstone/multimeter/mixin/common/compat/subtick/BlockEventQueueMixin.java @@ -0,0 +1,68 @@ +package redstone.multimeter.mixin.common.compat.subtick; + +import org.apache.commons.lang3.tuple.Pair; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; + +import redstone.multimeter.interfaces.mixin.BlockEventListener; + +@Pseudo +@Mixin(targets = "subtick.queues.BlockEventQueue") +public class BlockEventQueueMixin { + + private BlockEventListener rsmm$listener; + + @Inject( + method = "", + at = @At( + value = "TAIL" + ) + ) + private void init(ServerLevel level, CallbackInfo ci) { + this.rsmm$listener = (BlockEventListener)level; + } + + @Inject( + method = "start", + at = @At( + value = "HEAD" + ) + ) + private void start(CallbackInfo ci) { + if (rsmm$listener != null) { + rsmm$listener.rsmm$startBlockEvents(); + } + } + + @Inject( + method = "step", + at = @At( + value = "INVOKE", + target = "Lit/unimi/dsi/fastutil/objects/ObjectLinkedOpenHashSet;removeFirst()Ljava/lang/Object;" + ) + ) + private void next(int count, BlockPos pos, int range, CallbackInfoReturnable> cir) { + if (rsmm$listener != null) { + rsmm$listener.rsmm$nextBlockEvent(); + } + } + + @Inject( + method = "end", + at = @At( + value = "HEAD" + ) + ) + private void end(CallbackInfo ci) { + if (rsmm$listener != null) { + rsmm$listener.rsmm$endBlockEvents(); + } + } +} diff --git a/src/main/java/redstone/multimeter/mixin/common/compat/subtick/ScheduledTickQueueMixin.java b/src/main/java/redstone/multimeter/mixin/common/compat/subtick/ScheduledTickQueueMixin.java new file mode 100644 index 00000000..6374c97e --- /dev/null +++ b/src/main/java/redstone/multimeter/mixin/common/compat/subtick/ScheduledTickQueueMixin.java @@ -0,0 +1,41 @@ +package redstone.multimeter.mixin.common.compat.subtick; + +import org.apache.commons.lang3.tuple.Pair; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.ticks.LevelTicks; +import net.minecraft.world.ticks.ScheduledTick; + +import redstone.multimeter.interfaces.mixin.ILevelTicks; +import redstone.multimeter.interfaces.mixin.ScheduledTickListener; + +@Pseudo +@Mixin(targets = "subtick.queues.ScheduledTickQueue") +public class ScheduledTickQueueMixin { + + @Shadow @Final private LevelTicks levelTicks; + + @Inject( + method = "step", + locals = LocalCapture.CAPTURE_FAILHARD, + at = @At( + value = "INVOKE", + target = "Ljava/util/function/BiConsumer;accept(Ljava/lang/Object;Ljava/lang/Object;)V" + ) + ) + private void logTick(int count, BlockPos pos, int range, CallbackInfoReturnable> cir, int executed_steps, ScheduledTick scheduledTick) { + ScheduledTickListener listener = ((ILevelTicks)levelTicks).rsmm$getListener(); + + if (listener != null) { + listener.rsmm$runTick(scheduledTick); + } + } +} diff --git a/src/main/resources/rsmm_fabric.mixins.json b/src/main/resources/rsmm_fabric.mixins.json index 9420662e..b7ac60a4 100644 --- a/src/main/resources/rsmm_fabric.mixins.json +++ b/src/main/resources/rsmm_fabric.mixins.json @@ -21,6 +21,8 @@ "common.ServerLevelMixin", "common.compat.alternate_current.LevelHelperMixin", "common.compat.alternate_current_plus.LevelHelperMixin", + "common.compat.subtick.BlockEventQueueMixin", + "common.compat.subtick.ScheduledTickQueueMixin", "common.meterable.BellBlockMixin", "common.meterable.ButtonBlockMixin", "common.meterable.ComparatorBlockEntityMixin",