Skip to content

Commit 55f78f1

Browse files
committed
Cleanup DispenserBlockMixin_Tracker
1 parent 25e47d0 commit 55f78f1

File tree

1 file changed

+38
-45
lines changed

1 file changed

+38
-45
lines changed

src/mixins/java/org/spongepowered/common/mixin/tracker/world/level/block/DispenserBlockMixin_Tracker.java

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
package org.spongepowered.common.mixin.tracker.world.level.block;
2626

2727
import com.google.common.collect.ImmutableList;
28+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
29+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
30+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
31+
import com.llamalad7.mixinextras.sugar.Share;
32+
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
2833
import net.minecraft.core.BlockPos;
2934
import net.minecraft.core.dispenser.BlockSource;
3035
import net.minecraft.core.dispenser.DispenseItemBehavior;
@@ -33,18 +38,16 @@
3338
import net.minecraft.world.level.block.DispenserBlock;
3439
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
3540
import net.minecraft.world.level.block.state.BlockState;
41+
import org.checkerframework.checker.nullness.qual.NonNull;
42+
import org.checkerframework.checker.nullness.qual.Nullable;
3643
import org.spongepowered.api.event.CauseStackManager;
3744
import org.spongepowered.api.event.SpongeEventFactory;
3845
import org.spongepowered.api.event.item.inventory.DropItemEvent;
3946
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
4047
import org.spongepowered.api.world.BlockChangeFlags;
4148
import org.spongepowered.asm.mixin.Mixin;
4249
import org.spongepowered.asm.mixin.injection.At;
43-
import org.spongepowered.asm.mixin.injection.Inject;
44-
import org.spongepowered.asm.mixin.injection.Redirect;
4550
import org.spongepowered.asm.mixin.injection.Slice;
46-
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
47-
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
4851
import org.spongepowered.common.SpongeCommon;
4952
import org.spongepowered.common.block.SpongeBlockSnapshot;
5053
import org.spongepowered.common.bridge.world.TrackedWorldBridge;
@@ -56,70 +59,60 @@
5659

5760
import java.util.ArrayList;
5861
import java.util.List;
59-
import java.util.function.Supplier;
6062

6163
@Mixin(DispenserBlock.class)
6264
public abstract class DispenserBlockMixin_Tracker {
63-
private Supplier<ItemStack> tracker$originalItem = () -> ItemStack.EMPTY;
64-
private PhaseContext<?> tracker$context = PhaseContext.empty();
6565

66-
@Inject(method = "dispenseFrom", at = @At(value = "HEAD"))
67-
private void tracker$createContextOnDispensing(final ServerLevel worldIn, final BlockState state, final BlockPos pos, final CallbackInfo ci) {
66+
@WrapMethod(method = "dispenseFrom")
67+
private void tracker$createContextOnDispensing(final ServerLevel worldIn, final BlockState state, final BlockPos pos, final Operation<Void> original) {
6868
final SpongeBlockSnapshot spongeBlockSnapshot = ((TrackedWorldBridge) worldIn).bridge$createSnapshot(state, pos, BlockChangeFlags.ALL);
6969
final LevelChunkBridge mixinChunk = (LevelChunkBridge) worldIn.getChunkAt(pos);
70-
this.tracker$context = BlockPhase.State.DISPENSE.createPhaseContext(PhaseTracker.SERVER)
70+
try (final @Nullable PhaseContext<@NonNull ?> context = BlockPhase.State.DISPENSE
71+
.createPhaseContext(PhaseTracker.SERVER)
7172
.source(spongeBlockSnapshot)
7273
.creator(() -> mixinChunk.bridge$getBlockCreatorUUID(pos))
73-
.notifier(() -> mixinChunk.bridge$getBlockNotifierUUID(pos))
74-
.buildAndSwitch();
74+
.notifier(() -> mixinChunk.bridge$getBlockNotifierUUID(pos))) {
75+
context.buildAndSwitch();
76+
original.call(worldIn, state, pos);
77+
}
7578
}
7679

7780

78-
@Inject(method = "dispenseFrom", at = @At(value = "RETURN"))
79-
private void tracker$closeContextOnDispensing(final ServerLevel worldIn, final BlockState state, final BlockPos pos, final CallbackInfo ci) {
80-
this.tracker$context.close();
81-
this.tracker$context = PhaseContext.empty();
82-
}
83-
84-
@Inject(method = "dispenseFrom",
85-
at = @At(
86-
value = "INVOKE",
87-
target = "Lnet/minecraft/core/dispenser/DispenseItemBehavior;dispense(Lnet/minecraft/core/dispenser/BlockSource;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;"
88-
),
89-
slice = @Slice(
90-
from = @At(value = "FIELD",
91-
target = "Lnet/minecraft/core/dispenser/DispenseItemBehavior;NOOP:Lnet/minecraft/core/dispenser/DispenseItemBehavior;"),
92-
to = @At("TAIL")
93-
),
94-
locals = LocalCapture.CAPTURE_FAILSOFT
81+
@WrapOperation(method = "dispenseFrom",
82+
at = @At(
83+
value = "INVOKE",
84+
target = "Lnet/minecraft/core/dispenser/DispenseItemBehavior;dispense(Lnet/minecraft/core/dispenser/BlockSource;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;"
85+
),
86+
slice = @Slice(
87+
from = @At(value = "FIELD",
88+
target = "Lnet/minecraft/core/dispenser/DispenseItemBehavior;NOOP:Lnet/minecraft/core/dispenser/DispenseItemBehavior;"),
89+
to = @At("TAIL")
90+
)
9591
)
96-
private void tracker$storeOriginalItem(final ServerLevel worldIn, final BlockState state, final BlockPos pos, final CallbackInfo ci,
97-
final DispenserBlockEntity dispenser, final BlockSource source, final int slotIndex, final ItemStack dispensedItem, final DispenseItemBehavior behavior) {
98-
final ItemStack tracker$originalItem = ItemStackUtil.cloneDefensiveNative(dispensedItem);
99-
this.tracker$originalItem = () -> tracker$originalItem;
92+
private ItemStack tracker$storeOriginalItem(final DispenseItemBehavior instance, final BlockSource blockSource, final ItemStack itemStack,
93+
final Operation<ItemStack> original, final @Share("original-item") LocalRef<ItemStack> originalItemRef) {
94+
originalItemRef.set(ItemStackUtil.cloneDefensiveNative(itemStack));
95+
return original.call(instance, blockSource, itemStack);
10096
}
10197

102-
103-
@Redirect(method = "dispenseFrom",
98+
@WrapOperation(method = "dispenseFrom",
10499
at = @At(value = "INVOKE",
105100
target = "Lnet/minecraft/world/level/block/entity/DispenserBlockEntity;setItem(ILnet/minecraft/world/item/ItemStack;)V"))
106-
private void tracker$setInventoryContentsCallEvent(final DispenserBlockEntity dispenserTileEntity, final int index, final ItemStack stack) {
101+
private void tracker$setInventoryContentsCallEvent(final DispenserBlockEntity dispenserTileEntity, final int index, final ItemStack stack,
102+
final Operation<Void> original, final @Share("original-item") LocalRef<ItemStack> originalItemRef) {
107103
final ItemStack dispensedItem = ItemStack.EMPTY;
108104
final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(dispensedItem);
109-
final List<ItemStackSnapshot> original = new ArrayList<>();
110-
original.add(snapshot);
105+
final List<ItemStackSnapshot> items = new ArrayList<>();
106+
items.add(snapshot);
111107
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
112108
frame.pushCause(dispenserTileEntity);
113-
final DropItemEvent.Pre dropEvent = SpongeEventFactory.createDropItemEventPre(frame.currentCause(), ImmutableList.of(snapshot), original);
114-
SpongeCommon.post(dropEvent);
115-
if (dropEvent.isCancelled()) {
116-
dispenserTileEntity.setItem(index, this.tracker$originalItem.get());
109+
final DropItemEvent.Pre dropEvent = SpongeEventFactory.createDropItemEventPre(frame.currentCause(), ImmutableList.of(snapshot), items);
110+
if (SpongeCommon.post(dropEvent)) {
111+
original.call(dispenserTileEntity, index, originalItemRef.get());
117112
return;
118113
}
119114

120-
dispenserTileEntity.setItem(index, stack);
121-
} finally {
122-
this.tracker$originalItem = () -> ItemStack.EMPTY;
115+
original.call(dispenserTileEntity, index, stack);
123116
}
124117
}
125118
}

0 commit comments

Comments
 (0)