mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-26 23:26:45 +01:00
Update Flag containers. Add javadocs. Add missing methods.
This commit is contained in:
parent
e9c69dc80c
commit
83a33d2b41
@ -8,15 +8,30 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@EqualsAndHashCode(of = "flagMap") public class FlagContainer {
|
/**
|
||||||
|
* Container type for {@link PlotFlag plot flags}.
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(of = "flagMap") @SuppressWarnings("unused") public class FlagContainer {
|
||||||
|
|
||||||
private final FlagContainer parentContainer;
|
private final FlagContainer parentContainer;
|
||||||
private final Map<Class<?>, PlotFlag<?, ?>> flagMap = new HashMap<>();
|
private final Map<Class<?>, PlotFlag<?, ?>> flagMap = new HashMap<>();
|
||||||
|
private final PlotFlagUpdateHandler plotFlagUpdateHandler;
|
||||||
|
|
||||||
public FlagContainer(@Nullable final FlagContainer parentContainer) {
|
public FlagContainer(@Nullable final FlagContainer parentContainer,
|
||||||
|
@Nullable PlotFlagUpdateHandler plotFlagUpdateHandler) {
|
||||||
this.parentContainer = parentContainer;
|
this.parentContainer = parentContainer;
|
||||||
|
this.plotFlagUpdateHandler = plotFlagUpdateHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FlagContainer(@Nullable final FlagContainer parentContainer) {
|
||||||
|
this(parentContainer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the parent container (if the container has a parent)
|
||||||
|
*
|
||||||
|
* @return Parent container
|
||||||
|
*/
|
||||||
public FlagContainer getParentContainer() {
|
public FlagContainer getParentContainer() {
|
||||||
return this.parentContainer;
|
return this.parentContainer;
|
||||||
}
|
}
|
||||||
@ -25,24 +40,68 @@ import java.util.Map;
|
|||||||
return this.flagMap;
|
return this.flagMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an immutable view of the underlying flag map
|
||||||
|
*
|
||||||
|
* @return Immutable flag map
|
||||||
|
*/
|
||||||
public Map<Class<?>, PlotFlag<?, ?>> getFlagMap() {
|
public Map<Class<?>, PlotFlag<?, ?>> getFlagMap() {
|
||||||
return ImmutableMap.<Class<?>, PlotFlag<?, ?>>builder().putAll(this.flagMap).build();
|
return ImmutableMap.<Class<?>, PlotFlag<?, ?>>builder().putAll(this.flagMap).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFlag(final PlotFlag<?, ? extends PlotFlag<?, ?>> flag) {
|
/**
|
||||||
|
* Add a flag to the container
|
||||||
|
*
|
||||||
|
* @param flag Flag to add
|
||||||
|
* @see #addAll(Collection) to add multiple flags
|
||||||
|
*/
|
||||||
|
public <V, T extends PlotFlag<V, ?>> void addFlag(final T flag) {
|
||||||
this.flagMap.put(flag.getClass(), flag);
|
this.flagMap.put(flag.getClass(), flag);
|
||||||
|
if (this.plotFlagUpdateHandler != null) {
|
||||||
|
this.plotFlagUpdateHandler.handle(flag, PlotFlagUpdateType.FLAG_ADDED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a flag from the container
|
||||||
|
*
|
||||||
|
* @param flag Flag to remove
|
||||||
|
*/
|
||||||
|
public <V, T extends PlotFlag<V, ?>> void removeFlag(final T flag) {
|
||||||
|
this.flagMap.remove(flag.getClass());
|
||||||
|
if (this.plotFlagUpdateHandler != null) {
|
||||||
|
this.plotFlagUpdateHandler.handle(flag, PlotFlagUpdateType.FLAG_REMOVED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all flags to the container
|
||||||
|
*
|
||||||
|
* @param flags Flags to add
|
||||||
|
* @see #addFlag(PlotFlag) to add a single flagg
|
||||||
|
*/
|
||||||
public void addAll(final Collection<PlotFlag<?, ?>> flags) {
|
public void addAll(final Collection<PlotFlag<?, ?>> flags) {
|
||||||
for (final PlotFlag<?, ?> flag : flags) {
|
for (final PlotFlag<?, ?> flag : flags) {
|
||||||
this.addFlag(flag);
|
this.addFlag(flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a collection of all recognized plot flags. Will by
|
||||||
|
* default use the values contained in {@link GlobalFlagContainer}.
|
||||||
|
*
|
||||||
|
* @return All recognized flag types
|
||||||
|
*/
|
||||||
public Collection<PlotFlag<?, ?>> getRecognizedPlotFlags() {
|
public Collection<PlotFlag<?, ?>> getRecognizedPlotFlags() {
|
||||||
return this.getHighestClassContainer().getFlagMap().values();
|
return this.getHighestClassContainer().getFlagMap().values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively seek for the highest order flag container.
|
||||||
|
* This will by default return {@link GlobalFlagContainer}.
|
||||||
|
*
|
||||||
|
* @return Highest order class container.
|
||||||
|
*/
|
||||||
public final FlagContainer getHighestClassContainer() {
|
public final FlagContainer getHighestClassContainer() {
|
||||||
if (this.getParentContainer() != null) {
|
if (this.getParentContainer() != null) {
|
||||||
return this.getParentContainer();
|
return this.getParentContainer();
|
||||||
@ -50,6 +109,10 @@ import java.util.Map;
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has the same functionality as {@link #getFlag(Class)}, but
|
||||||
|
* with erased generic types.
|
||||||
|
*/
|
||||||
public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
|
public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
|
||||||
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
|
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
|
||||||
if (flag != null) {
|
if (flag != null) {
|
||||||
@ -62,10 +125,20 @@ import java.util.Map;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> PlotFlag<T, ?> getFlag(final Class<? extends PlotFlag<T, ?>> flagClass) {
|
/**
|
||||||
|
* Query all levels of flag containers for a flag. This guarantees that a flag
|
||||||
|
* instance is returned, as long as it is registered in the
|
||||||
|
* {@link GlobalFlagContainer global flag container}.
|
||||||
|
*
|
||||||
|
* @param flagClass Flag class to query for
|
||||||
|
* @param <V> Flag value type
|
||||||
|
* @param <T> Flag type
|
||||||
|
* @return Flag instance
|
||||||
|
*/
|
||||||
|
public <V, T extends PlotFlag<V, ?>> T getFlag(final Class<? extends T> flagClass) {
|
||||||
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
|
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
|
||||||
if (flag != null) {
|
if (flag != null) {
|
||||||
return (PlotFlag<T, ?>) flag;
|
return castUnsafe(flag);
|
||||||
} else {
|
} else {
|
||||||
if (getParentContainer() != null) {
|
if (getParentContainer() != null) {
|
||||||
return getParentContainer().getFlag(flagClass);
|
return getParentContainer().getFlag(flagClass);
|
||||||
@ -74,4 +147,55 @@ import java.util.Map;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for flag existence in this flag container instance.
|
||||||
|
*
|
||||||
|
* @param flagClass Flag class to query for
|
||||||
|
* @param <V> Flag value type
|
||||||
|
* @param <T> Flag type
|
||||||
|
* @return The flag instance, if it exists in this container, else null.
|
||||||
|
*/
|
||||||
|
@Nullable public <V, T extends PlotFlag<V, ?>> T queryLocal(final Class<? extends T> flagClass) {
|
||||||
|
final PlotFlag<?, ?> localFlag = this.flagMap.get(flagClass);
|
||||||
|
if (localFlag == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return castUnsafe(localFlag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ALL")
|
||||||
|
protected static <V, T extends PlotFlag<V, ?>> T castUnsafe(final PlotFlag<?, ?> flag) {
|
||||||
|
return (T) flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for update events in {@link FlagContainer flag containers}.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface public interface PlotFlagUpdateHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act on the flag update event
|
||||||
|
* @param plotFlag Plot flag
|
||||||
|
* @param type Update type
|
||||||
|
*/
|
||||||
|
void handle(PlotFlag<?, ?> plotFlag, PlotFlagUpdateType type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update event types used in {@link PlotFlagUpdateHandler}.
|
||||||
|
*/
|
||||||
|
public enum PlotFlagUpdateType {
|
||||||
|
/**
|
||||||
|
* A flag was added to a plot container
|
||||||
|
*/
|
||||||
|
FLAG_ADDED,
|
||||||
|
/**
|
||||||
|
* A flag was removed from a plot container
|
||||||
|
*/
|
||||||
|
FLAG_REMOVED
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,21 @@ import java.util.Map;
|
|||||||
public final class GlobalFlagContainer extends FlagContainer {
|
public final class GlobalFlagContainer extends FlagContainer {
|
||||||
|
|
||||||
@Getter private static final GlobalFlagContainer instance = new GlobalFlagContainer();
|
@Getter private static final GlobalFlagContainer instance = new GlobalFlagContainer();
|
||||||
|
private static Map<String, Class<?>> stringClassMap = new HashMap<>();
|
||||||
|
|
||||||
private final Map<String, Class<?>> stringClassMap = new HashMap<>();
|
private GlobalFlagContainer() {
|
||||||
|
super(null, (flag, type) -> {
|
||||||
|
if (type == PlotFlagUpdateType.FLAG_ADDED) {
|
||||||
|
stringClassMap.put(flag.getName().toLowerCase(Locale.ENGLISH), flag.getClass());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Register all default flags here
|
||||||
|
this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
|
||||||
|
this.addFlag(MusicFlag.MUSIC_FLAG_NONE);
|
||||||
|
this.addFlag(FlightFlag.FLIGHT_FLAG_FALSE);
|
||||||
|
this.addFlag(UntrustedVisitFlag.UNTRUSTED_VISIT_FLAG_TRUE);
|
||||||
|
this.addFlag(DenyExitFlag.DENY_EXIT_FLAG_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
|
@Override public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
|
||||||
final PlotFlag<?, ?> flag = super.getFlagErased(flagClass);
|
final PlotFlag<?, ?> flag = super.getFlagErased(flagClass);
|
||||||
@ -28,33 +41,19 @@ public final class GlobalFlagContainer extends FlagContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public <T> PlotFlag<T, ?> getFlag(Class<? extends PlotFlag<T, ?>> flagClass) {
|
@Nonnull @Override
|
||||||
|
public <V, T extends PlotFlag<V, ?>> T getFlag(Class<? extends T> flagClass) {
|
||||||
final PlotFlag<?, ?> flag = super.getFlag(flagClass);
|
final PlotFlag<?, ?> flag = super.getFlag(flagClass);
|
||||||
if (flag != null) {
|
if (flag != null) {
|
||||||
return (PlotFlag<T, ?>) flag;
|
return castUnsafe(flag);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
|
throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
|
||||||
+ " must be present in the global flag container.", flagClass.getSimpleName()));
|
+ " must be present in the global flag container.", flagClass.getSimpleName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlobalFlagContainer() {
|
|
||||||
super(null);
|
|
||||||
// Register all default flags here
|
|
||||||
this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
|
|
||||||
this.addFlag(MusicFlag.MUSIC_FLAG_NONE);
|
|
||||||
this.addFlag(FlightFlag.FLIGHT_FLAG_FALSE);
|
|
||||||
this.addFlag(UntrustedVisitFlag.UNTRUSTED_VISIT_FLAG_TRUE);
|
|
||||||
this.addFlag(DenyExitFlag.DENY_EXIT_FLAG_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void addFlag(PlotFlag<?, ?> flag) {
|
|
||||||
super.addFlag(flag);
|
|
||||||
this.stringClassMap.put(flag.getName().toLowerCase(Locale.ENGLISH), flag.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?> getFlagClassFromString(final String name) {
|
public Class<?> getFlagClassFromString(final String name) {
|
||||||
return this.stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
|
return stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlotFlag<?, ?> getFlagFromString(final String name) {
|
public PlotFlag<?, ?> getFlagFromString(final String name) {
|
||||||
|
Loading…
Reference in New Issue
Block a user