#971: Remove strong chunk reference in PDC

A previous fix for SPIGOT-6814 implemented a callback function for the
PDC implementation that could be set to actively define a chunk as
unsaved, allowing chunks that have not been mutated through block
changes to still require saving if the chunks pdc was mutated.

This implementation however would pass a callback that references the
chunk access internally, meaning the PDC now actively holds onto a
callback that holds a reference to the entire chunk.

Aditionally, this change also impacted the pdc for item metas and
entities for really no reason whatsoever.

This commit re-implements the fix by introducing a new child of the pdc
implementation that the chunk now uses as its pdc. This specific
implementation maintains a dirty flag that is set to `true` on any form
of mutation and set back to false by the chunk that owns the PDC
whenever the chunk itself is flag as no longer dirty.

By: Bjarne Koll <lynxplay101@gmail.com>
This commit is contained in:
CraftBukkit/Spigot
2021-12-05 08:52:51 +11:00
parent 14215fdadd
commit 24b8f3c641
4 changed files with 88 additions and 35 deletions

View File

@@ -6,25 +6,37 @@
+ // CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading.
+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
+ public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
+ public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(DATA_TYPE_REGISTRY);
+ // CraftBukkit end
+
public IChunkAccess(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter, LevelHeightAccessor levelheightaccessor, IRegistry<BiomeBase> iregistry, long i, @Nullable ChunkSection[] achunksection, @Nullable BlendingData blendingdata) {
this.chunkPos = chunkcoordintpair;
this.upgradeData = chunkconverter;
@@ -94,7 +99,12 @@
@@ -94,7 +99,11 @@
}
replaceMissingSections(levelheightaccessor, iregistry, this.sections);
+ // CraftBukkit start
+ this.biomeRegistry = iregistry;
+ this.persistentDataContainer.setCallback(() -> setUnsaved(true)); // CraftBukkit - SPIGOT-6814: Handle cases were only persistentData is saved
}
+ public final IRegistry<BiomeBase> biomeRegistry;
+ // CraftBukkit end
private static void replaceMissingSections(LevelHeightAccessor levelheightaccessor, IRegistry<BiomeBase> iregistry, ChunkSection[] achunksection) {
for (int i = 0; i < achunksection.length; ++i) {
@@ -258,10 +267,11 @@
public void setUnsaved(boolean flag) {
this.unsaved = flag;
+ if (!flag) this.persistentDataContainer.dirty(false); // CraftBukkit - SPIGOT-6814: chunk was saved, pdc is no longer dirty
}
public boolean isUnsaved() {
- return this.unsaved;
+ return this.unsaved || this.persistentDataContainer.dirty(); // CraftBukkit - SPIGOT-6814: chunk is unsaved if pdc was mutated
}
public abstract ChunkStatus getStatus();
@@ -394,6 +404,27 @@
}
}