mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 13:16:45 +01:00
Don't keep PlotFlagUpdateHandlers forever
This allows Plots, FlagContainers and its PlotFlagUpdateHandlers being cleaned up by the GC correctly
This commit is contained in:
parent
391476ba26
commit
5ab8d50b86
@ -85,6 +85,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.ref.Cleaner;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -127,6 +128,7 @@ public class Plot {
|
|||||||
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Plot.class.getSimpleName());
|
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Plot.class.getSimpleName());
|
||||||
private static final DecimalFormat FLAG_DECIMAL_FORMAT = new DecimalFormat("0");
|
private static final DecimalFormat FLAG_DECIMAL_FORMAT = new DecimalFormat("0");
|
||||||
private static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
|
private static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
|
||||||
|
private static final Cleaner CLEANER = Cleaner.create();
|
||||||
|
|
||||||
static Set<Plot> connected_cache;
|
static Set<Plot> connected_cache;
|
||||||
static Set<CuboidRegion> regions_cache;
|
static Set<CuboidRegion> regions_cache;
|
||||||
@ -256,6 +258,9 @@ public class Plot {
|
|||||||
this.temp = temp;
|
this.temp = temp;
|
||||||
this.flagContainer.setParentContainer(area.getFlagContainer());
|
this.flagContainer.setParentContainer(area.getFlagContainer());
|
||||||
PlotSquared.platform().injector().injectMembers(this);
|
PlotSquared.platform().injector().injectMembers(this);
|
||||||
|
// This is needed, because otherwise the Plot, the FlagContainer and its
|
||||||
|
// `this::handleUnknown` PlotFlagUpdateHandler won't get cleaned up ever
|
||||||
|
CLEANER.register(this, this.flagContainer.createCleanupHook());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,14 +27,15 @@ package com.plotsquared.core.plot.flag;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -49,8 +50,9 @@ public class FlagContainer {
|
|||||||
private final Map<String, String> unknownFlags = new HashMap<>();
|
private final Map<String, String> unknownFlags = new HashMap<>();
|
||||||
private final Map<Class<?>, PlotFlag<?, ?>> flagMap = new HashMap<>();
|
private final Map<Class<?>, PlotFlag<?, ?>> flagMap = new HashMap<>();
|
||||||
private final PlotFlagUpdateHandler plotFlagUpdateHandler;
|
private final PlotFlagUpdateHandler plotFlagUpdateHandler;
|
||||||
private final Collection<PlotFlagUpdateHandler> updateSubscribers = new ArrayList<>();
|
private final Collection<PlotFlagUpdateHandler> updateSubscribers = new HashSet<>();
|
||||||
private FlagContainer parentContainer;
|
private FlagContainer parentContainer;
|
||||||
|
private final PlotFlagUpdateHandler unknownsRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new flag container with an optional parent container and update handler.
|
* Construct a new flag container with an optional parent container and update handler.
|
||||||
@ -71,7 +73,10 @@ public class FlagContainer {
|
|||||||
this.parentContainer = parentContainer;
|
this.parentContainer = parentContainer;
|
||||||
this.plotFlagUpdateHandler = plotFlagUpdateHandler;
|
this.plotFlagUpdateHandler = plotFlagUpdateHandler;
|
||||||
if (!(this instanceof GlobalFlagContainer)) {
|
if (!(this instanceof GlobalFlagContainer)) {
|
||||||
GlobalFlagContainer.getInstance().subscribe(this::handleUnknowns);
|
this.unknownsRef = this::handleUnknowns;
|
||||||
|
GlobalFlagContainer.getInstance().subscribe(this.unknownsRef);
|
||||||
|
} else {
|
||||||
|
this.unknownsRef = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +341,23 @@ public class FlagContainer {
|
|||||||
this.unknownFlags.put(flagName.toLowerCase(Locale.ENGLISH), value);
|
this.unknownFlags.put(flagName.toLowerCase(Locale.ENGLISH), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a cleanup hook that is meant to run once this FlagContainer isn't needed anymore.
|
||||||
|
* This is to prevent memory leaks. This method is not part of the API.
|
||||||
|
*
|
||||||
|
* @return a new Runnable that cleans up once the FlagContainer isn't needed anymore.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public Runnable createCleanupHook() {
|
||||||
|
return () -> GlobalFlagContainer.getInstance().unsubscribe(unknownsRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unsubscribe(final @Nullable PlotFlagUpdateHandler updateHandler) {
|
||||||
|
if (updateHandler != null) {
|
||||||
|
this.updateSubscribers.remove(updateHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (o == this) {
|
if (o == this) {
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user