Commit 4bf718669f177dfce2d1bd248920ef7c0ad2fe50
1 parent
61965517
adding MessageBus
Showing
5 changed files
with
507 additions
and
7 deletions
java/client/com/mumfrey/liteloader/client/api/LiteLoaderCoreAPIClient.java
| @@ -14,6 +14,7 @@ import com.mumfrey.liteloader.client.LiteLoaderCoreProviderClient; | @@ -14,6 +14,7 @@ import com.mumfrey.liteloader.client.LiteLoaderCoreProviderClient; | ||
| 14 | import com.mumfrey.liteloader.core.LiteLoader; | 14 | import com.mumfrey.liteloader.core.LiteLoader; |
| 15 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; | 15 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; |
| 16 | import com.mumfrey.liteloader.interfaces.ObjectFactory; | 16 | import com.mumfrey.liteloader.interfaces.ObjectFactory; |
| 17 | +import com.mumfrey.liteloader.messaging.MessageBus; | ||
| 17 | 18 | ||
| 18 | /** | 19 | /** |
| 19 | * Client side of the core API | 20 | * Client side of the core API |
| @@ -113,7 +114,8 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | @@ -113,7 +114,8 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | ||
| 113 | ( | 114 | ( |
| 114 | objectFactory.getEventBroker(), | 115 | objectFactory.getEventBroker(), |
| 115 | objectFactory.getClientPluginChannels(), | 116 | objectFactory.getClientPluginChannels(), |
| 116 | - objectFactory.getServerPluginChannels() | 117 | + objectFactory.getServerPluginChannels(), |
| 118 | + MessageBus.getInstance() | ||
| 117 | ); | 119 | ); |
| 118 | } | 120 | } |
| 119 | 121 | ||
| @@ -125,7 +127,7 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | @@ -125,7 +127,7 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | ||
| 125 | { | 127 | { |
| 126 | return ImmutableList.<Observer>of | 128 | return ImmutableList.<Observer>of |
| 127 | ( | 129 | ( |
| 128 | - this.getObjectFactory().getModPanelManager() | 130 | + this.getObjectFactory().getPanelManager() |
| 129 | ); | 131 | ); |
| 130 | } | 132 | } |
| 131 | 133 |
java/common/com/mumfrey/liteloader/core/LiteLoader.java
| @@ -46,6 +46,7 @@ import com.mumfrey.liteloader.interfaces.PanelManager; | @@ -46,6 +46,7 @@ import com.mumfrey.liteloader.interfaces.PanelManager; | ||
| 46 | import com.mumfrey.liteloader.interfaces.ObjectFactory; | 46 | import com.mumfrey.liteloader.interfaces.ObjectFactory; |
| 47 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 47 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
| 48 | import com.mumfrey.liteloader.launch.LoaderProperties; | 48 | import com.mumfrey.liteloader.launch.LoaderProperties; |
| 49 | +import com.mumfrey.liteloader.messaging.MessageBus; | ||
| 49 | import com.mumfrey.liteloader.modconfig.ConfigManager; | 50 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
| 50 | import com.mumfrey.liteloader.modconfig.Exposable; | 51 | import com.mumfrey.liteloader.modconfig.Exposable; |
| 51 | import com.mumfrey.liteloader.permissions.PermissionsManagerClient; | 52 | import com.mumfrey.liteloader.permissions.PermissionsManagerClient; |
| @@ -848,7 +849,7 @@ public final class LiteLoader | @@ -848,7 +849,7 @@ public final class LiteLoader | ||
| 848 | } | 849 | } |
| 849 | 850 | ||
| 850 | // Get the mod panel manager | 851 | // Get the mod panel manager |
| 851 | - this.panelManager = this.objectFactory.getModPanelManager(); | 852 | + this.panelManager = this.objectFactory.getPanelManager(); |
| 852 | if (this.panelManager != null) | 853 | if (this.panelManager != null) |
| 853 | { | 854 | { |
| 854 | this.panelManager.init(this.mods, this.configManager); | 855 | this.panelManager.init(this.mods, this.configManager); |
| @@ -905,15 +906,14 @@ public final class LiteLoader | @@ -905,15 +906,14 @@ public final class LiteLoader | ||
| 905 | // Set the loader branding in ClientBrandRetriever using reflection | 906 | // Set the loader branding in ClientBrandRetriever using reflection |
| 906 | LiteLoaderBootstrap.setBranding("LiteLoader"); | 907 | LiteLoaderBootstrap.setBranding("LiteLoader"); |
| 907 | 908 | ||
| 908 | - for (CoreProvider coreProvider : this.coreProviders) | ||
| 909 | - { | ||
| 910 | - coreProvider.onStartupComplete(); | ||
| 911 | - } | 909 | + this.coreProviders.all().onStartupComplete(); |
| 912 | 910 | ||
| 913 | if (this.panelManager != null) | 911 | if (this.panelManager != null) |
| 914 | { | 912 | { |
| 915 | this.panelManager.onStartupComplete(); | 913 | this.panelManager.onStartupComplete(); |
| 916 | } | 914 | } |
| 915 | + | ||
| 916 | + MessageBus.getInstance().onStartupComplete(); | ||
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | /** | 919 | /** |
java/common/com/mumfrey/liteloader/messaging/Message.java
0 → 100644
| 1 | +package com.mumfrey.liteloader.messaging; | ||
| 2 | + | ||
| 3 | +import java.util.HashMap; | ||
| 4 | +import java.util.Map; | ||
| 5 | +import java.util.regex.Pattern; | ||
| 6 | + | ||
| 7 | +import com.google.common.collect.ImmutableMap; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Class used to encapsulate a MessageBus message | ||
| 11 | + * | ||
| 12 | + * @author Adam Mummery-Smith | ||
| 13 | + */ | ||
| 14 | +public class Message | ||
| 15 | +{ | ||
| 16 | + /** | ||
| 17 | + * Regex for matching valid channels | ||
| 18 | + */ | ||
| 19 | + private static final Pattern channelPattern = Pattern.compile("^[a-z0-9]([a-z0-9_\\-]*[a-z0-9])?:[a-z0-9]([a-z0-9_\\-]*[a-z0-9])?$", Pattern.CASE_INSENSITIVE); | ||
| 20 | + | ||
| 21 | + private final String channel, replyChannel; | ||
| 22 | + private final Messenger sender; | ||
| 23 | + private final Map<String, ?> payload; | ||
| 24 | + | ||
| 25 | + Message(String channel, Object value, Messenger sender) | ||
| 26 | + { | ||
| 27 | + this(channel, value, sender, null); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + Message(String channel, Object value, Messenger sender, String replyChannel) | ||
| 31 | + { | ||
| 32 | + Message.validateChannel(channel); | ||
| 33 | + | ||
| 34 | + this.channel = channel; | ||
| 35 | + this.payload = ImmutableMap.<String, Object>of("value", value); | ||
| 36 | + this.sender = sender; | ||
| 37 | + this.replyChannel = replyChannel; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + Message(String channel, Map<String, ?> payload, Messenger sender) | ||
| 41 | + { | ||
| 42 | + this(channel, payload, sender, null); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + Message(String channel, Map<String, ?> payload, Messenger sender, String replyChannel) | ||
| 46 | + { | ||
| 47 | + Message.validateChannel(channel); | ||
| 48 | + | ||
| 49 | + this.channel = channel; | ||
| 50 | + this.payload = payload != null ? ImmutableMap.copyOf(payload) : ImmutableMap.<String, String>of(); | ||
| 51 | + this.sender = sender; | ||
| 52 | + this.replyChannel = replyChannel; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * Get the channel (fully qualified) that this message was sent on | ||
| 57 | + */ | ||
| 58 | + public String getChannel() | ||
| 59 | + { | ||
| 60 | + return this.channel; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * Get the channel category for this message | ||
| 65 | + */ | ||
| 66 | + public String getCategory() | ||
| 67 | + { | ||
| 68 | + return this.channel.substring(0, this.channel.indexOf(':')); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Get the specified reply channel (if any) for this message - may return null | ||
| 73 | + */ | ||
| 74 | + public String getReplyChannel() | ||
| 75 | + { | ||
| 76 | + return this.replyChannel; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Get the message sender (if any) for this message - may return null | ||
| 81 | + */ | ||
| 82 | + public Messenger getSender() | ||
| 83 | + { | ||
| 84 | + return this.sender; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * Get the message payload | ||
| 89 | + */ | ||
| 90 | + public Map<String, ?> getPayload() | ||
| 91 | + { | ||
| 92 | + return this.payload; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Check if this message is on the specified channel | ||
| 97 | + * | ||
| 98 | + * @param channel Full name of the channel to check against (case sensitive) | ||
| 99 | + * @return | ||
| 100 | + */ | ||
| 101 | + public boolean isChannel(String channel) | ||
| 102 | + { | ||
| 103 | + return this.channel.equals(channel); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + /** | ||
| 107 | + * Check if this message has the specified category | ||
| 108 | + * | ||
| 109 | + * @param category | ||
| 110 | + * @return | ||
| 111 | + */ | ||
| 112 | + public boolean isCategory(String category) | ||
| 113 | + { | ||
| 114 | + return this.getCategory().equals(category); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * Get (and implicit cast) a value from this message's payload | ||
| 119 | + * | ||
| 120 | + * @param key | ||
| 121 | + * @return | ||
| 122 | + */ | ||
| 123 | + @SuppressWarnings("unchecked") | ||
| 124 | + public <T> T get(String key) | ||
| 125 | + { | ||
| 126 | + return (T)this.payload.get(key); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + @SuppressWarnings("unchecked") | ||
| 130 | + public <T> T get(String key, T defaultValue) | ||
| 131 | + { | ||
| 132 | + Object value = this.payload.get(key); | ||
| 133 | + if (value != null) | ||
| 134 | + { | ||
| 135 | + return (T)value; | ||
| 136 | + } | ||
| 137 | + return defaultValue; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + /** | ||
| 141 | + * Gets the payload with the key "value", which is used with messages constructed using a string-only payload | ||
| 142 | + */ | ||
| 143 | + public <T> T getValue() | ||
| 144 | + { | ||
| 145 | + return this.get("value"); | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + public static void validateChannel(String channel) throws IllegalArgumentException | ||
| 149 | + { | ||
| 150 | + if (channel == null) | ||
| 151 | + { | ||
| 152 | + throw new IllegalArgumentException("Channel name cannot be null"); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + if (!Message.isValidChannel(channel)) | ||
| 156 | + { | ||
| 157 | + throw new IllegalArgumentException("'" + channel + "' is not a valid channel name"); | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + public static boolean isValidChannel(String channel) | ||
| 162 | + { | ||
| 163 | + return Message.channelPattern.matcher(channel).matches(); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * Build a KV map from interleaved keys and values, convenience function | ||
| 168 | + * | ||
| 169 | + * @param args | ||
| 170 | + * @return | ||
| 171 | + */ | ||
| 172 | + public static Map<String, ?> buildMap(Object... args) | ||
| 173 | + { | ||
| 174 | + Map<String, Object> payload = new HashMap<String, Object>(); | ||
| 175 | + for (int i = 0; i < args.length - 1; i += 2) | ||
| 176 | + { | ||
| 177 | + if (args[i] instanceof String) | ||
| 178 | + { | ||
| 179 | + payload.put((String)args[i], args[i + 1]); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + return payload; | ||
| 184 | + } | ||
| 185 | +} |
java/common/com/mumfrey/liteloader/messaging/MessageBus.java
0 → 100644
| 1 | +package com.mumfrey.liteloader.messaging; | ||
| 2 | + | ||
| 3 | +import java.util.Deque; | ||
| 4 | +import java.util.HashMap; | ||
| 5 | +import java.util.LinkedList; | ||
| 6 | +import java.util.List; | ||
| 7 | +import java.util.Map; | ||
| 8 | + | ||
| 9 | +import com.mumfrey.liteloader.api.InterfaceProvider; | ||
| 10 | +import com.mumfrey.liteloader.api.Listener; | ||
| 11 | +import com.mumfrey.liteloader.core.InterfaceRegistrationDelegate; | ||
| 12 | +import com.mumfrey.liteloader.core.event.HandlerList; | ||
| 13 | +import com.mumfrey.liteloader.interfaces.FastIterable; | ||
| 14 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * Intra-mod messaging bus, allows mods to send arbitrary notifications to each other without having to | ||
| 18 | + * create an explicit dependency or resort to reflection | ||
| 19 | + * | ||
| 20 | + * @author Adam Mummery-Smith | ||
| 21 | + */ | ||
| 22 | +public class MessageBus implements InterfaceProvider | ||
| 23 | +{ | ||
| 24 | + /** | ||
| 25 | + * Singleton | ||
| 26 | + */ | ||
| 27 | + private static MessageBus instance; | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * Messengers subscribed to each channel | ||
| 31 | + */ | ||
| 32 | + private final Map<String, FastIterable<Messenger>> messengers = new HashMap<String, FastIterable<Messenger>>(); | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * Pending messages dispatched pre-startup | ||
| 36 | + */ | ||
| 37 | + private final Deque<Message> messageQueue = new LinkedList<Message>(); | ||
| 38 | + | ||
| 39 | + private boolean enableMessaging = false; | ||
| 40 | + | ||
| 41 | + private MessageBus() | ||
| 42 | + { | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Get the singleton instance | ||
| 47 | + */ | ||
| 48 | + public static MessageBus getInstance() | ||
| 49 | + { | ||
| 50 | + if (MessageBus.instance == null) | ||
| 51 | + { | ||
| 52 | + MessageBus.instance = new MessageBus(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + return MessageBus.instance; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /* (non-Javadoc) | ||
| 59 | + * @see com.mumfrey.liteloader.api.InterfaceProvider#getListenerBaseType() | ||
| 60 | + */ | ||
| 61 | + @Override | ||
| 62 | + public Class<? extends Listener> getListenerBaseType() | ||
| 63 | + { | ||
| 64 | + return Listener.class; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + /* (non-Javadoc) | ||
| 68 | + * @see com.mumfrey.liteloader.api.InterfaceProvider#registerInterfaces(com.mumfrey.liteloader.core.InterfaceRegistrationDelegate) | ||
| 69 | + */ | ||
| 70 | + @Override | ||
| 71 | + public void registerInterfaces(InterfaceRegistrationDelegate delegate) | ||
| 72 | + { | ||
| 73 | + delegate.registerInterface(Messenger.class); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /* (non-Javadoc) | ||
| 77 | + * @see com.mumfrey.liteloader.api.InterfaceProvider#initProvider() | ||
| 78 | + */ | ||
| 79 | + @Override | ||
| 80 | + public void initProvider() | ||
| 81 | + { | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + /** | ||
| 85 | + * | ||
| 86 | + */ | ||
| 87 | + public void onStartupComplete() | ||
| 88 | + { | ||
| 89 | + this.enableMessaging = true; | ||
| 90 | + | ||
| 91 | + while (this.messageQueue.size() > 0) | ||
| 92 | + { | ||
| 93 | + Message msg = this.messageQueue.pop(); | ||
| 94 | + this.dispatchMessage(msg); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + public void registerMessenger(Messenger messenger) | ||
| 99 | + { | ||
| 100 | + List<String> messageChannels = messenger.getMessageChannels(); | ||
| 101 | + if (messageChannels == null) | ||
| 102 | + { | ||
| 103 | + LiteLoaderLogger.warning("Listener %s returned a null channel list for getMessageChannels(), this could indicate a problem with the listener", messenger.getName()); | ||
| 104 | + return; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + for (String channel : messageChannels) | ||
| 108 | + { | ||
| 109 | + if (channel != null && Message.isValidChannel(channel)) | ||
| 110 | + { | ||
| 111 | + LiteLoaderLogger.info("Listener %s is registering MessageBus channel %s", messenger.getName(), channel); | ||
| 112 | + this.getMessengerList(channel).add(messenger); | ||
| 113 | + } | ||
| 114 | + else | ||
| 115 | + { | ||
| 116 | + LiteLoaderLogger.warning("Listener %s tried to register invalid MessageBus channel %s", messenger.getName(), channel); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + /** | ||
| 122 | + * @param message | ||
| 123 | + */ | ||
| 124 | + private void sendMessage(Message message) | ||
| 125 | + { | ||
| 126 | + if (this.enableMessaging) | ||
| 127 | + { | ||
| 128 | + this.dispatchMessage(message); | ||
| 129 | + return; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + this.messageQueue.push(message); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * @param message | ||
| 137 | + */ | ||
| 138 | + private void dispatchMessage(Message message) | ||
| 139 | + { | ||
| 140 | + try | ||
| 141 | + { | ||
| 142 | + FastIterable<Messenger> messengerList = this.messengers.get(message.getChannel()); | ||
| 143 | + if (messengerList != null) | ||
| 144 | + { | ||
| 145 | + messengerList.all().receiveMessage(message); | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | + catch (StackOverflowError err) | ||
| 149 | + { | ||
| 150 | + // A listener tried to reply on the same channel and ended up calling itself | ||
| 151 | + throw new RuntimeException("Stack overflow encountered dispatching message on channel '" + message.getChannel() + "'. Did you reply to yourself?"); | ||
| 152 | + } | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + /** | ||
| 156 | + * Get messengers for the specified channel | ||
| 157 | + * | ||
| 158 | + * @param channel | ||
| 159 | + * @return | ||
| 160 | + */ | ||
| 161 | + private FastIterable<Messenger> getMessengerList(String channel) | ||
| 162 | + { | ||
| 163 | + FastIterable<Messenger> messengerList = this.messengers.get(channel); | ||
| 164 | + if (messengerList == null) | ||
| 165 | + { | ||
| 166 | + messengerList = new HandlerList<Messenger>(Messenger.class); | ||
| 167 | + this.messengers.put(channel, messengerList); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + return messengerList; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + /** | ||
| 174 | + * Send an empty message on the specified channel, this is useful for messages which are basically just notifications | ||
| 175 | + * | ||
| 176 | + * @param channel | ||
| 177 | + */ | ||
| 178 | + public static void send(String channel) | ||
| 179 | + { | ||
| 180 | + Message message = new Message(channel, null, null); | ||
| 181 | + MessageBus.getInstance().sendMessage(message); | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * Send a message with a value on the specified channel | ||
| 186 | + * | ||
| 187 | + * @param channel | ||
| 188 | + * @param value | ||
| 189 | + */ | ||
| 190 | + public static void send(String channel, String value) | ||
| 191 | + { | ||
| 192 | + Message message = new Message(channel, value, null); | ||
| 193 | + MessageBus.getInstance().sendMessage(message); | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + /** | ||
| 197 | + * Send a message with a value on the specified channel from the specified sender | ||
| 198 | + * | ||
| 199 | + * @param channel | ||
| 200 | + * @param value | ||
| 201 | + * @param sender | ||
| 202 | + */ | ||
| 203 | + public static void send(String channel, String value, Messenger sender) | ||
| 204 | + { | ||
| 205 | + Message message = new Message(channel, value, sender); | ||
| 206 | + MessageBus.getInstance().sendMessage(message); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + /** | ||
| 210 | + * Send a message with a value on the specified channel from the specified sender | ||
| 211 | + * | ||
| 212 | + * @param channel | ||
| 213 | + * @param value | ||
| 214 | + * @param sender | ||
| 215 | + * @param replyChannel | ||
| 216 | + */ | ||
| 217 | + public static void send(String channel, String value, Messenger sender, String replyChannel) | ||
| 218 | + { | ||
| 219 | + Message message = new Message(channel, value, sender, replyChannel); | ||
| 220 | + MessageBus.getInstance().sendMessage(message); | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + /** | ||
| 224 | + * Send a message with a supplied payload on the specified channel | ||
| 225 | + * | ||
| 226 | + * @param channel | ||
| 227 | + * @param payload | ||
| 228 | + */ | ||
| 229 | + public static void send(String channel, Map<String, ?> payload) | ||
| 230 | + { | ||
| 231 | + Message message = new Message(channel, payload, null); | ||
| 232 | + MessageBus.getInstance().sendMessage(message); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + /** | ||
| 236 | + * Send a message with a supplied payload on the specified channel from the specified sender | ||
| 237 | + * | ||
| 238 | + * @param channel | ||
| 239 | + * @param payload | ||
| 240 | + * @param sender | ||
| 241 | + */ | ||
| 242 | + public static void send(String channel, Map<String, ?> payload, Messenger sender) | ||
| 243 | + { | ||
| 244 | + Message message = new Message(channel, payload, sender); | ||
| 245 | + MessageBus.getInstance().sendMessage(message); | ||
| 246 | + } | ||
| 247 | + | ||
| 248 | + /** | ||
| 249 | + * Send a message with a supplied payload on the specified channel from the specified sender | ||
| 250 | + * | ||
| 251 | + * @param channel | ||
| 252 | + * @param payload | ||
| 253 | + * @param sender | ||
| 254 | + * @param replyChannel | ||
| 255 | + */ | ||
| 256 | + public static void send(String channel, Map<String, ?> payload, Messenger sender, String replyChannel) | ||
| 257 | + { | ||
| 258 | + Message message = new Message(channel, payload, sender, replyChannel); | ||
| 259 | + MessageBus.getInstance().sendMessage(message); | ||
| 260 | + } | ||
| 261 | +} |
java/common/com/mumfrey/liteloader/messaging/Messenger.java
0 → 100644
| 1 | +package com.mumfrey.liteloader.messaging; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | + | ||
| 5 | +import com.mumfrey.liteloader.api.Listener; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * Interface for listeners that want to receive (or send) | ||
| 9 | + * | ||
| 10 | + * @author Adam Mummery-Smith | ||
| 11 | + */ | ||
| 12 | +public interface Messenger extends Listener | ||
| 13 | +{ | ||
| 14 | + /** | ||
| 15 | + * Get listening channels for this Messenger. Channel names must follow the format: | ||
| 16 | + * | ||
| 17 | + * {category}:{channel} | ||
| 18 | + * | ||
| 19 | + * where both {category} and {channel} are alpha-numeric identifiers which can contain underscore or dash | ||
| 20 | + * but must begin and end with only alpha-numeric characters: for example the following channel names are | ||
| 21 | + * valid: | ||
| 22 | + * | ||
| 23 | + * * foo:bar | ||
| 24 | + * * foo-bar:baz | ||
| 25 | + * * foo-bar:baz_derp | ||
| 26 | + * | ||
| 27 | + * The following are INVALID: | ||
| 28 | + * | ||
| 29 | + * * foo | ||
| 30 | + * * foo_:bar | ||
| 31 | + * * _foo:bar | ||
| 32 | + * | ||
| 33 | + * In general, your listener should listen on channels all beginning with the same category, which may match | ||
| 34 | + * your mod id. Channel names and categories are case-sensitive. | ||
| 35 | + * | ||
| 36 | + * @return List of channels to listen on | ||
| 37 | + */ | ||
| 38 | + public abstract List<String> getMessageChannels(); | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Called when a message matching a channel you have elected to listen on is dispatched by any agent. | ||
| 42 | + * WARNING: this method is called if you dispatch a message on a channel you are listening to, thus you should | ||
| 43 | + * AVOID replying on channels you are listening to UNLESS you specifically filter messages based on their sender: | ||
| 44 | + * | ||
| 45 | + * if (message.getSender() == this) return; | ||
| 46 | + * | ||
| 47 | + * Messages may have a null sender or payload but will never have a null channel. | ||
| 48 | + * | ||
| 49 | + * @param message | ||
| 50 | + */ | ||
| 51 | + public abstract void receiveMessage(Message message); | ||
| 52 | +} |