Cleanup use-max-prio algorithm, add tests.

This commit is contained in:
wizjany 2020-08-03 10:21:35 -04:00
parent 449145ba1f
commit ed4287ace7
3 changed files with 66 additions and 9 deletions

View File

@ -75,10 +75,19 @@ public class DelayedRegionOverlapAssociation implements RegionAssociable {
if (source == null) {
ApplicableRegionSet result = query.getApplicableRegions(location);
source = result.getRegions();
if (useMaxPriorityAssociation)
maxPriority = source.stream().mapToInt(ProtectedRegion::getPriority).max().orElse(0);
}
assert source != null;
if (useMaxPriorityAssociation) {
int best = 0;
for (ProtectedRegion region : source) {
int priority = region.getPriority();
if (priority > best) {
best = priority;
}
}
maxPriority = best;
}
}
for (ProtectedRegion region : regions) {
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
@ -88,7 +97,9 @@ public class DelayedRegionOverlapAssociation implements RegionAssociable {
if (source.contains(region)) {
if (useMaxPriorityAssociation) {
int priority = region.getPriority();
if (priority == maxPriority) return Association.OWNER;
if (priority == maxPriority) {
return Association.OWNER;
}
} else {
return Association.OWNER;
}

View File

@ -34,6 +34,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class RegionOverlapAssociation implements RegionAssociable {
private final Set<ProtectedRegion> source;
private boolean useMaxPriorityAssociation;
private int maxPriority; // only used for useMaxPriorityAssociation
/**
* Create a new instance.
@ -41,16 +43,46 @@ public class RegionOverlapAssociation implements RegionAssociable {
* @param source set of regions that input regions must be contained within
*/
public RegionOverlapAssociation(Set<ProtectedRegion> source) {
this(source, false);
}
/**
* Create a new instance.
*
* @param source set of regions that input regions must be contained within
* @param useMaxPriorityAssociation whether to use the max priority from regions to determine association
*/
public RegionOverlapAssociation(Set<ProtectedRegion> source, boolean useMaxPriorityAssociation) {
checkNotNull(source);
this.source = source;
this.useMaxPriorityAssociation = useMaxPriorityAssociation;
int best = 0;
for (ProtectedRegion region : source) {
int priority = region.getPriority();
if (priority > best) {
best = priority;
}
}
this.maxPriority = best;
}
@Override
public Association getAssociation(List<ProtectedRegion> regions) {
for (ProtectedRegion region : regions) {
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty()) || source.contains(region)) {
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
return Association.OWNER;
}
if (source.contains(region)) {
if (useMaxPriorityAssociation) {
int priority = region.getPriority();
if (priority == maxPriority) {
return Association.OWNER;
}
} else {
return Association.OWNER;
}
}
}
return Association.NON_MEMBER;

View File

@ -38,10 +38,14 @@ import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@RunWith(Parameterized.class)
public abstract class RegionOverlapTest {
static String COURTYARD_ID = "courtyard";
static String FOUNTAIN_ID = "fountain";
@ -60,6 +64,14 @@ public abstract class RegionOverlapTest {
TestPlayer player1;
TestPlayer player2;
@Parameterized.Parameters(name = "{index}: useMaxPrio = {0}")
public static Iterable<Object[]> params() {
return Arrays.asList(new Object[][]{{true}, {false}});
}
@Parameterized.Parameter
public boolean useMaxPriorityAssociation;
protected FlagRegistry getFlagRegistry() {
return WorldGuard.getInstance().getFlagRegistry();
}
@ -105,6 +117,7 @@ public abstract class RegionOverlapTest {
ProtectedRegion region = new ProtectedPolygonalRegion(COURTYARD_ID, points, 0, 10);
region.setOwners(domain);
region.setPriority(5);
manager.addRegion(region);
courtyard = region;
@ -117,6 +130,7 @@ public abstract class RegionOverlapTest {
ProtectedRegion region = new ProtectedCuboidRegion(FOUNTAIN_ID,
BlockVector3.ZERO, BlockVector3.at(5, 5, 5));
region.setMembers(domain);
region.setPriority(10);
manager.addRegion(region);
fountain = region;
@ -186,7 +200,7 @@ public abstract class RegionOverlapTest {
HashSet<ProtectedRegion> source = new HashSet<>();
source.add(courtyard);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source, useMaxPriorityAssociation);
// Outside
appl = manager.getApplicableRegions(outside);
@ -206,14 +220,14 @@ public abstract class RegionOverlapTest {
HashSet<ProtectedRegion> source = new HashSet<>();
source.add(fountain);
source.add(courtyard);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source, useMaxPriorityAssociation);
// Outside
appl = manager.getApplicableRegions(outside);
assertTrue(appl.testState(assoc, Flags.BUILD));
// Inside courtyard
appl = manager.getApplicableRegions(inCourtyard);
assertTrue(appl.testState(assoc, Flags.BUILD));
assertTrue(useMaxPriorityAssociation ^ appl.testState(assoc, Flags.BUILD));
// Inside fountain
appl = manager.getApplicableRegions(inFountain);
assertTrue(appl.testState(assoc, Flags.BUILD));
@ -224,7 +238,7 @@ public abstract class RegionOverlapTest {
ApplicableRegionSet appl;
HashSet<ProtectedRegion> source = new HashSet<>();
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source);
RegionOverlapAssociation assoc = new RegionOverlapAssociation(source, useMaxPriorityAssociation);
// Outside
appl = manager.getApplicableRegions(outside);