re-enable ChunkSectionMixin
This commit is contained in:
@@ -1,15 +1,18 @@
|
|||||||
package net.gensokyoreimagined.nitori.mixin.needs_testing.util.block_tracking;
|
package net.gensokyoreimagined.nitori.mixin.util.block_tracking;
|
||||||
|
|
||||||
import net.gensokyoreimagined.nitori.common.block.*;
|
import net.gensokyoreimagined.nitori.common.block.*;
|
||||||
import net.gensokyoreimagined.nitori.common.entity.block_tracking.ChunkSectionChangeCallback;
|
import net.gensokyoreimagined.nitori.common.entity.block_tracking.ChunkSectionChangeCallback;
|
||||||
import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
import org.spongepowered.asm.mixin.*;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@@ -30,14 +33,14 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
public PalettedContainer<BlockState> states;
|
public PalettedContainer<BlockState> states;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private short[] countsByFlag = null;
|
private short[] nitori$countsByFlag = null;
|
||||||
@Unique
|
@Unique
|
||||||
private ChunkSectionChangeCallback changeListener;
|
private ChunkSectionChangeCallback nitori$changeListener;
|
||||||
@Unique
|
@Unique
|
||||||
private short listeningMask;
|
private short nitori$listeningMask;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private static void addToFlagCount(short[] countsByFlag, BlockState state, short change) {
|
private static void nitori$addToFlagCount(short[] countsByFlag, BlockState state, short change) {
|
||||||
int flags = ((BlockStateFlagHolder) state).lithium$getAllFlags();
|
int flags = ((BlockStateFlagHolder) state).lithium$getAllFlags();
|
||||||
int i;
|
int i;
|
||||||
while ((i = Integer.numberOfTrailingZeros(flags)) < 32 && i < countsByFlag.length) {
|
while ((i = Integer.numberOfTrailingZeros(flags)) < 32 && i < countsByFlag.length) {
|
||||||
@@ -49,61 +52,27 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean lithium$mayContainAny(TrackedBlockStatePredicate trackedBlockStatePredicate) {
|
public boolean lithium$mayContainAny(TrackedBlockStatePredicate trackedBlockStatePredicate) {
|
||||||
if (this.countsByFlag == null) {
|
if (this.nitori$countsByFlag == null) {
|
||||||
fastInitClientCounts();
|
nitori$fastInitClientCounts();
|
||||||
}
|
}
|
||||||
return this.countsByFlag[trackedBlockStatePredicate.getIndex()] != (short) 0;
|
return this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] != (short) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void fastInitClientCounts() {
|
private void nitori$fastInitClientCounts() {
|
||||||
this.countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||||
for (TrackedBlockStatePredicate trackedBlockStatePredicate : BlockStateFlags.TRACKED_FLAGS) {
|
for (TrackedBlockStatePredicate trackedBlockStatePredicate : BlockStateFlags.TRACKED_FLAGS) {
|
||||||
if (this.states.maybeHas(trackedBlockStatePredicate)) {
|
if (this.states.maybeHas(trackedBlockStatePredicate)) {
|
||||||
//We haven't counted, so we just set the count so high that it never incorrectly reaches 0.
|
//We haven't counted, so we just set the count so high that it never incorrectly reaches 0.
|
||||||
//For most situations, this overestimation does not hurt client performance compared to correct counting,
|
//For most situations, this overestimation does not hurt client performance compared to correct counting,
|
||||||
this.countsByFlag[trackedBlockStatePredicate.getIndex()] = 16 * 16 * 16;
|
this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] = 16 * 16 * 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Redirect(
|
@Inject(method = "recalcBlockCounts()V", at = @At("HEAD"))
|
||||||
// method = "recalcBlockCounts()V",
|
private void createFlagCounters(CallbackInfo ci) {
|
||||||
// at = @At(
|
this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||||
// value = "INVOKE",
|
|
||||||
// target = "Lnet/minecraft/world/chunk/PalettedContainer;count(Lnet/minecraft/world/chunk/PalettedContainer$Counter;)V"
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// private void initFlagCounters(PalettedContainer<BlockState> palettedContainer, PalettedContainer.Counter<BlockState> consumer) {
|
|
||||||
// palettedContainer.count((state, count) -> {
|
|
||||||
// consumer.accept(state, count);
|
|
||||||
// addToFlagCount(this.countsByFlag, state, (short) count);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
@Shadow
|
|
||||||
short nonEmptyBlockCount;
|
|
||||||
@Shadow
|
|
||||||
private short tickingBlockCount;
|
|
||||||
@Shadow
|
|
||||||
private short tickingFluidCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author DoggySazHi
|
|
||||||
* @reason Replace the Paper implementation with Mojang + Lithium implementation
|
|
||||||
*/
|
|
||||||
@Overwrite
|
|
||||||
public void recalcBlockCounts() {
|
|
||||||
this.countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
|
||||||
|
|
||||||
BlockStateCounter lv = new BlockStateCounter();
|
|
||||||
this.states.count((state, count) -> {
|
|
||||||
lv.accept(state, count);
|
|
||||||
addToFlagCount(this.countsByFlag, state, (short) count);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.nonEmptyBlockCount = (short)lv.nonEmptyBlockCount;
|
|
||||||
this.tickingBlockCount = (short)lv.randomTickableBlockCount;
|
|
||||||
this.tickingFluidCount = (short)lv.nonEmptyFluidCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -111,7 +80,7 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
at = @At(value = "HEAD")
|
at = @At(value = "HEAD")
|
||||||
)
|
)
|
||||||
private void resetData(FriendlyByteBuf buf, CallbackInfo ci) {
|
private void resetData(FriendlyByteBuf buf, CallbackInfo ci) {
|
||||||
this.countsByFlag = null;
|
this.nitori$countsByFlag = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -130,7 +99,7 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lithium$trackBlockStateChange(BlockState newState, BlockState oldState) {
|
public void lithium$trackBlockStateChange(BlockState newState, BlockState oldState) {
|
||||||
short[] countsByFlag = this.countsByFlag;
|
short[] countsByFlag = this.nitori$countsByFlag;
|
||||||
if (countsByFlag == null) {
|
if (countsByFlag == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -143,7 +112,7 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
//blocks that are different according to the predicate (XOR). For XOR, the block counting needs to be updated
|
//blocks that are different according to the predicate (XOR). For XOR, the block counting needs to be updated
|
||||||
//as well.
|
//as well.
|
||||||
int iterateFlags = (~BlockStateFlags.LISTENING_MASK_OR & flagsXOR) |
|
int iterateFlags = (~BlockStateFlags.LISTENING_MASK_OR & flagsXOR) |
|
||||||
(BlockStateFlags.LISTENING_MASK_OR & this.listeningMask & (prevFlags | flags));
|
(BlockStateFlags.LISTENING_MASK_OR & this.nitori$listeningMask & (prevFlags | flags));
|
||||||
int flagIndex;
|
int flagIndex;
|
||||||
|
|
||||||
while ((flagIndex = Integer.numberOfTrailingZeros(iterateFlags)) < 32 && flagIndex < countsByFlag.length) {
|
while ((flagIndex = Integer.numberOfTrailingZeros(iterateFlags)) < 32 && flagIndex < countsByFlag.length) {
|
||||||
@@ -152,8 +121,8 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
if ((flagsXOR & flagBit) != 0) {
|
if ((flagsXOR & flagBit) != 0) {
|
||||||
countsByFlag[flagIndex] += (short) (1 - (((prevFlags >>> flagIndex) & 1) << 1));
|
countsByFlag[flagIndex] += (short) (1 - (((prevFlags >>> flagIndex) & 1) << 1));
|
||||||
}
|
}
|
||||||
if ((this.listeningMask & flagBit) != 0) {
|
if ((this.nitori$listeningMask & flagBit) != 0) {
|
||||||
this.listeningMask = this.changeListener.onBlockChange(flagIndex, this);
|
this.nitori$listeningMask = this.nitori$changeListener.onBlockChange(flagIndex, this);
|
||||||
}
|
}
|
||||||
iterateFlags &= ~flagBit;
|
iterateFlags &= ~flagBit;
|
||||||
}
|
}
|
||||||
@@ -161,29 +130,29 @@ public abstract class ChunkSectionMixin implements BlockCountingSection, BlockLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lithium$addToCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker, long sectionPos, Level world) {
|
public void lithium$addToCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker, long sectionPos, Level world) {
|
||||||
if (this.changeListener == null) {
|
if (this.nitori$changeListener == null) {
|
||||||
if (sectionPos == Long.MIN_VALUE || world == null) {
|
if (sectionPos == Long.MIN_VALUE || world == null) {
|
||||||
throw new IllegalArgumentException("Expected world and section pos during intialization!");
|
throw new IllegalArgumentException("Expected world and section pos during intialization!");
|
||||||
}
|
}
|
||||||
this.changeListener = ChunkSectionChangeCallback.create(sectionPos, world);
|
this.nitori$changeListener = ChunkSectionChangeCallback.create(sectionPos, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listeningMask = this.changeListener.addTracker(tracker, blockGroup);
|
this.nitori$listeningMask = this.nitori$changeListener.addTracker(tracker, blockGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lithium$removeFromCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker) {
|
public void lithium$removeFromCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker) {
|
||||||
if (this.changeListener != null) {
|
if (this.nitori$changeListener != null) {
|
||||||
this.listeningMask = this.changeListener.removeTracker(tracker, blockGroup);
|
this.nitori$listeningMask = this.nitori$changeListener.removeTracker(tracker, blockGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Unique
|
@Unique
|
||||||
public void lithium$invalidateListeningSection(SectionPos sectionPos) {
|
public void lithium$invalidateListeningSection(SectionPos sectionPos) {
|
||||||
if (this.listeningMask != 0) {
|
if (this.nitori$listeningMask != 0) {
|
||||||
this.changeListener.onChunkSectionInvalidated(sectionPos);
|
this.nitori$changeListener.onChunkSectionInvalidated(sectionPos);
|
||||||
this.listeningMask = 0;
|
this.nitori$listeningMask = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
"world.block_entity_ticking.support_cache.BlockEntityMixin",
|
"world.block_entity_ticking.support_cache.BlockEntityMixin",
|
||||||
"world.block_entity_ticking.support_cache.DirectBlockEntityTickInvokerMixin",
|
"world.block_entity_ticking.support_cache.DirectBlockEntityTickInvokerMixin",
|
||||||
"world.block_entity_ticking.support_cache.WorldChunkMixin",
|
"world.block_entity_ticking.support_cache.WorldChunkMixin",
|
||||||
"world.portal_checks.DisablePortalChecksMixin"
|
"world.portal_checks.DisablePortalChecksMixin",
|
||||||
|
"util.block_tracking.ChunkSectionMixin"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user