import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.channel.MessageReceiver;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class TextChannel implements MessageChannel<MessageReceiver,Text>, MessageReceiver {
// Static
public static final TextChannel TO_NONE = new TextChannel(Stream::of);
public static TextChannel.Mutable from(MessageReceiver... recipients) {
return fromCollection(Arrays.asList(recipients));
}
public static <I extends MessageReceiver> TextChannel.Mutable fromCollection(Collection<I> recipients) {
Set<MessageReceiver> recipientsSet = Collections.newSetFromMap(new WeakHashMap<>());
recipientsSet.addAll(recipients);
return new TextChannel.Mutable(recipientsSet);
}
public static <I extends MessageReceiver> TextChannel fromIterable(Supplier<Iterable<I>> iterableSupplier) {
return fromStream(() -> StreamSupport.stream(iterableSupplier.get().spliterator(), false));
}
public static TextChannel.SpongeWrapper fromSpongeChannel(org.spongepowered.api.text.channel.MessageChannel spongeMessageChannel) {
return new TextChannel.SpongeWrapper(spongeMessageChannel);
}
public static <I extends MessageReceiver> TextChannel fromStream(Supplier<Stream<I>> streamSupplier) {
return new TextChannel(streamSupplier);
}
// Class
private final Supplier<Stream<MessageReceiver>> recipientsSupplier;
private TextChannel.SpongeUnwrapper wrapperMessageChannel = null;
@SuppressWarnings("unchecked") // Cast is safe
protected <I extends MessageReceiver> TextChannel(@Nullable Supplier<Stream<I>> recipientsSupplier) {
this.recipientsSupplier = recipientsSupplier == null ? Stream::of : (Supplier<Stream<MessageReceiver>>) (Supplier<?>) recipientsSupplier;
}
/**
* Converts this TextChannel into a SpongeAPI {@link org.spongepowered.api.text.channel.MessageChannel MessageChannel} for use in the Sponge ecosystem.
*
* @return A MessageChannel described by this TextChannel
*/
@Override
public org.spongepowered.api.text.channel.MessageChannel getMessageChannel() {
// Create the subclass on-demand, save object for future use.
if (wrapperMessageChannel == null) wrapperMessageChannel = new TextChannel.SpongeUnwrapper(this);
return wrapperMessageChannel;
}
@Override
public Stream<MessageReceiver> getRecipients() {
return recipientsSupplier.get();
}
@Override
public void sendMessage(Text message) {
send(message);
}
@Override
public void sendTo(MessageReceiver recipient, Text message) {
// Basic loop prevention
if (recipient != this) recipient.sendMessage(message);
}
@Override
public void setMessageChannel(org.spongepowered.api.text.channel.MessageChannel channel) {
// Do nothing
}
// Subclasses
public static class Mutable extends TextChannel implements MutableMessageChannel<MessageReceiver,Text> {
private final Collection<MessageReceiver> recipients;
@SuppressWarnings("unchecked") // Cast is safe
protected <I extends MessageReceiver> Mutable(Collection<I> recipients) {
super(recipients::stream);
this.recipients = (Collection<MessageReceiver>) recipients;
}
@Override
public boolean addRecipient(MessageReceiver recipient) {
return recipients.add(recipient);
}
@Override
public void clearRecipients() {
recipients.clear();
}
@Override
public boolean removeRecipient(MessageReceiver recipient) {
return recipients.remove(recipient);
}
}
public static class SpongeWrapper extends TextChannel {
private final org.spongepowered.api.text.channel.MessageChannel spongeMessageChannel;
protected SpongeWrapper(org.spongepowered.api.text.channel.MessageChannel spongeMessageChannel) {
super(null);
this.spongeMessageChannel = spongeMessageChannel;
}
@Override
public org.spongepowered.api.text.channel.MessageChannel getMessageChannel() {
return spongeMessageChannel;
}
@Override
public Stream<MessageReceiver> getRecipients() {
return spongeMessageChannel.getMembers().stream();
}
@Override
public Optional<Text> transformMessage(@Nullable Object sender, MessageReceiver recipient, Text originalMessage) {
return spongeMessageChannel.transformMessage(sender, recipient, originalMessage);
}
}
public static class SpongeUnwapper implements org.spongepowered.api.text.channel.MessageChannel {
private final TextChannel textChannel;
protected SpongeUnwrapper(TextChannel textChannel) {
this.textChannel = textChannel;
}
@Override
public Collection<MessageReceiver> getMembers() {
return textChannel.getRecipients().collect(Collectors.toList());
}
@Override
public void send(Text original) {
textChannel.send(original);
}
@Override
public void send(@Nullable Object sender, Text original) {
textChannel.send(sender, original);
}
@Override
public Optional<Text> transformMessage(@Nullable Object sender, MessageReceiver recipient, Text original) {
return textChannel.transformMessage(sender, recipient, original);
}
}
}
Comments