Skip to content

Commit 1a06c36

Browse files
committed
Cleanup some of the section code
1 parent 47bdc9f commit 1a06c36

7 files changed

Lines changed: 55 additions & 63 deletions

File tree

worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/internal/SectionBufferingExtent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ record SectionDataWithOld(
206206
Int2ObjectArrayMap<SectionDataWithOld> oldSections = new Int2ObjectArrayMap<>(entry.getValue().size());
207207
for (Int2ObjectArrayMap.Entry<SectionData> sectionEntry : entry.getValue().int2ObjectEntrySet()) {
208208
SectionData data = sectionEntry.getValue();
209-
NativeChunkSection old = chunk.setChunkSection(sectionEntry.getIntKey(), data.section);
209+
NativeChunkSection old = chunk.setChunkSection(sectionEntry.getIntKey(), data.section, data.modified);
210210
oldSections.put(sectionEntry.getIntKey(), new SectionDataWithOld(data.section, old, data.modified));
211211
}
212212
effectData.put(entry.getLongKey(), oldSections);

worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/NativeChunk.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ public interface NativeChunk {
1919
@Nullable
2020
NativeBlockState setBlockState(NativePosition blockPos, NativeBlockState newState);
2121

22-
void notifyBlockUpdate(NativePosition pos, NativeBlockState oldState, NativeBlockState newState);
23-
24-
void markBlockChanged(NativePosition pos);
25-
2622
void markSectionChanged(int index, ChunkSectionMask changed);
2723

2824
void updateHeightmaps();
@@ -45,11 +41,12 @@ public interface NativeChunk {
4541
* Replaces a chunk section in the given chunk. This method is also responsible for updating heightmaps
4642
* and creating block entities, to keep consistency with {@link #setBlockState(NativePosition, NativeBlockState)}
4743
* (the method we used to use). This is usually easily done by calling
48-
* {@link WNASharedImpl#postChunkSectionReplacement(NativeChunk, int, NativeChunkSection, NativeChunkSection)}.
44+
* {@link WNASharedImpl#postChunkSectionReplacement(NativeChunk, int, NativeChunkSection, NativeChunkSection, ChunkSectionMask)}.
4945
*
5046
* @param index the index, from 0 to the max height divided by 16
5147
* @param section the new chunk section
48+
* @param modifiedBlocks the mask of modified blocks
5249
* @return the old chunk section
5350
*/
54-
NativeChunkSection setChunkSection(int index, NativeChunkSection section);
51+
NativeChunkSection setChunkSection(int index, NativeChunkSection section, ChunkSectionMask modifiedBlocks);
5552
}

worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/NativeWorld.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package com.sk89q.worldedit.internal.wna;
2121

22-
import com.sk89q.worldedit.math.BlockVector3;
2322
import org.enginehub.linbus.tree.LinCompoundTag;
2423

2524
/**
@@ -39,6 +38,10 @@ public interface NativeWorld {
3938

4039
NativeChunk getChunk(int chunkX, int chunkZ);
4140

41+
void notifyBlockUpdate(NativePosition pos, NativeBlockState oldState, NativeBlockState newState);
42+
43+
void markBlockChanged(NativePosition pos);
44+
4245
void updateLightingForBlock(NativePosition position);
4346

4447
boolean updateTileEntity(NativePosition position, LinCompoundTag tag);

worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WNASharedImpl.java

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.sk89q.worldedit.internal.wna;
2121

2222
import com.sk89q.worldedit.WorldEditException;
23+
import com.sk89q.worldedit.internal.util.collection.ChunkSectionMask;
2324
import com.sk89q.worldedit.math.BlockVector3;
2425
import com.sk89q.worldedit.util.SideEffect;
2526
import com.sk89q.worldedit.util.SideEffectSet;
@@ -129,36 +130,36 @@ public static void applySideEffectsNoLookups(
129130
* This is a heavily modified function stripped from MC to apply WorldEdit-modifications.
130131
*
131132
* <p>
132-
* See Forge's World.markAndNotifyBlock
133+
* See NeoForge's Level.markAndNotifyBlock
133134
* </p>
134135
*/
135136
public static void markAndNotifyBlock(
136-
NativeWorld wna, NativePosition pos, NativeChunk chunk, NativeBlockState oldState, NativeBlockState newState,
137+
NativeWorld nativeWorld, NativePosition pos, NativeChunk chunk, NativeBlockState oldState, NativeBlockState newState,
137138
SideEffectSet sideEffectSet
138139
) {
139140
// Removed redundant branches
140141

141142
if (chunk.isTicking()) {
142143
if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) {
143-
chunk.notifyBlockUpdate(pos, oldState, newState);
144+
nativeWorld.notifyBlockUpdate(pos, oldState, newState);
144145
} else if (sideEffectSet.shouldApply(SideEffect.NETWORK)) {
145146
// If we want to skip entity AI, just mark the block for sending
146-
chunk.markBlockChanged(pos);
147+
nativeWorld.markBlockChanged(pos);
147148
}
148149
}
149150

150151
if (sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
151-
wna.notifyNeighbors(pos, oldState, newState);
152+
nativeWorld.notifyNeighbors(pos, oldState, newState);
152153
}
153154

154155
// Make connection updates optional
155156
if (sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
156-
wna.updateNeighbors(pos, oldState, newState, 512);
157+
nativeWorld.updateNeighbors(pos, oldState, newState, 512);
157158
}
158159

159160
// Seems used only for PoI updates
160161
if (sideEffectSet.shouldApply(SideEffect.POI_UPDATE)) {
161-
wna.onBlockStateChange(pos, oldState, newState);
162+
nativeWorld.onBlockStateChange(pos, oldState, newState);
162163
}
163164
}
164165

@@ -171,35 +172,30 @@ public static void markAndNotifyBlock(
171172
* @param index the replaced section index
172173
* @param oldSection the old section
173174
* @param newSection the new section
175+
* @param modifiedBlocks the mask of modified blocks
174176
*/
175177
public static void postChunkSectionReplacement(
176-
NativeChunk chunk, int index, NativeChunkSection oldSection, NativeChunkSection newSection
178+
NativeChunk chunk, int index, NativeChunkSection oldSection, NativeChunkSection newSection,
179+
ChunkSectionMask modifiedBlocks
177180
) {
178-
for (int secX = 0; secX < 16; secX++) {
179-
for (int secY = 0; secY < 16; secY++) {
180-
for (int secZ = 0; secZ < 16; secZ++) {
181-
NativeBlockState oldState = oldSection.getBlock(secX, secY, secZ);
182-
NativeBlockState newState = newSection.getBlock(secX, secY, secZ);
183-
if (oldState.isSame(newState)) {
184-
continue;
185-
}
186-
int chunkY = chunk.getWorld().getYForSectionIndex(index) + secY;
187-
// We skip heightmaps, they're optimized at a higher level to a single call.
188-
189-
// We skip onRemove here, will call in UPDATE side effect if necessary.
190-
191-
if (oldState.isSameBlockType(newState) && oldState.hasBlockEntity()) {
192-
chunk.removeSectionBlockEntity(secX, chunkY, secZ);
193-
}
194-
195-
// We skip onPlace here, will call in UPDATE side effect if necessary.
196-
197-
if (newState.hasBlockEntity()) {
198-
chunk.initializeBlockEntity(secX, chunkY, secZ, newState);
199-
}
200-
}
181+
modifiedBlocks.forEach((secX, secY, secZ) -> {
182+
NativeBlockState oldState = oldSection.getBlock(secX, secY, secZ);
183+
NativeBlockState newState = newSection.getBlock(secX, secY, secZ);
184+
int chunkY = chunk.getWorld().getYForSectionIndex(index) + secY;
185+
// We skip heightmaps, they're optimized at a higher level to a single call.
186+
187+
// We skip onRemove here, will call in UPDATE side effect if necessary.
188+
189+
if (oldState.isSameBlockType(newState) && oldState.hasBlockEntity()) {
190+
chunk.removeSectionBlockEntity(secX, chunkY, secZ);
201191
}
202-
}
192+
193+
// We skip onPlace here, will call in UPDATE side effect if necessary.
194+
195+
if (newState.hasBlockEntity()) {
196+
chunk.initializeBlockEntity(secX, chunkY, secZ, newState);
197+
}
198+
});
203199

204200
boolean wasOnlyAir = oldSection.isOnlyAir();
205201
boolean onlyAir = newSection.isOnlyAir();

worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinNativeChunk.java

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import net.minecraft.world.level.Level;
2020
import net.minecraft.world.level.LevelHeightAccessor;
2121
import net.minecraft.world.level.biome.Biome;
22-
import net.minecraft.world.level.block.Block;
2322
import net.minecraft.world.level.block.EntityBlock;
2423
import net.minecraft.world.level.block.entity.BlockEntity;
2524
import net.minecraft.world.level.block.state.BlockState;
@@ -98,33 +97,16 @@ public MixinNativeChunk(ChunkPos chunkPos, UpgradeData upgradeData, LevelHeightA
9897
return (NativeBlockState) setBlockState((BlockPos) blockPos, (BlockState) newState, false);
9998
}
10099

101-
public void nc$notifyBlockUpdate(NativePosition pos, NativeBlockState oldState, NativeBlockState newState) {
102-
if (getSections()[getLevel().getSectionIndex(pos.y())] != null) {
103-
getLevel().sendBlockUpdated(
104-
(BlockPos) pos, (BlockState) oldState, (BlockState) newState,
105-
Block.UPDATE_NEIGHBORS | Block.UPDATE_CLIENTS
106-
);
107-
}
108-
}
109-
110-
public void nc$markBlockChanged(NativePosition pos) {
111-
if (getSections()[getLevel().getSectionIndex(pos.y())] != null) {
112-
((ServerChunkCache) getLevel().getChunkSource()).blockChanged((BlockPos) pos);
113-
}
114-
}
115-
116100
public void nc$markSectionChanged(int index, ChunkSectionMask changed) {
117101
ChunkHolder holder = ((ServerChunkCache) getLevel().getChunkSource())
118102
.getVisibleChunkIfPresent(getPos().toLong());
119103
if (holder != null) {
120104
if (holder.changedBlocksPerSection[index] == null) {
121105
holder.hasChangedSections = true;
122-
holder.changedBlocksPerSection[index] = new ShortOpenHashSet(
123-
Math.max(ShortOpenHashSet.DEFAULT_INITIAL_SIZE, changed.cardinality())
124-
);
106+
holder.changedBlocksPerSection[index] = new ShortOpenHashSet(changed.asShortCollection());
107+
} else {
108+
holder.changedBlocksPerSection[index].addAll(changed.asShortCollection());
125109
}
126-
127-
holder.changedBlocksPerSection[index].addAll(changed.asShortCollection());
128110
}
129111
}
130112

@@ -163,12 +145,12 @@ public MixinNativeChunk(ChunkPos chunkPos, UpgradeData upgradeData, LevelHeightA
163145
return (NativeChunkSection) getSection(index);
164146
}
165147

166-
public NativeChunkSection nc$setChunkSection(int index, NativeChunkSection section) {
148+
public NativeChunkSection nc$setChunkSection(int index, NativeChunkSection section, ChunkSectionMask modifiedBlocks) {
167149
Preconditions.checkPositionIndex(index, getSectionsCount());
168150
LevelChunkSection[] chunkSections = getSections();
169151
var oldSection = (NativeChunkSection) chunkSections[index];
170152
chunkSections[index] = (LevelChunkSection) section;
171-
WNASharedImpl.postChunkSectionReplacement((NativeChunk) this, index, oldSection, section);
153+
WNASharedImpl.postChunkSectionReplacement((NativeChunk) this, index, oldSection, section, modifiedBlocks);
172154
this.unsaved = true;
173155
return oldSection;
174156
}

worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinNativeChunkSection.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.spongepowered.asm.mixin.Mixin;
3434
import org.spongepowered.asm.mixin.Mutable;
3535
import org.spongepowered.asm.mixin.Shadow;
36+
import org.spongepowered.asm.mixin.Unique;
3637

3738
@Mixin(LevelChunkSection.class)
3839
@Implements(@Interface(iface = NativeChunkSection.class, prefix = "ncs$"))
@@ -87,6 +88,7 @@ public abstract net.minecraft.world.level.block.state.BlockState getBlockState(
8788
* @param container the container to copy
8889
* @return the copied container
8990
*/
91+
@Unique
9092
private static <T> PalettedContainer<T> copyPalettedContainer(PalettedContainer<T> container) {
9193
// First init by directly moving the fields over
9294
PalettedContainer<T> copy = new PalettedContainer<>(container.registry, container.strategy, container.data);

worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinNativeWorld.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import net.minecraft.core.SectionPos;
1414
import net.minecraft.nbt.CompoundTag;
1515
import net.minecraft.resources.ResourceKey;
16+
import net.minecraft.server.level.ServerChunkCache;
1617
import net.minecraft.server.level.ServerLevel;
1718
import net.minecraft.util.profiling.ProfilerFiller;
1819
import net.minecraft.world.level.Level;
@@ -51,6 +52,17 @@ protected MixinNativeWorld(WritableLevelData levelData, ResourceKey<Level> dimen
5152
return (NativeChunk) getChunk(chunkX, chunkZ);
5253
}
5354

55+
public void nw$notifyBlockUpdate(NativePosition pos, NativeBlockState oldState, NativeBlockState newState) {
56+
sendBlockUpdated(
57+
(BlockPos) pos, (BlockState) oldState, (BlockState) newState,
58+
Block.UPDATE_NEIGHBORS | Block.UPDATE_CLIENTS
59+
);
60+
}
61+
62+
public void nw$markBlockChanged(NativePosition pos) {
63+
((ServerChunkCache) getChunkSource()).blockChanged((BlockPos) pos);
64+
}
65+
5466
public void nw$updateLightingForBlock(NativePosition position) {
5567
ProfilerFiller profilerFiller = getProfiler();
5668
profilerFiller.push("updateSkyLightSources");

0 commit comments

Comments
 (0)