77import java .util .Map ;
88import java .util .concurrent .ConcurrentHashMap ;
99import java .util .function .Consumer ;
10+ import java .util .stream .Collectors ;
1011
1112/**
1213 * Base plugin class that provides a simple way to manage components
1314 */
1415public class BasePlugin extends JavaPlugin implements Loadable {
1516 private final List <Object > components ;
16- private final Map <Class <?>, Object > lookupMap ;
17+ private final Map <Class <?>, List < Object > > lookupMap ;
1718
1819 /**
1920 * Create a new plugin instance
@@ -33,6 +34,25 @@ protected List<Object> getComponents() {
3334 return Collections .emptyList ();
3435 }
3536
37+ private List <Object > getComponents (Class <?> type ) {
38+ return lookupMap .computeIfAbsent (
39+ type ,
40+ t -> components .stream ().filter (t ::isInstance ).map (t ::cast ).collect (Collectors .toList ())
41+ );
42+ }
43+
44+ /**
45+ * Get all components that are the instanced of the given type
46+ *
47+ * @param type the class of the component
48+ * @param <T> the type
49+ * @return the type of the component
50+ */
51+ @ SuppressWarnings ("unchecked" )
52+ public final <T > List <T > getAll (Class <T > type ) {
53+ return (List <T >) getComponents (type );
54+ }
55+
3656 /**
3757 * Get a component by its class.
3858 *
@@ -41,14 +61,11 @@ protected List<Object> getComponents() {
4161 * @return the component
4262 */
4363 public final <T > T get (Class <T > type ) {
44- return type .cast (lookupMap .computeIfAbsent (type , t -> {
45- for (Object component : components ) {
46- if (type .isInstance (component )) {
47- return component ;
48- }
49- }
64+ List <Object > components = getComponents (type );
65+ if (components .isEmpty ()) {
5066 throw new IllegalArgumentException ("No component of type " + type .getName () + " found" );
51- }));
67+ }
68+ return type .cast (components .get (0 ));
5269 }
5370
5471 /**
@@ -60,8 +77,10 @@ public final <T> T get(Class<T> type) {
6077 * @param <T> the type of the component
6178 */
6279 public final <T > void call (Class <T > type , Consumer <T > consumer , boolean reverse ) {
63- int size = components .size ();
80+ List <T > components = getAll (type );
81+ if (components .isEmpty ()) return ;
6482
83+ int size = components .size ();
6584 int index , step ;
6685 if (reverse ) {
6786 index = size - 1 ;
@@ -72,10 +91,8 @@ public final <T> void call(Class<T> type, Consumer<T> consumer, boolean reverse)
7291 }
7392
7493 while (index >= 0 && index < size ) {
75- Object component = components .get (index );
76- if (type .isInstance (component )) {
77- consumer .accept (type .cast (component ));
78- }
94+ T component = components .get (index );
95+ consumer .accept (component );
7996 index += step ;
8097 }
8198 }
@@ -107,5 +124,6 @@ public final void onEnable() {
107124 public final void onDisable () {
108125 this .call (Loadable .class , Loadable ::disable , true );
109126 this .disable ();
127+ this .lookupMap .clear ();
110128 }
111129}
0 commit comments