Skip to content

Commit

Permalink
fix: Item stack resurrection causing incorrect internal state of Lith…
Browse files Browse the repository at this point in the history
…iumStackList

Caused missing comparator updates and maybe a lot more, other issues
  • Loading branch information
2No2Name committed Jun 19, 2024
1 parent de2abef commit 1f97499
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@ public void changed() {
@Override
public ItemStack set(int index, ItemStack element) {
ItemStack previous = super.set(index, element);

//Handle vanilla's item stack resurrection in HopperBlockEntity extract(Hopper hopper, Inventory inventory, int slot, Direction side):
// Item stacks are set to 0 items, then back to 1. Then inventory.set(index, element) is called.
// At this point, the LithiumStackList unsubscribed from the stack when it reached 0.
// Handle: If the previous == element, and the stack is not subscribed, we handle it as if an empty stack was replaced.
if (previous == element && !element.isEmpty()) {
//noinspection unchecked
boolean notSubscribed = ((ChangePublisher<ItemStack>) (Object) previous).lithium$isSubscribedWithData(this, index);
if (!notSubscribed) {
previous = ItemStack.EMPTY;
}
}

if (previous != element) {
if (!previous.isEmpty()) {
//noinspection unchecked
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.jellysquid.mods.lithium.common.util.change_tracking;

import net.minecraft.item.ItemStack;

public interface ChangePublisher<T> {
void lithium$subscribe(ChangeSubscriber<T> subscriber, int subscriberData);

Expand All @@ -8,4 +10,8 @@ public interface ChangePublisher<T> {
default void lithium$unsubscribeWithData(ChangeSubscriber<T> subscriber, int index) {
throw new UnsupportedOperationException("Only implemented for ItemStacks");
}

default boolean lithium$isSubscribedWithData(ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
throw new UnsupportedOperationException("Only implemented for ItemStacks");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.jellysquid.mods.lithium.common.util.change_tracking;

import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -79,6 +80,13 @@ static int dataOf(ChangeSubscriber<?> subscribers, ChangeSubscriber<?> subscribe
return subscribers instanceof Multi<?> multi ? multi.subscriberDatas.getInt(multi.subscribers.indexOf(subscriber)) : subscriberData;
}

static boolean containsSubscriber(ChangeSubscriber<ItemStack> subscriber, int subscriberData, ChangeSubscriber<ItemStack> subscriber1, int subscriberData1) {
if (subscriber instanceof Multi<ItemStack> multi) {
return multi.indexOf(subscriber1, subscriberData1, true) != -1;
}
return subscriber == subscriber1 && subscriberData == subscriberData1;
}


/**
* Notify the subscriber that the publisher will be changed immediately after this call.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private void init(BlockEntityType<?> type, BlockPos pos, BlockState state, Callb
public void lithium$onComparatorAdded(Direction direction, int offset) {
byte hasComparators = this.hasComparators;
if (direction.getAxis() != Direction.Axis.Y && hasComparators != COMPARATOR_PRESENT && offset >= 1 && offset <= 2) {
this.hasComparators = 1;
this.hasComparators = COMPARATOR_PRESENT;

if (this instanceof InventoryChangeTracker inventoryChangeTracker) {
inventoryChangeTracker.lithium$emitFirstComparatorAdded();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ public abstract class ItemStackMixin implements ChangePublisher<ItemStack>, Chan
}
}

@Override
public boolean lithium$isSubscribedWithData(ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
if (this.isEmpty()) {
throw new IllegalStateException("Cannot be subscribed to an empty ItemStack!");
}

return ChangeSubscriber.containsSubscriber(this.subscriber, this.subscriberData, subscriber, subscriberData);
}

@Override
public void lithium$forceUnsubscribe(ComponentMapImpl publisher, int subscriberData) {
if (publisher != this.components) {
Expand Down

0 comments on commit 1f97499

Please sign in to comment.