Add fallback value to queryMapValue, use Flag$chooseValue

This commit is contained in:
JOO200 2020-10-18 14:07:00 +02:00 committed by wizjany
parent b70f5a73ce
commit 88c91ce3fc
5 changed files with 58 additions and 9 deletions

View File

@ -143,6 +143,28 @@ public interface ApplicableRegionSet extends Iterable<ProtectedRegion> {
@Nullable
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key);
/**
* Get the effective value for a key in a {@link MapFlag}. If there are multiple values
* (for example, if there are multiple regions with the same priority
* but with different farewell messages set, there would be multiple
* completing values), then the selected (or "winning") value will be undefined.
*
* <p>A subject can be provided that is used to determine whether the value
* of a flag on a particular region should be used. For example, if a
* flag's region group is set to {@link RegionGroup#MEMBERS} and the given
* subject is not a member, then the region would be skipped when
* querying that flag. If {@code null} is provided for the subject, then
* only flags that use {@link RegionGroup#ALL},
* {@link RegionGroup#NON_MEMBERS}, etc. will apply.</p>
*
* @param subject an optional subject, which would be used to determine the region group to apply
* @param flag the flag of type {@link MapFlag}
* @param key the key for the map flag
* @return a value, which could be {@code null}
*/
@Nullable
<V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback);
/**
* Get the effective values for a flag, returning a collection of all
* values. It is up to the caller to determine which value, if any,

View File

@ -70,8 +70,14 @@ public <V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag) {
@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
return queryMapValue(subject, flag, key, null);
}
@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
Map<K, V> defaultVal = flag.getDefault();
return defaultVal != null ? defaultVal.get(key) : null;
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
}
@SuppressWarnings("unchecked")

View File

@ -245,11 +245,12 @@ public <V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag) {
* @return a value, which could be {@code null}
*/
@Nullable
public <V, T> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<T, V> flag, T key) {
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, Flag<V> fallback) {
checkNotNull(flag);
checkNotNull(key);
V value = null;
Map<ProtectedRegion, V> consideredValues = new HashMap<>();
Map<ProtectedRegion, V> fallbackValues = new HashMap<>();
int minimumPriority = Integer.MIN_VALUE;
Set<ProtectedRegion> ignoredParents = new HashSet<>();
@ -266,23 +267,31 @@ public <V, T> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<T, V>
if (effectiveValue != null) {
minimumPriority = getPriority(region);
value = effectiveValue;
consideredValues.put(region, effectiveValue);
} else {
effectiveValue = getEffectiveFlag(region, fallback, subject);
if (effectiveValue != null) {
minimumPriority = getPriority(region);
fallbackValues.put(region, effectiveValue);
}
}
addParents(ignoredParents, region);
}
return value;
V finalValue = flag.getValueFlag().chooseValue(consideredValues.values());
if (finalValue == null) return fallback.chooseValue(fallbackValues.values());
return finalValue;
}
@Nullable
private <V, T> V getEffectiveMapValue(ProtectedRegion region, MapFlag<T, V> mapFlag, T key, RegionAssociable subject) {
private <V, K> V getEffectiveMapValue(ProtectedRegion region, MapFlag<K, V> mapFlag, K key, RegionAssociable subject) {
List<ProtectedRegion> seen = new ArrayList<>();
ProtectedRegion current = region;
while (current != null) {
seen.add(current);
Map<T, V> mapValue = current.getFlag(mapFlag);
Map<K, V> mapValue = current.getFlag(mapFlag);
if (mapValue != null && mapValue.containsKey(key)) {
boolean use = true;

View File

@ -64,8 +64,14 @@ public <V> V queryValue(@Nullable RegionAssociable subject, Flag<V> flag) {
@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
return queryMapValue(subject, flag, key, null);
}
@Nullable
@Override
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, @Nullable Flag<V> fallback) {
Map<K, V> defaultVal = flag.getDefault();
return defaultVal != null ? defaultVal.get(key) : null;
return defaultVal != null ? defaultVal.get(key) : fallback != null ? fallback.getDefault() : null;
}
@SuppressWarnings("unchecked")

View File

@ -112,7 +112,13 @@ public <V> Collection<V> queryAllValues(@Nullable RegionAssociable subject, Flag
@Override
@Nullable
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key) {
return flagValueCalculator.queryMapValue(subject, flag, key);
return flagValueCalculator.queryMapValue(subject, flag, key, null);
}
@Override
@Nullable
public <V, K> V queryMapValue(@Nullable RegionAssociable subject, MapFlag<K, V> flag, K key, Flag<V> fallback) {
return flagValueCalculator.queryMapValue(subject, flag, key, fallback);
}
@Override