Allow viewing predicates to be null to properly support `hasPredictableViewers`

This commit is contained in:
themode 2022-03-03 16:32:52 +01:00
parent baa603ba41
commit fff0e3d97a
3 changed files with 22 additions and 17 deletions

View File

@ -357,7 +357,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ta
}
@ApiStatus.Experimental
public void updateViewableRule(@NotNull Predicate<Player> predicate) {
public void updateViewableRule(@Nullable Predicate<Player> predicate) {
this.viewEngine.viewableOption.updateRule(predicate);
}
@ -388,7 +388,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ta
}
@ApiStatus.Experimental
public void updateViewerRule(@NotNull Predicate<Entity> predicate) {
public void updateViewerRule(@Nullable Predicate<Entity> predicate) {
this.viewEngine.viewerOption.updateRule(predicate);
}

View File

@ -103,7 +103,7 @@ final class EntityView {
public boolean hasPredictableViewers() {
// Verify if this entity's viewers can be predicted from surrounding entities
synchronized (mutex) {
return viewableOption.isAuto() && viewableOption.predictable && manualViewers.isEmpty();
return viewableOption.isAuto() && viewableOption.predicate == null && manualViewers.isEmpty();
}
}
@ -138,9 +138,8 @@ final class EntityView {
// 1 if auto, 0 if manual
private volatile int auto = 1;
// The custom rule used to determine if an entity is viewable.
private Predicate<T> predicate = entity -> true;
private boolean predictable = true;
// null if auto-viewable
private Predicate<T> predicate = null;
public Option(EntityTracker.Target<T> target, Predicate<T> loopPredicate,
Consumer<T> addition, Consumer<T> removal) {
@ -155,7 +154,8 @@ final class EntityView {
}
public boolean predicate(T entity) {
return predicate.test(entity);
final Predicate<T> predicate = this.predicate;
return predicate == null || predicate.test(entity);
}
public boolean isRegistered(T entity) {
@ -194,14 +194,19 @@ final class EntityView {
}
void updateRule0(Predicate<T> predicate) {
this.predictable = false;
update(loopPredicate, entity -> {
final boolean result = predicate.test(entity);
if (result != isRegistered(entity)) {
if (result) addition.accept(entity);
else removal.accept(entity);
}
});
if (predicate == null) {
update(loopPredicate, entity -> {
if (!isRegistered(entity)) addition.accept(entity);
});
} else {
update(loopPredicate, entity -> {
final boolean result = predicate.test(entity);
if (result != isRegistered(entity)) {
if (result) addition.accept(entity);
else removal.accept(entity);
}
});
}
}
private void update(Predicate<T> visibilityPredicate,

View File

@ -115,10 +115,10 @@ public class EntityViewIntegrationTest {
}
// CHANGE RULE
{
// May cause all subsequent `hasPredictableViewers` to return false
// due to the server not able detect always-true predicate
p.updateViewableRule(player -> false);
assertFalse(p.hasPredictableViewers());
p.updateViewableRule(null);
assertTrue(p.hasPredictableViewers());
}
}