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 23376ad4f0..d30305ae59 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -30,6 +30,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; +import com.openosrs.client.graphics.ModelOutlineRenderer; import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; @@ -73,6 +74,7 @@ import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.OPRSExternalPluginManager; 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.FatalErrorDialog; @@ -171,6 +173,9 @@ public class RuneLite @Inject private Provider worldMapOverlay; + @Inject + private Provider modelOutlineRenderer; + @Inject private Provider lootManager; @@ -184,6 +189,9 @@ public class RuneLite @Nullable private Client client; + @Inject + private Scheduler scheduler; + public static void main(String[] args) throws Exception { Locale.setDefault(Locale.ENGLISH); @@ -397,6 +405,12 @@ public class RuneLite // Start plugins pluginManager.startPlugins(); + // Register additional schedulers + if (this.client != null) + { + scheduler.registerObject(modelOutlineRenderer.get()); + } + SplashScreen.stop(); clientUI.show(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 500bd48000..8aedb0f158 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -38,13 +38,7 @@ import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; import java.io.IOException; -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.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -72,12 +66,9 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PluginChanged; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; -import net.runelite.client.task.Schedule; -import net.runelite.client.task.ScheduledMethod; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.SplashScreen; import net.runelite.client.util.GameEventManager; -import net.runelite.client.util.ReflectUtil; @Singleton @Slf4j @@ -636,59 +627,14 @@ public class PluginManager private void schedule(Plugin plugin) { - for (Method method : plugin.getClass().getMethods()) - { - Schedule schedule = method.getAnnotation(Schedule.class); - - if (schedule == null) - { - continue; - } - - Runnable runnable = null; - try - { - final Class clazz = method.getDeclaringClass(); - final MethodHandles.Lookup caller = ReflectUtil.privateLookupIn(clazz); - final MethodType subscription = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription); - final CallSite site = LambdaMetafactory.metafactory( - caller, - "run", - MethodType.methodType(Runnable.class, clazz), - subscription, - target, - subscription); - - final MethodHandle factory = site.getTarget(); - runnable = (Runnable) factory.bindTo(plugin).invokeExact(); - } - catch (Throwable e) - { - log.warn("Unable to create lambda for method {}", method, e); - } - - ScheduledMethod scheduledMethod = new ScheduledMethod(schedule, method, plugin, runnable); - log.debug("Scheduled task {}", scheduledMethod); - - scheduler.addScheduledMethod(scheduledMethod); - } + // note to devs: this method will almost certainly merge conflict in the future, just apply the changes in the scheduler instead + scheduler.registerObject(plugin); } private void unschedule(Plugin plugin) { - List methods = new ArrayList<>(scheduler.getScheduledMethods()); - - for (ScheduledMethod method : methods) - { - if (method.getObject() != plugin) - { - continue; - } - - log.debug("Removing scheduled task {}", method); - scheduler.removeScheduledMethod(method); - } + // note to devs: this method will almost certainly merge conflict in the future, just apply the changes in the scheduler instead + scheduler.unregisterObject(plugin); } /** diff --git a/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java b/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java index 8ecf6ab665..67ba137e63 100644 --- a/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java +++ b/runelite-client/src/main/java/net/runelite/client/task/Scheduler.java @@ -24,10 +24,16 @@ */ package net.runelite.client.task; +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.InvocationTargetException; import java.lang.reflect.Method; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -60,6 +66,63 @@ public class Scheduler return Collections.unmodifiableList(scheduledMethods); } + public void registerObject(Object obj) + { + for (Method method : obj.getClass().getMethods()) + { + Schedule schedule = method.getAnnotation(Schedule.class); + + if (schedule == null) + { + continue; + } + + Runnable runnable = null; + try + { + final Class clazz = method.getDeclaringClass(); + final MethodHandles.Lookup caller = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); + final MethodType subscription = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); + final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription); + final CallSite site = LambdaMetafactory.metafactory( + caller, + "run", + MethodType.methodType(Runnable.class, clazz), + subscription, + target, + subscription); + + final MethodHandle factory = site.getTarget(); + runnable = (Runnable) factory.bindTo(obj).invokeExact(); + } + catch (Throwable e) + { + log.warn("Unable to create lambda for method {}", method, e); + } + + ScheduledMethod scheduledMethod = new ScheduledMethod(schedule, method, obj, runnable); + log.debug("Scheduled task {}", scheduledMethod); + + addScheduledMethod(scheduledMethod); + } + } + + public void unregisterObject(Object obj) + { + List methods = new ArrayList<>(getScheduledMethods()); + + for (ScheduledMethod method : methods) + { + if (method.getObject() != obj) + { + continue; + } + + log.debug("Removing scheduled task {}", method); + removeScheduledMethod(method); + } + } + public void tick() { Instant now = Instant.now();