mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-30 13:14:06 +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.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 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.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() {
|
||||
return this.parentContainer;
|
||||
}
|
||||
@ -25,24 +40,68 @@ import java.util.Map;
|
||||
return this.flagMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an immutable view of the underlying flag map
|
||||
*
|
||||
* @return Immutable flag map
|
||||
*/
|
||||
public Map<Class<?>, PlotFlag<?, ?>> getFlagMap() {
|
||||
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);
|
||||
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) {
|
||||
for (final PlotFlag<?, ?> flag : flags) {
|
||||
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() {
|
||||
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() {
|
||||
if (this.getParentContainer() != null) {
|
||||
return this.getParentContainer();
|
||||
@ -50,6 +109,10 @@ import java.util.Map;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the same functionality as {@link #getFlag(Class)}, but
|
||||
* with erased generic types.
|
||||
*/
|
||||
public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
|
||||
final PlotFlag<?, ?> flag = this.flagMap.get(flagClass);
|
||||
if (flag != null) {
|
||||
@ -62,10 +125,20 @@ import java.util.Map;
|
||||
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);
|
||||
if (flag != null) {
|
||||
return (PlotFlag<T, ?>) flag;
|
||||
return castUnsafe(flag);
|
||||
} else {
|
||||
if (getParentContainer() != null) {
|
||||
return getParentContainer().getFlag(flagClass);
|
||||
@ -74,4 +147,55 @@ import java.util.Map;
|
||||
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 {
|
||||
|
||||
@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) {
|
||||
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);
|
||||
if (flag != null) {
|
||||
return (PlotFlag<T, ?>) flag;
|
||||
return castUnsafe(flag);
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
|
||||
+ " 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) {
|
||||
return this.stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
|
||||
return stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public PlotFlag<?, ?> getFlagFromString(final String name) {
|
||||
|
Loading…
Reference in New Issue
Block a user