Skip to content

Commit

Permalink
api: Audience.filter
Browse files Browse the repository at this point in the history
  • Loading branch information
kashike committed May 13, 2021
1 parent 9ba3b62 commit 20e1612
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
20 changes: 18 additions & 2 deletions api/src/main/java/net/kyori/adventure/audience/Audience.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@

import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collector;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.title.Title;
import net.kyori.adventure.identity.Identified;
import org.checkerframework.checker.nullness.qual.NonNull;

/**
Expand Down Expand Up @@ -134,6 +135,21 @@ public interface Audience {
return Audiences.COLLECTOR;
}

/**
* Filters this audience.
*
* <p>The returned {@code Audience} may be the same, or a completely different one.</p>
*
* @param filter the filter
* @since 4.8.0
*/
default @NonNull Audience filterAudience(final @NonNull Predicate<? super Audience> filter) {
if(filter.test(this)) {
return this;
}
return empty();
}

/**
* Executes an action against all audiences.
*
Expand All @@ -143,7 +159,7 @@ public interface Audience {
* @param action the action
* @since 4.8.0
*/
default void foreach(final @NonNull Consumer<? super Audience> action) {
default void forEachAudience(final @NonNull Consumer<? super Audience> action) {
action.accept(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package net.kyori.adventure.audience;

import java.util.function.Consumer;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.ComponentLike;
Expand All @@ -32,6 +33,10 @@
final class EmptyAudience implements Audience {
static final EmptyAudience INSTANCE = new EmptyAudience();

@Override
public void forEachAudience(final @NonNull Consumer<? super Audience> action) {
}

@Override
public void sendMessage(final @NonNull ComponentLike message) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
*/
package net.kyori.adventure.audience;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
Expand All @@ -34,6 +37,7 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.ApiStatus;

/**
Expand All @@ -57,8 +61,27 @@ public interface ForwardingAudience extends Audience {
@NonNull Iterable<? extends Audience> audiences();

@Override
default void foreach(final @NonNull Consumer<? super Audience> action) {
for(final Audience audience : this.audiences()) audience.foreach(action);
default @NonNull Audience filterAudience(final @NonNull Predicate<? super Audience> filter) {
@Nullable List<Audience> audiences = null;
for(final Audience audience : this.audiences()) {
if(filter.test(audience)) { // todo(kashike): should we test before filtering children?
final Audience filtered = audience.filterAudience(filter);
if(filtered != Audience.empty()) {
if(audiences == null) {
audiences = new ArrayList<>();
}
audiences.add(filtered);
}
}
}
return audiences != null
? Audience.audience(audiences)
: Audience.empty();
}

@Override
default void forEachAudience(final @NonNull Consumer<? super Audience> action) {
for(final Audience audience : this.audiences()) audience.forEachAudience(action);
}

@Override
Expand Down Expand Up @@ -164,8 +187,16 @@ interface Single extends ForwardingAudience {
}

@Override
default void foreach(final @NonNull Consumer<? super Audience> action) {
this.audience().foreach(action);
default @NonNull Audience filterAudience(final @NonNull Predicate<? super Audience> filter) {
final Audience audience = this.audience();
return filter.test(audience) // todo(kashike): should we be testing "audience" or "this"
? this
: Audience.empty();
}

@Override
default void forEachAudience(final @NonNull Consumer<? super Audience> action) {
this.audience().forEachAudience(action);
}

@Override
Expand Down
29 changes: 29 additions & 0 deletions api/src/test/java/net/kyori/adventure/audience/AudienceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
package net.kyori.adventure.audience;

import com.google.common.testing.EqualsTester;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand All @@ -52,6 +54,33 @@ void testOf_many() {
assertThat(((ForwardingAudience) ma).audiences()).containsExactly(a0, a1).inOrder();
}

@Test
void testForEachAudienceEmpty() {
final AtomicInteger touched = new AtomicInteger(0);
Audience.empty().forEachAudience(audience -> touched.incrementAndGet());
assertEquals(0, touched.get());
}

@Test
void testForEachAudienceForwarded() {
final AtomicInteger touched = new AtomicInteger(0);
Audience.audience(
new Audience() {
}
).forEachAudience(audience -> touched.incrementAndGet());
assertEquals(1, touched.get());
}

@Test
void testForEachAudienceForwardedOfEmpty() {
final AtomicInteger touched = new AtomicInteger(0);
Audience.audience(
Audience.empty(),
Audience.empty()
).forEachAudience(audience -> touched.incrementAndGet());
assertEquals(0, touched.get());
}

@Test
void testEquality() {
new EqualsTester()
Expand Down

0 comments on commit 20e1612

Please sign in to comment.