Attempt to fix the field not being found

This commit is contained in:
Zontreck 2024-02-12 21:27:29 -07:00
parent ee629e2bc8
commit 08058af758

View file

@ -10,67 +10,52 @@ import dev.zontreck.eventsbus.events.ResetEventBusEvent;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class EventDispatcher public class EventDispatcher {
{
private static List<Method> singleshot = new ArrayList<>(); private static List<Method> singleshot = new ArrayList<>();
private static List<Class<?>> subscribers = new ArrayList<>(); private static List<Class<?>> subscribers = new ArrayList<>();
/** /**
* Scans every Java class that is currently loaded. It then checks for Subscribe, and a proper parameter before posting the Event. * 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. * 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 * @param event The event to post
* @return True if cancelled. * @return True if cancelled.
*/ */
public static boolean Post(Event event) {
public static boolean Post(Event event) for (PriorityLevel level : PriorityLevel.values()) {
{ for (Class<?> clazz : subscribers) {
for(PriorityLevel level : PriorityLevel.values()) for (Method M : clazz.getMethods()) {
{ if (!M.isAnnotationPresent(Subscribe.class)) continue;
for(Class<?> clazz : subscribers)
{
for(Method M :clazz.getMethods())
{
if(!M.isAnnotationPresent(Subscribe.class)) continue;
Subscribe subscriber = M.getAnnotation(Subscribe.class); Subscribe subscriber = M.getAnnotation(Subscribe.class);
boolean canPost = true;
boolean canPost=true;
Class<?> param = M.getParameterTypes()[0]; Class<?> param = M.getParameterTypes()[0];
if(param == event.getClass()) if (param == event.getClass()) {
{ if (M.isAnnotationPresent(SingleshotEvent.class)) {
if(M.isAnnotationPresent(SingleshotEvent.class)) if (singleshot.contains(M)) {
{ canPost = false;
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); Priority prio = M.getAnnotation(Priority.class);
eventPriotityLevel=prio.Level(); eventPriorityLevel = prio.Level();
} }
if(level != eventPriotityLevel) if (level != eventPriorityLevel) {
{ canPost = false;
canPost=false;
} }
// Dispatch the event now // Dispatch the event now
try { try {
if(event.isCancelled() && !subscriber.allowCancelled()) if (event.isCancelled() && !subscriber.allowCancelled())
continue; continue;
else else
M.invoke(null, event); M.invoke(null, event);
@ -79,49 +64,23 @@ public class EventDispatcher
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }
} }
return event.isCancelled(); return event.isCancelled();
} }
/** /**
* Scan all event subscribers * Scan all event subscribers
*/ */
public static void Scan() public static void Scan() {
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Package[] packages = Package.getPackages();
List<Class<?>> loaded = new ArrayList<>(); List<Class<?>> loaded = new ArrayList<>();
for(Package pkg : packages) CustomClassLoader customClassLoader = new CustomClassLoader(classLoader);
{
try{
String packageName = pkg.getName();
Field classesField = ClassLoader.class.getDeclaredField("classes");
classesField.setAccessible(true);
List<Class<?>> classes = (List<Class<?>>) classesField.get(classLoader); for (Package pkg : Package.getPackages()) {
customClassLoader.loadClasses(pkg.getName(), loaded);
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);
}
} }
subscribers = loaded; subscribers = loaded;
@ -130,10 +89,9 @@ public class EventDispatcher
/** /**
* Resets the events system. * Resets the events system.
* <br/> * <br/>
* 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()); Post(new ResetEventBusEvent());
singleshot.clear(); singleshot.clear();
@ -142,4 +100,45 @@ public class EventDispatcher
Post(new EventBusReadyEvent()); 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<Class<?>> loaded) {
Field classesField = EventDispatcher.findField(ClassLoader.class, "classes");
classesField.setAccessible(true);
List<Class<?>> classes = null;
try {
classes = (List<Class<?>>) 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;
}
} }