diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml
index e30b7deb73..b5bf50d355 100644
--- a/runelite-client/pom.xml
+++ b/runelite-client/pom.xml
@@ -300,6 +300,16 @@
httpmime
4.5.9
+
+ io.reactivex.rxjava2
+ rxjava
+ 2.2.10
+
+
+ com.jakewharton.rxrelay2
+ rxrelay
+ 2.1.0
+
diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java
index 1fa6aeb5b3..2993fdf108 100644
--- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java
+++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java
@@ -48,16 +48,9 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.client.account.SessionManager;
import net.runelite.client.chat.ChatMessageManager;
-import net.runelite.client.chat.CommandManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.discord.DiscordService;
-import net.runelite.client.eventbus.EventBus;
-import net.runelite.client.game.ClanManager;
-import net.runelite.client.game.ItemManager;
-import net.runelite.client.game.LootManager;
-import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.graphics.ModelOutlineRenderer;
-import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginInstantiationException;
import net.runelite.client.plugins.PluginManager;
@@ -65,18 +58,14 @@ import net.runelite.client.rs.ClientLoader;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.ClientUI;
-import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.RuneLiteSplashScreen;
import net.runelite.client.ui.overlay.OverlayManager;
-import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.client.ui.overlay.WidgetOverlay;
import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay;
import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
-import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
-import net.runelite.client.ws.PartyService;
import org.slf4j.LoggerFactory;
@Singleton
@@ -97,15 +86,9 @@ public class RuneLite
@Inject
private PluginManager pluginManager;
- @Inject
- private EventBus eventBus;
-
@Inject
private ConfigManager configManager;
- @Inject
- private DrawManager drawManager;
-
@Inject
private SessionManager sessionManager;
@@ -118,33 +101,12 @@ public class RuneLite
@Inject
private ClientUI clientUI;
- @Inject
- private InfoBoxManager infoBoxManager;
-
@Inject
private OverlayManager overlayManager;
- @Inject
- private PartyService partyService;
-
- @Inject
- private Provider itemManager;
-
- @Inject
- private Provider overlayRenderer;
-
- @Inject
- private Provider clanManager;
-
@Inject
private Provider chatMessageManager;
- @Inject
- private Provider menuManager;
-
- @Inject
- private Provider commandManager;
-
@Inject
private Provider infoBoxOverlay;
@@ -160,12 +122,6 @@ public class RuneLite
@Inject
private Provider arrowMinimapOverlay;
- @Inject
- private Provider lootManager;
-
- @Inject
- private Provider chatboxPanelManager;
-
@Inject
@Nullable
private Client client;
@@ -351,28 +307,11 @@ public class RuneLite
// Close the splash screen
splashScreen.close();
- // Register event listeners
- eventBus.register(clientUI);
- eventBus.register(pluginManager);
- eventBus.register(overlayManager);
- eventBus.register(drawManager);
- eventBus.register(infoBoxManager);
- eventBus.register(partyService);
-
if (!isOutdated)
{
// Initialize chat colors
chatMessageManager.get().loadColors();
- eventBus.register(overlayRenderer.get());
- eventBus.register(clanManager.get());
- eventBus.register(itemManager.get());
- eventBus.register(menuManager.get());
- eventBus.register(chatMessageManager.get());
- eventBus.register(commandManager.get());
- eventBus.register(lootManager.get());
- eventBus.register(chatboxPanelManager.get());
-
// Add core overlays
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
overlayManager.add(infoBoxOverlay.get());
diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java
index f394c17f40..22813b4c0a 100644
--- a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java
+++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java
@@ -42,6 +42,7 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.config.RuneLitePlusConfig;
import net.runelite.client.eventbus.EventBus;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.game.ItemManager;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.PluginManager;
@@ -84,7 +85,7 @@ public class RuneLiteModule extends AbstractModule
bind(Callbacks.class).to(Hooks.class);
bind(EventBus.class)
- .toInstance(new EventBus());
+ .toInstance(new EventBusImplementation());
bind(EventBus.class)
.annotatedWith(Names.named("Deferred EventBus"))
diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
index 4caef359c3..75e8ec8212 100644
--- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
@@ -25,6 +25,7 @@
package net.runelite.client.account;
import com.google.gson.Gson;
+import io.reactivex.disposables.Disposable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
@@ -39,7 +40,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
-import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen;
import net.runelite.client.util.LinkBrowser;
@@ -57,17 +58,20 @@ public class SessionManager
@Getter
private AccountSession accountSession;
- private final EventBus eventBus;
+ private final EventBusImplementation eventBus;
private final ConfigManager configManager;
private final WSClient wsClient;
@Inject
- private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
+ private SessionManager(ConfigManager configManager, EventBusImplementation eventBus, WSClient wsClient)
{
this.configManager = configManager;
this.eventBus = eventBus;
this.wsClient = wsClient;
- eventBus.register(this);
+
+ this.eventBus
+ .observableOfType(LoginResponse.class)
+ .subscribe(this::onLoginResponse);
}
public void loadSession()
@@ -207,8 +211,7 @@ public class SessionManager
LinkBrowser.browse(login.getOauthUrl());
}
- @Subscribe
- public void onLoginResponse(LoginResponse loginResponse)
+ private void onLoginResponse(LoginResponse loginResponse)
{
log.debug("Now logged in as {}", loginResponse.getUsername());
diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java
index 5c53677308..8d1873a20f 100644
--- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java
+++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java
@@ -60,6 +60,7 @@ import net.runelite.client.Notifier;
import net.runelite.client.RuneLite;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.eventbus.EventBus;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager;
import net.runelite.client.task.Scheduler;
@@ -88,7 +89,7 @@ public class Hooks implements Callbacks
private static final OverlayManager overlayManager = injector.getInstance(OverlayManager.class);
@Inject
- private EventBus eventBus;
+ private EventBusImplementation eventBus;
@Inject
private DeferredEventBus deferredEventBus;
diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java
index f930992d08..c19a84a405 100644
--- a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java
@@ -35,7 +35,7 @@ import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.eventbus.EventBus;
-import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.events.ChatInput;
import net.runelite.client.events.ChatboxInput;
import net.runelite.client.events.PrivateMessageInput;
@@ -49,12 +49,15 @@ public class ChatCommandManager implements ChatboxInputListener
private final ScheduledExecutorService scheduledExecutorService;
@Inject
- private ChatCommandManager(EventBus eventBus, CommandManager commandManager, Client client, ScheduledExecutorService scheduledExecutorService)
+ private ChatCommandManager(EventBusImplementation eventBus, CommandManager commandManager, Client client, ScheduledExecutorService scheduledExecutorService)
{
this.client = client;
this.scheduledExecutorService = scheduledExecutorService;
- eventBus.register(this);
+ // eventBus.register(this);
commandManager.register(this);
+
+ eventBus.observableOfType(ChatMessage.class)
+ .subscribe(this::onChatMessage);
}
public void registerCommand(String command, BiConsumer execute)
@@ -82,8 +85,7 @@ public class ChatCommandManager implements ChatboxInputListener
commands.remove(command.toLowerCase());
}
- @Subscribe
- public void onChatMessage(ChatMessage chatMessage)
+ private void onChatMessage(ChatMessage chatMessage)
{
if (client.getGameState() != GameState.LOGGED_IN)
{
diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java
index c571282a00..5baa5ba42a 100644
--- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java
@@ -52,7 +52,7 @@ import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ChatColorConfig;
-import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
@@ -70,17 +70,32 @@ public class ChatMessageManager
@Inject
private ChatMessageManager(
- Client client,
- ChatColorConfig chatColorConfig,
- ClientThread clientThread)
+ final Client client,
+ final ChatColorConfig chatColorConfig,
+ final ClientThread clientThread,
+ final EventBusImplementation eventbus)
{
this.client = client;
this.chatColorConfig = chatColorConfig;
this.clientThread = clientThread;
+
+ eventbus.observableOfType(VarbitChanged.class)
+ .subscribe(this::onVarbitChanged);
+
+ eventbus.observableOfType(ResizeableChanged.class)
+ .subscribe(this::onResizeableChanged);
+
+ eventbus.observableOfType(ConfigChanged.class)
+ .subscribe(this::onConfigChanged);
+
+ eventbus.observableOfType(ChatMessage.class)
+ .subscribe(this::onChatMessage);
+
+ eventbus.observableOfType(ScriptCallbackEvent.class)
+ .subscribe(this::onScriptCallbackEvent);
}
- @Subscribe
- public void onVarbitChanged(VarbitChanged event)
+ private void onVarbitChanged(VarbitChanged event)
{
int setting = client.getVar(Varbits.TRANSPARENT_CHATBOX);
@@ -91,14 +106,12 @@ public class ChatMessageManager
}
}
- @Subscribe
- public void onResizeableChanged(ResizeableChanged event)
+ private void onResizeableChanged(ResizeableChanged event)
{
refreshAll();
}
- @Subscribe
- public void onConfigChanged(ConfigChanged event)
+ private void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("textrecolor"))
{
@@ -107,8 +120,7 @@ public class ChatMessageManager
}
}
- @Subscribe
- public void onChatMessage(ChatMessage chatMessage)
+ private void onChatMessage(ChatMessage chatMessage)
{
MessageNode messageNode = chatMessage.getMessageNode();
ChatMessageType chatMessageType = chatMessage.getType();
@@ -173,8 +185,7 @@ public class ChatMessageManager
}
}
- @Subscribe
- public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
+ private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
{
final String eventName = scriptCallbackEvent.getEventName();
diff --git a/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java
index 7529fc6d56..fc07646f0a 100644
--- a/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java
@@ -37,8 +37,7 @@ import net.runelite.api.VarClientStr;
import net.runelite.api.events.CommandExecuted;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.callback.ClientThread;
-import net.runelite.client.eventbus.EventBus;
-import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.events.ChatboxInput;
import net.runelite.client.events.PrivateMessageInput;
@@ -51,18 +50,25 @@ public class CommandManager
private static final String PRIVMATE_MESSAGE = "privateMessage";
private final Client client;
- private final EventBus eventBus;
+ private final EventBusImplementation eventBus;
private final ClientThread clientThread;
private boolean sending;
private final List chatboxInputListenerList = new ArrayList<>();
@Inject
- private CommandManager(Client client, EventBus eventBus, ClientThread clientThread)
+ private CommandManager(
+ final Client client,
+ final EventBusImplementation eventBus,
+ final ClientThread clientThread
+ )
{
this.client = client;
this.eventBus = eventBus;
this.clientThread = clientThread;
+
+ eventBus.observableOfType(ScriptCallbackEvent.class)
+ .subscribe(this::onScriptCallbackEvent);
}
public void register(ChatboxInputListener chatboxInputListener)
@@ -75,7 +81,6 @@ public class CommandManager
chatboxInputListenerList.remove(chatboxInputListener);
}
- @Subscribe
private void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (sending)
diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java
index b22c8e67a7..2a5ba38441 100644
--- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java
@@ -66,6 +66,7 @@ import net.runelite.api.events.ConfigChanged;
import net.runelite.client.RuneLite;
import static net.runelite.client.RuneLite.PROFILES_DIR;
import net.runelite.client.eventbus.EventBus;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.client.util.ColorUtil;
import net.runelite.client.ui.FontManager;
@@ -79,7 +80,7 @@ public class ConfigManager
private static final File STANDARD_SETTINGS_FILE = new File(RuneLite.RUNELITE_DIR, STANDARD_SETTINGS_FILE_NAME);
@Inject
- EventBus eventBus;
+ EventBusImplementation eventBus;
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties();
diff --git a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java
index 091c479ac6..7b6b858788 100644
--- a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java
+++ b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java
@@ -39,6 +39,7 @@ import net.runelite.client.discord.events.DiscordJoinRequest;
import net.runelite.client.discord.events.DiscordReady;
import net.runelite.client.discord.events.DiscordSpectateGame;
import net.runelite.client.eventbus.EventBus;
+import net.runelite.client.eventbus.EventBusImplementation;
import net.runelite.discord.DiscordEventHandlers;
import net.runelite.discord.DiscordRPC;
import net.runelite.discord.DiscordRichPresence;
@@ -48,7 +49,7 @@ import net.runelite.discord.DiscordUser;
@Slf4j
public class DiscordService implements AutoCloseable
{
- private final EventBus eventBus;
+ private final EventBusImplementation eventBus;
private final RuneLiteProperties runeLiteProperties;
private final ScheduledExecutorService executorService;
private final DiscordRPC discordRPC;
@@ -61,7 +62,7 @@ public class DiscordService implements AutoCloseable
@Inject
private DiscordService(
- final EventBus eventBus,
+ final EventBusImplementation eventBus,
final RuneLiteProperties runeLiteProperties,
final ScheduledExecutorService executorService)
{
diff --git a/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java
index a28f2f4371..cc8925c933 100644
--- a/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java
+++ b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java
@@ -25,225 +25,14 @@
*/
package net.runelite.client.eventbus;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Multimap;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.LambdaMetafactory;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.function.Consumer;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import lombok.EqualsAndHashCode;
-import lombok.RequiredArgsConstructor;
-import lombok.Value;
-import lombok.extern.slf4j.Slf4j;
+import io.reactivex.Observable;
+import java.util.List;
-@Slf4j
-@RequiredArgsConstructor
-@ThreadSafe
-public class EventBus
+public interface EventBus
{
- @FunctionalInterface
- public interface SubscriberMethod
- {
- void invoke(Object event);
- }
+ void post(Object event);
- @Value
- private static class Subscriber
- {
- private final Object object;
- private final Method method;
- @EqualsAndHashCode.Exclude
- private final SubscriberMethod lamda;
+ Observable observableOfType(Class eventClass);
- void invoke(final Object arg) throws Exception
- {
- if (lamda != null)
- {
- lamda.invoke(arg);
- }
- else
- {
- method.invoke(object, arg);
- }
- }
- }
-
- private final Consumer exceptionHandler;
- private ImmutableMultimap subscribers = ImmutableMultimap.of();
-
- /**
- * Instantiates EventBus with default exception handler
- */
- public EventBus()
- {
- this((e) -> log.warn("Uncaught exception in event subscriber", e));
- }
-
- /**
- * Registers subscriber to EventBus. All methods in subscriber and it's parent classes are checked for
- * {@link Subscribe} annotation and then added to map of subscriptions.
- *
- * @param object subscriber to register
- * @throws IllegalArgumentException in case subscriber method name is wrong (correct format is 'on' + EventName
- */
- public synchronized void register(@Nonnull final Object object)
- {
- final ImmutableMultimap.Builder builder = ImmutableMultimap.builder();
-
- if (subscribers != null)
- {
- builder.putAll(subscribers);
- }
-
- for (Class> clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass())
- {
- for (final Method method : clazz.getDeclaredMethods())
- {
- final Subscribe sub = method.getAnnotation(Subscribe.class);
-
- if (sub == null)
- {
- continue;
- }
-
- Preconditions.checkArgument(method.getReturnType() == Void.TYPE, "@Subscribed method \"" + method + "\" cannot return a value");
- Preconditions.checkArgument(method.getParameterCount() == 1, "@Subscribed method \"" + method + "\" must take exactly 1 argument");
- Preconditions.checkArgument(!Modifier.isStatic(method.getModifiers()), "@Subscribed method \"" + method + "\" cannot be static");
-
- final Class> parameterClazz = method.getParameterTypes()[0];
-
- Preconditions.checkArgument(!parameterClazz.isPrimitive(), "@Subscribed method \"" + method + "\" cannot subscribe to primitives");
- Preconditions.checkArgument((parameterClazz.getModifiers() & (Modifier.ABSTRACT | Modifier.INTERFACE)) == 0, "@Subscribed method \"" + method + "\" cannot subscribe to polymorphic classes");
-
- for (Class> psc = parameterClazz.getSuperclass(); psc != null; psc = psc.getSuperclass())
- {
- if (subscribers.containsKey(psc))
- {
- throw new IllegalArgumentException("@Subscribed method \"" + method + "\" cannot subscribe to class which inherits from subscribed class \"" + psc + "\"");
- }
- }
-
- final String preferredName = "on" + parameterClazz.getSimpleName();
- Preconditions.checkArgument(method.getName().equals(preferredName), "Subscribed method " + method + " should be named " + preferredName);
-
- method.setAccessible(true);
- SubscriberMethod lambda = null;
-
- try
- {
- final MethodHandles.Lookup caller = privateLookupIn(clazz);
- final MethodType subscription = MethodType.methodType(void.class, parameterClazz);
- final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription);
- final CallSite site = LambdaMetafactory.metafactory(
- caller,
- "invoke",
- MethodType.methodType(SubscriberMethod.class, clazz),
- subscription.changeParameterType(0, Object.class),
- target,
- subscription);
-
- final MethodHandle factory = site.getTarget();
- lambda = (SubscriberMethod) factory.bindTo(object).invokeExact();
- }
- catch (Throwable e)
- {
- log.warn("Unable to create lambda for method {}", method, e);
- }
-
- final Subscriber subscriber = new Subscriber(object, method, lambda);
- builder.put(parameterClazz, subscriber);
- log.debug("Registering {} - {}", parameterClazz, subscriber);
- }
- }
-
- subscribers = builder.build();
- }
-
- /**
- * Unregisters all subscribed methods from provided subscriber object.
- *
- * @param object object to unsubscribe from
- */
- public synchronized void unregister(@Nonnull final Object object)
- {
- if (subscribers == null)
- {
- return;
- }
-
- final Multimap map = HashMultimap.create();
- map.putAll(subscribers);
-
- for (Class> clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass())
- {
- for (final Method method : clazz.getDeclaredMethods())
- {
- final Subscribe sub = method.getAnnotation(Subscribe.class);
-
- if (sub == null)
- {
- continue;
- }
-
- final Class> parameterClazz = method.getParameterTypes()[0];
- map.remove(parameterClazz, new Subscriber(object, method, null));
- }
- }
-
- subscribers = ImmutableMultimap.copyOf(map);
- }
-
- /**
- * Posts provided event to all registered subscribers. Subscriber calls are invoked immediately and in order
- * in which subscribers were registered.
- *
- * @param event event to post
- */
- public void post(@Nonnull final Object event)
- {
- for (final Subscriber subscriber : subscribers.get(event.getClass()))
- {
- try
- {
- subscriber.invoke(event);
- }
- catch (Exception e)
- {
- exceptionHandler.accept(e);
- }
- }
- }
-
- private static MethodHandles.Lookup privateLookupIn(Class clazz) throws IllegalAccessException, NoSuchFieldException, InvocationTargetException
- {
- try
- {
- // Java 9+ has privateLookupIn method on MethodHandles, but since we are shipping and using Java 8
- // we need to access it via reflection. This is preferred way because it's Java 9+ public api and is
- // likely to not change
- final Method privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
- return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, MethodHandles.lookup());
- }
- catch (NoSuchMethodException e)
- {
- // In Java 8 we first do standard lookupIn class
- final MethodHandles.Lookup lookupIn = MethodHandles.lookup().in(clazz);
-
- // and then we mark it as trusted for private lookup via reflection on private field
- final Field modes = MethodHandles.Lookup.class.getDeclaredField("allowedModes");
- modes.setAccessible(true);
- modes.setInt(lookupIn, -1); // -1 == TRUSTED
- return lookupIn;
- }
- }
+ Observable