Skip to content

Commit

Permalink
!feat: Refactor Interactions to use Transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabizou committed Jun 4, 2024
1 parent 0f62e97 commit a36f6a7
Show file tree
Hide file tree
Showing 55 changed files with 1,157 additions and 279 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@

import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.BlockHitResult;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.world.BlockChangeFlag;
Expand All @@ -41,6 +46,9 @@
import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge;
import org.spongepowered.common.event.tracking.PhaseContext;
import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemOnBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline;

import java.util.Optional;
Expand Down Expand Up @@ -111,4 +119,9 @@ public interface TrackedWorldBridge {
*/
SpongeBlockSnapshot bridge$createSnapshotWithEntity(BlockState state, BlockPos pos, BlockChangeFlag updateFlag, @Nullable BlockEntity tileEntity);

UseItemOnBlockPipeline bridge$startInteractionUseOnChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack);

UseBlockPipeline bridge$startInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack);

UseItemPipeline bridge$startItemInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, ItemStack copiedStack, BlockHitResult blockRaytraceResult, boolean creative);
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,10 @@ public static InteractBlockEvent.Primary callInteractBlockEventPrimary(final Ser
}
}

public static InteractBlockEvent.Secondary callInteractBlockEventSecondary(final net.minecraft.world.entity.player.Player player, final ItemStack heldItem, final Vector3d hitVec, final BlockSnapshot targetBlock, final Direction targetSide, final InteractionHand hand) {
public static InteractBlockEvent.Secondary.Pre callInteractBlockEventSecondary(final net.minecraft.world.entity.player.Player player, final ItemStack heldItem, final Vector3d hitVec, final BlockSnapshot targetBlock, final Direction targetSide, final InteractionHand hand) {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
SpongeCommonEventFactory.applyCommonInteractContext(player, heldItem, hand, targetBlock, null, frame);
final InteractBlockEvent.Secondary event = SpongeEventFactory.createInteractBlockEventSecondary(frame.currentCause(),
final InteractBlockEvent.Secondary.Pre event = SpongeEventFactory.createInteractBlockEventSecondaryPre(frame.currentCause(),
Tristate.UNDEFINED, Tristate.UNDEFINED, Tristate.UNDEFINED, Tristate.UNDEFINED, targetBlock, hitVec,
targetSide);
SpongeCommon.post(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
import java.util.Deque;

public class EffectTransactor implements AutoCloseable {
final @Nullable ResultingTransactionBySideEffect previousEffect;
final @Nullable ResultingTransactionBySideEffect<?, ?, ?, ?> previousEffect;
public final @Nullable GameTransaction<@NonNull ?> parent;
private final TransactionalCaptureSupplier supplier;
private final ResultingTransactionBySideEffect effect;
private final ResultingTransactionBySideEffect<?, ?, ?, ?> effect;

EffectTransactor(final ResultingTransactionBySideEffect effect, final @Nullable GameTransaction<@NonNull ?> parent,
final @Nullable ResultingTransactionBySideEffect previousEffect, final TransactionalCaptureSupplier transactor) {
EffectTransactor(final ResultingTransactionBySideEffect<?, ?, ?, ?> effect, final @Nullable GameTransaction<@NonNull ?> parent,
final @Nullable ResultingTransactionBySideEffect<?, ?, ?, ?> previousEffect, final TransactionalCaptureSupplier transactor) {
/*
| ChangeBlock(1) <- head will be RemoveTileEntity(1), tail is still RemoveTileentity(1)
| |- RemoveTileEntity <- Head will be ChangeBlock(2) tail is still ChangeBlock(2)
Expand All @@ -55,7 +55,7 @@ public void close() {
&& this.parent.sideEffects != null
&& this.parent.getEffects().peekLast() == this.effect
) {
final Deque<ResultingTransactionBySideEffect> effects = this.parent.getEffects();
final Deque<ResultingTransactionBySideEffect<?, ?, ?, ?>> effects = this.parent.getEffects();
effects.removeLast();
if (effects.isEmpty()) {
this.parent.sideEffects = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public abstract class GameTransaction<E extends Event & Cancellable> implements
protected boolean cancelled = false;

// Children Definitions
@Nullable LinkedList<ResultingTransactionBySideEffect> sideEffects;
@Nullable LinkedList<ResultingTransactionBySideEffect<?, ?, ?, ?>> sideEffects;

// LinkedList node definitions
@Nullable GameTransaction<@NonNull ?> previous;
Expand All @@ -75,14 +75,14 @@ public final TransactionType<? extends E> getTransactionType() {
return this.transactionType;
}

final Deque<ResultingTransactionBySideEffect> getEffects() {
final Deque<ResultingTransactionBySideEffect<?, ?, ?, ?>> getEffects() {
if (this.sideEffects == null) {
this.sideEffects = new LinkedList<>();
}
return this.sideEffects;
}

public final void addLast(final ResultingTransactionBySideEffect effect) {
public final void addLast(final ResultingTransactionBySideEffect<?, ?, ?, ?> effect) {
if (this.sideEffects == null) {
this.sideEffects = new LinkedList<>();
}
Expand All @@ -97,7 +97,7 @@ public final boolean hasAnyPrimaryChildrenTransactions() {
if (this.sideEffects == null) {
return false;
}
for (final ResultingTransactionBySideEffect sideEffect : this.sideEffects) {
for (final ResultingTransactionBySideEffect<?, ?, ?, ?> sideEffect : this.sideEffects) {
@Nullable GameTransaction<@NonNull ?> transaction = sideEffect.head;
while (transaction != null) {
if (transaction.transactionType.isPrimary() || transaction.hasChildTransactions()) {
Expand Down Expand Up @@ -131,10 +131,17 @@ public abstract Optional<E> generateEvent(
public final void markCancelled() {
this.cancelled = true;
this.childIterator().forEachRemaining(GameTransaction::markCancelled);
if (this.next != null && this.next.hasUnknownChainRequiringCancellation()) {
this.next.markCancelled();
}
}

public abstract boolean markCancelledTransactions(E event, ImmutableList<? extends GameTransaction<E>> transactions);

protected boolean hasUnknownChainRequiringCancellation() {
return false;
}

public void postProcessEvent(final PhaseContext<@NonNull ?> context, final E event) {

}
Expand Down Expand Up @@ -183,16 +190,16 @@ protected void captureState() {
}

private static class ChildIterator implements Iterator<GameTransaction<@NonNull ?>> {
private final Iterator<ResultingTransactionBySideEffect> effectIterator;
private final Iterator<ResultingTransactionBySideEffect<?, ?, ?, ?>> effectIterator;
private @Nullable GameTransaction<@NonNull ?> cachedNext;
private @MonotonicNonNull GameTransaction<@NonNull ?> pointer;
private boolean hasNoRemainingElements = false;

ChildIterator(final Iterator<ResultingTransactionBySideEffect> iterator) {
ChildIterator(final Iterator<ResultingTransactionBySideEffect<?, ?, ?, ?>> iterator) {
// We're going to search the iterator's effects until we find the first at least
this.effectIterator = iterator;
while (this.effectIterator.hasNext()) {
final ResultingTransactionBySideEffect next = this.effectIterator.next();
final ResultingTransactionBySideEffect<?, ?, ?, ?> next = this.effectIterator.next();
if (next.head != null) {
this.cachedNext = next.head;
this.pointer = next.head;
Expand All @@ -219,7 +226,7 @@ public boolean hasNext() {
// start search for the next, sadly because effects don't make a clean chain,
// there can be many effects with no transactions recorded
while (this.effectIterator.hasNext()) {
final ResultingTransactionBySideEffect next = this.effectIterator.next();
final ResultingTransactionBySideEffect<?, ?, ?, ?> next = this.effectIterator.next();
if (next.head != null) {
this.cachedNext = next.head;
return true;
Expand Down Expand Up @@ -250,16 +257,16 @@ public boolean hasNext() {


private static class ReverseChildIterator implements Iterator<GameTransaction<@NonNull ?>> {
private final Iterator<ResultingTransactionBySideEffect> effectIterator;
private final Iterator<ResultingTransactionBySideEffect<?, ?, ?, ?>> effectIterator;
private @Nullable GameTransaction<@NonNull ?> cachedPrevious;
private @MonotonicNonNull GameTransaction<@NonNull ?> pointer;
private boolean hasNoRemainingElements = false;

ReverseChildIterator(final Iterator<ResultingTransactionBySideEffect> iterator) {
ReverseChildIterator(final Iterator<ResultingTransactionBySideEffect<?, ?, ?, ?>> iterator) {
// We're going to search the iterator's effects until we find the first at least
this.effectIterator = iterator;
while (this.effectIterator.hasNext()) {
final ResultingTransactionBySideEffect next = this.effectIterator.next();
final ResultingTransactionBySideEffect<?, ?, ?, ?> next = this.effectIterator.next();
if (next.tail != null) {
this.pointer = next.tail;
this.cachedPrevious = next.tail;
Expand Down Expand Up @@ -287,7 +294,7 @@ public boolean hasNext() {
// start search for the next, sadly because effects don't make a clean chain,
// there can be many effects with no transactions recorded
while (this.effectIterator.hasNext()) {
final ResultingTransactionBySideEffect next = this.effectIterator.next();
final ResultingTransactionBySideEffect<?, ?, ?, ?> next = this.effectIterator.next();
if (next.tail != null) {
this.cachedPrevious = next.tail;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
import java.util.Iterator;
import java.util.Optional;

public class ResultingTransactionBySideEffect {
public final ProcessingSideEffect effect;
public class ResultingTransactionBySideEffect<T, C, A extends ProcessingSideEffect.Args, @Nullable R> {
public final ProcessingSideEffect<T, C, A, @Nullable R> effect;
@Nullable GameTransaction<@NonNull ?> head;
@Nullable GameTransaction<@NonNull ?> tail;

public ResultingTransactionBySideEffect(final ProcessingSideEffect effect) {
public ResultingTransactionBySideEffect(final ProcessingSideEffect<T, C, A, @Nullable R> effect) {
this.effect = effect;
}

Expand Down
Loading

0 comments on commit a36f6a7

Please sign in to comment.