#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:
@@ -15,13 +15,11 @@ import org.bukkit.persistence.PersistentDataAdapterContext;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public final class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
|
||||
private static final Callback EMPTY = () -> { };
|
||||
private final Map<String, NBTBase> customDataTags = new HashMap<>();
|
||||
private final CraftPersistentDataTypeRegistry registry;
|
||||
private final CraftPersistentDataAdapterContext adapterContext;
|
||||
private Callback callback = EMPTY;
|
||||
|
||||
public CraftPersistentDataContainer(Map<String, NBTBase> customTags, CraftPersistentDataTypeRegistry registry) {
|
||||
this(registry);
|
||||
@@ -33,14 +31,6 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
this.adapterContext = new CraftPersistentDataAdapterContext(this.registry);
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
if (callback == null) {
|
||||
this.callback = EMPTY;
|
||||
return;
|
||||
}
|
||||
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, Z> void set(NamespacedKey key, PersistentDataType<T, Z> type, Z value) {
|
||||
@@ -49,7 +39,6 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
Validate.notNull(value, "The provided value for the custom value was null");
|
||||
|
||||
this.customDataTags.put(key.toString(), registry.wrap(type.getPrimitiveType(), type.toPrimitive(value, adapterContext)));
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +92,6 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
Validate.notNull(key, "The provided key for the custom value was null");
|
||||
|
||||
this.customDataTags.remove(key.toString());
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,19 +126,16 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
|
||||
public void put(String key, NBTBase base) {
|
||||
this.customDataTags.put(key, base);
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public void putAll(Map<String, NBTBase> map) {
|
||||
this.customDataTags.putAll(map);
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public void putAll(NBTTagCompound compound) {
|
||||
for (String key : compound.getAllKeys()) {
|
||||
this.customDataTags.put(key, compound.get(key));
|
||||
}
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public Map<String, NBTBase> getRaw() {
|
||||
@@ -171,9 +156,4 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
public Map<String, Object> serialize() {
|
||||
return (Map<String, Object>) CraftNBTTagConfigSerializer.serialize(toTagCompound());
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Callback {
|
||||
void onValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.bukkit.craftbukkit.persistence;
|
||||
|
||||
import java.util.Map;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
/**
|
||||
* A child class of the persistent data container that recalls if it has been
|
||||
* mutated from an external caller.
|
||||
*/
|
||||
public final class DirtyCraftPersistentDataContainer extends CraftPersistentDataContainer {
|
||||
|
||||
private boolean dirty;
|
||||
|
||||
public DirtyCraftPersistentDataContainer(Map<String, NBTBase> customTags, CraftPersistentDataTypeRegistry registry) {
|
||||
super(customTags, registry);
|
||||
}
|
||||
|
||||
public DirtyCraftPersistentDataContainer(CraftPersistentDataTypeRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
public boolean dirty() {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
public void dirty(final boolean dirty) {
|
||||
this.dirty = dirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, Z> void set(NamespacedKey key, PersistentDataType<T, Z> type, Z value) {
|
||||
super.set(key, type, value);
|
||||
this.dirty(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(NamespacedKey key) {
|
||||
super.remove(key);
|
||||
this.dirty(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String key, NBTBase base) {
|
||||
super.put(key, base);
|
||||
this.dirty(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(NBTTagCompound compound) {
|
||||
super.putAll(compound);
|
||||
this.dirty(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<String, NBTBase> map) {
|
||||
super.putAll(map);
|
||||
this.dirty(true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user