Skip to content

Commit

Permalink
update SubTick compat
Browse files Browse the repository at this point in the history
  • Loading branch information
SpaceWalkerRS committed May 7, 2023
1 parent 9efd044 commit 0055f16
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package redstone.multimeter.interfaces.mixin;

public interface BlockEventListener {

void rsmm$startBlockEvents();

void rsmm$nextBlockEvent();

void rsmm$endBlockEvents();

}
Original file line number Diff line number Diff line change
@@ -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<ScheduledTick<?>> listener);
void rsmm$setListener(ScheduledTickListener listener);

public void rsmm$setTickListener(Consumer<ScheduledTick<?>> listener);
ScheduledTickListener rsmm$getListener();

}
Original file line number Diff line number Diff line change
@@ -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);

}
23 changes: 10 additions & 13 deletions src/main/java/redstone/multimeter/mixin/common/LevelTicksMixin.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<ScheduledTick<?>> rsmm$scheduleListener;
private Consumer<ScheduledTick<?>> rsmm$tickListener;
private ScheduledTickListener rsmm$listener;

@Inject(
method = "schedule(Lnet/minecraft/world/ticks/ScheduledTick;)V",
Expand All @@ -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);
}
}

Expand All @@ -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<BlockPos, ?> 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<ScheduledTick<?>> listener) {
this.rsmm$scheduleListener = listener;
public void rsmm$setListener(ScheduledTickListener listener) {
this.rsmm$listener = listener;
}

@Override
public void rsmm$setTickListener(Consumer<ScheduledTick<?>> listener) {
this.rsmm$tickListener = listener;
public ScheduledTickListener rsmm$getListener() {
return rsmm$listener;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Block> blockTicks;
Expand All @@ -62,19 +64,9 @@ private ServerLevelMixin(WritableLevelData data, ResourceKey<Level> 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(
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -477,8 +463,7 @@ private void onRunBlockEvent(CallbackInfo ci) {
)
)
private void postRunBlockEvents(CallbackInfo ci) {
rsmm$currentDepth = -1;
rsmm$currentBatch = 0;
rsmm$endBlockEvents();
}

@Inject(
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = "<init>",
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<Pair<Integer, Boolean>> 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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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<Pair<Integer, Boolean>> cir, int executed_steps, ScheduledTick<?> scheduledTick) {
ScheduledTickListener listener = ((ILevelTicks)levelTicks).rsmm$getListener();

if (listener != null) {
listener.rsmm$runTick(scheduledTick);
}
}
}
2 changes: 2 additions & 0 deletions src/main/resources/rsmm_fabric.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 0055f16

Please sign in to comment.