Skip to content

Commit

Permalink
fix: block.hopper: concurrent modification during iteration causing c…
Browse files Browse the repository at this point in the history
…ache invalidation to be skipped
  • Loading branch information
2No2Name committed Oct 28, 2022
1 parent 72786a8 commit 1d0963b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ private void initInsertInventoryTracker(World world, BlockState hopperState) {
public void setCachedState(BlockState state) {
BlockState cachedState = this.getCachedState();
super.setCachedState(state);
if (state.get(HopperBlock.FACING) != cachedState.get(HopperBlock.FACING)) {
if (this.world != null && !this.world.isClient() && state.get(HopperBlock.FACING) != cachedState.get(HopperBlock.FACING)) {
this.invalidateCachedData();
}
}
Expand All @@ -651,14 +651,15 @@ private void invalidateInsertionData() {
this.insertInventoryEntityFailedSearchTime = 0L;
}
}
this.invalidateBlockInsertionData();
}

private void invalidateBlockInsertionData() {
if (this.insertionMode == HopperCachingState.BlockInventory.REMOVAL_TRACKING_BLOCK_ENTITY) {
assert this.insertBlockInventory != null;
((InventoryChangeTracker) this.insertBlockInventory).stopListenForMajorInventoryChanges(this);
}
this.invalidateBlockInsertionData();
}

private void invalidateBlockInsertionData() {
this.insertionMode = HopperCachingState.BlockInventory.UNKNOWN;
this.insertBlockInventory = null;
this.insertInventory = null;
Expand All @@ -685,14 +686,14 @@ private void invalidateExtractionData() {
this.collectItemEntityTrackerWasEmpty = false;
}
}
this.invalidateBlockExtractionData();
}

private void invalidateBlockExtractionData() {
if (this.extractionMode == HopperCachingState.BlockInventory.REMOVAL_TRACKING_BLOCK_ENTITY) {
assert this.extractBlockInventory != null;
((InventoryChangeTracker) this.extractBlockInventory).stopListenForMajorInventoryChanges(this);
}
this.invalidateBlockExtractionData();
}

private void invalidateBlockExtractionData() {
this.extractionMode = HopperCachingState.BlockInventory.UNKNOWN;
this.extractBlockInventory = null;
this.extractInventory = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@

import me.jellysquid.mods.lithium.common.block.entity.inventory_change_tracking.InventoryChangeTracker;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
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.CallbackInfo;

@Mixin(BlockEntity.class)
public class BlockEntityMixin {

@Shadow
@Nullable
protected World world;

@Inject(
method = "markRemoved",
at = @At("RETURN")
)
private void updateStackListTracking(CallbackInfo ci) {
if (this instanceof InventoryChangeTracker inventoryChangeTracker) {
if (this.world != null && !this.world.isClient() && this instanceof InventoryChangeTracker inventoryChangeTracker) {
inventoryChangeTracker.emitRemoved();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ public void emitContentModified() {
public void emitStackListReplaced() {
ReferenceArraySet<InventoryChangeListener> listeners = this.inventoryHandlingTypeListeners;
if (listeners != null && !listeners.isEmpty()) {
listeners.forEach(inventoryChangeListener -> inventoryChangeListener.handleStackListReplaced(this));
for (InventoryChangeListener inventoryChangeListener : listeners) {
inventoryChangeListener.handleStackListReplaced(this);
}
listeners.clear();
}

if (this instanceof InventoryChangeListener listener) {
Expand All @@ -46,7 +49,10 @@ public void emitStackListReplaced() {
public void emitRemoved() {
ReferenceArraySet<InventoryChangeListener> listeners = this.inventoryHandlingTypeListeners;
if (listeners != null && !listeners.isEmpty()) {
listeners.forEach(listener -> listener.handleInventoryRemoved(this));
for (InventoryChangeListener listener : listeners) {
listener.handleInventoryRemoved(this);
}
listeners.clear();
}

if (this instanceof InventoryChangeListener listener) {
Expand Down

0 comments on commit 1d0963b

Please sign in to comment.