From 08058af758270558f619c3e27f8aa7c318b285ec Mon Sep 17 00:00:00 2001 From: Zontreck Date: Mon, 12 Feb 2024 21:27:29 -0700 Subject: [PATCH] Attempt to fix the field not being found --- .../zontreck/eventsbus/EventDispatcher.java | 133 +++++++++--------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/src/main/java/dev/zontreck/eventsbus/EventDispatcher.java b/src/main/java/dev/zontreck/eventsbus/EventDispatcher.java index 8cc210f..c5382e9 100644 --- a/src/main/java/dev/zontreck/eventsbus/EventDispatcher.java +++ b/src/main/java/dev/zontreck/eventsbus/EventDispatcher.java @@ -10,67 +10,52 @@ import dev.zontreck.eventsbus.events.ResetEventBusEvent; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.List; -public class EventDispatcher -{ +public class EventDispatcher { private static List singleshot = new ArrayList<>(); private static List> subscribers = new ArrayList<>(); /** * Scans every Java class that is currently loaded. It then checks for Subscribe, and a proper parameter before posting the Event. * The Event will only be posted if not cancelled using {@link Event#setCancelled(boolean)} and that {@link Subscribe#allowCancelled()} allows. + * * @param event The event to post * @return True if cancelled. */ - - public static boolean Post(Event event) - { - for(PriorityLevel level : PriorityLevel.values()) - { - - for(Class clazz : subscribers) - { - for(Method M :clazz.getMethods()) - { - if(!M.isAnnotationPresent(Subscribe.class)) continue; + public static boolean Post(Event event) { + for (PriorityLevel level : PriorityLevel.values()) { + for (Class clazz : subscribers) { + for (Method M : clazz.getMethods()) { + if (!M.isAnnotationPresent(Subscribe.class)) continue; Subscribe subscriber = M.getAnnotation(Subscribe.class); - - boolean canPost=true; + boolean canPost = true; Class param = M.getParameterTypes()[0]; - if(param == event.getClass()) - { - if(M.isAnnotationPresent(SingleshotEvent.class)) - { - if(singleshot.contains(M)) - { - canPost=false; + if (param == event.getClass()) { + if (M.isAnnotationPresent(SingleshotEvent.class)) { + if (singleshot.contains(M)) { + canPost = false; } } - } else canPost=false; + } else canPost = false; - PriorityLevel eventPriotityLevel= PriorityLevel.HIGH; // Default + PriorityLevel eventPriorityLevel = PriorityLevel.HIGH; // Default - if(M.isAnnotationPresent(Priority.class)) - { + if (M.isAnnotationPresent(Priority.class)) { Priority prio = M.getAnnotation(Priority.class); - eventPriotityLevel=prio.Level(); + eventPriorityLevel = prio.Level(); } - if(level != eventPriotityLevel) - { - canPost=false; + if (level != eventPriorityLevel) { + canPost = false; } - // Dispatch the event now - try { - if(event.isCancelled() && !subscriber.allowCancelled()) + if (event.isCancelled() && !subscriber.allowCancelled()) continue; else M.invoke(null, event); @@ -79,49 +64,23 @@ public class EventDispatcher } catch (InvocationTargetException e) { throw new RuntimeException(e); } - } } } - return event.isCancelled(); } - /** * Scan all event subscribers */ - public static void Scan() - { + public static void Scan() { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Package[] packages = Package.getPackages(); - List> loaded = new ArrayList<>(); - for(Package pkg : packages) - { - try{ - String packageName = pkg.getName(); - Field classesField = ClassLoader.class.getDeclaredField("classes"); - classesField.setAccessible(true); + CustomClassLoader customClassLoader = new CustomClassLoader(classLoader); - List> classes = (List>) classesField.get(classLoader); - - for(Class clazz : classes) - { - if(clazz.getPackage().getName().equalsIgnoreCase(packageName)) - { - - if(clazz.isAnnotationPresent(EventSubscriber.class)) - loaded.add(clazz); - } - } - - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } + for (Package pkg : Package.getPackages()) { + customClassLoader.loadClasses(pkg.getName(), loaded); } subscribers = loaded; @@ -130,10 +89,9 @@ public class EventDispatcher /** * Resets the events system. *
- * This action clears the Singleshot list for the events that should only be invoked once. And rescans all classes incase new classes were dynamically loaded. + * This action clears the Singleshot list for the events that should only be invoked once. And rescans all classes in case new classes were dynamically loaded. */ - public static void Reset() - { + public static void Reset() { Post(new ResetEventBusEvent()); singleshot.clear(); @@ -142,4 +100,45 @@ public class EventDispatcher Post(new EventBusReadyEvent()); } + + static class CustomClassLoader extends ClassLoader { + private final ClassLoader parent; + + public CustomClassLoader(ClassLoader parent) { + super(parent); + this.parent = parent; + } + + public void loadClasses(String packageName, List> loaded) { + + Field classesField = EventDispatcher.findField(ClassLoader.class, "classes"); + classesField.setAccessible(true); + List> classes = null; + try { + classes = (List>) classesField.get(parent); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + for (Class clazz : classes) { + if (clazz.getPackage().getName().equals(packageName) && + clazz.isAnnotationPresent(EventSubscriber.class)) { + loaded.add(clazz); + } + } + } + } + + private static Field findField(Class clazz, String name) + { + for(Field f : clazz.getFields()) + { + if(f.getName().equalsIgnoreCase(name)) + { + return f; + } + } + + return null; + } }