Wolfizen icon

Custom MessageChannel Implementation [3/3]

Wolfizen | PRO | 01/12/16 01:48:45 AM UTC | 0 ⭐ | 265 👁️ | Never ⏰ | []
Java |

5.77 KB

|

None

|

0 👍

/

0 👎

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