44 */
55package net .minecraftforge .eventbus .api ;
66
7- import net .minecraftforge .eventbus .InternalUtils ;
87import net .minecraftforge .eventbus .ListenerList ;
98import net .minecraftforge .eventbus .api .Event .HasResult ;
9+ import net .minecraftforge .eventbus .internal .Cache ;
1010
1111import java .lang .annotation .Annotation ;
1212import java .lang .reflect .Constructor ;
1313import java .lang .reflect .InvocationTargetException ;
1414import java .lang .reflect .Modifier ;
15- import java .util .function .BiFunction ;
16- import java .util .function .Supplier ;
1715
1816public class EventListenerHelper {
19- private static final BiFunction <Class <?>, Supplier < ListenerList >, ListenerList > listeners = InternalUtils . cachePublic ();
17+ private static final Cache <Class <?>, ListenerList > listeners = Cache . create ();
2018 private static final ListenerList EVENTS_LIST = new ListenerList ();
21- private static final BiFunction <Class <?>, Supplier <Boolean >, Boolean > cancelable = InternalUtils .cachePublic ();
22- private static final BiFunction <Class <?>, Supplier <Boolean >, Boolean > hasResult = InternalUtils .cachePublic ();
19+ private static final Cache <Class <?>, Boolean > cancelable = Cache .create ();
20+ private static final Cache <Class <?>, Boolean > hasResult = Cache .create ();
21+
2322 /**
2423 * Returns a {@link ListenerList} object that contains all listeners
2524 * that are registered to this event class.
@@ -35,7 +34,13 @@ public static ListenerList getListenerList(Class<?> eventClass) {
3534
3635 static ListenerList getListenerListInternal (Class <?> eventClass , boolean fromInstanceCall ) {
3736 if (eventClass == Event .class ) return EVENTS_LIST ; // Small optimization, bypasses all the locks/maps.
38- return listeners .apply (eventClass , () -> computeListenerList (eventClass , fromInstanceCall ));
37+
38+ // Attempt to get the ListenerList directly from the cache first. This avoids an allocating lambda on cache hit
39+ var ret = listeners .get (eventClass );
40+ if (ret != null ) return ret ;
41+
42+ // Cache miss, check again (for thread-safety) and compute the ListenerList if still absent
43+ return listeners .computeIfAbsent (eventClass , k -> computeListenerList (k , fromInstanceCall ));
3944 }
4045
4146 private static ListenerList computeListenerList (Class <?> eventClass , boolean fromInstanceCall ) {
@@ -66,14 +71,17 @@ static boolean hasResult(Class<?> eventClass) {
6671 return hasAnnotation (eventClass , HasResult .class , hasResult );
6772 }
6873
69- private static boolean hasAnnotation (Class <?> eventClass , Class <? extends Annotation > annotation , BiFunction <Class <?>, Supplier < Boolean >, Boolean > cache ) {
74+ private static boolean hasAnnotation (Class <?> eventClass , Class <? extends Annotation > annotation , Cache <Class <?>, Boolean > cache ) {
7075 if (eventClass == Event .class || eventClass == Object .class )
7176 return false ;
7277
73- return cache .apply (eventClass , () -> {
74- if (eventClass .isAnnotationPresent (annotation ))
78+ var ret = cache .get (eventClass );
79+ if (ret != null ) return ret ;
80+
81+ return cache .computeIfAbsent (eventClass , k -> {
82+ if (k .isAnnotationPresent (annotation ))
7583 return true ;
76- var parent = eventClass .getSuperclass ();
84+ var parent = k .getSuperclass ();
7785 return parent != null && hasAnnotation (parent , annotation , cache );
7886 });
7987 }
0 commit comments