Skip to content

Commit e6c7eae

Browse files
committed
Deprecate BlueMapAPIListener and add two new methods to listen to enabling/disabling BlueMapAPI
This should fix an issue with a ClassNotFoundException when soft-depending on BlueMap and BlueMap is not installed.
1 parent ccbb600 commit e6c7eae

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/main/java/de/bluecolored/bluemap/api/BlueMapAPI.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Optional;
3333
import java.util.UUID;
3434
import java.util.concurrent.ExecutionException;
35+
import java.util.function.Consumer;
3536

3637
import de.bluecolored.bluemap.api.marker.Marker;
3738
import de.bluecolored.bluemap.api.marker.MarkerAPI;
@@ -43,7 +44,12 @@
4344
*/
4445
public abstract class BlueMapAPI {
4546
private static BlueMapAPI instance;
46-
private static Collection<BlueMapAPIListener> listener = new ArrayList<>();
47+
48+
@Deprecated
49+
private static Collection<BlueMapAPIListener> listener = new ArrayList<>(2);
50+
51+
private static Collection<Consumer<BlueMapAPI>> onEnableConsumers = new ArrayList<>(2);
52+
private static Collection<Consumer<BlueMapAPI>> onDisableConsumers = new ArrayList<>(2);
4753

4854
/**
4955
* Getter for the {@link RenderAPI}.
@@ -113,7 +119,11 @@ public abstract class BlueMapAPI {
113119
/**
114120
* Register a listener that will be called when the API enables/disables
115121
* @param listener the {@link BlueMapAPIListener}
122+
*
123+
* @deprecated Implementing {@link BlueMapAPIListener} can cause a ClassNotFoundException when you soft-depend on BlueMap and your plugin/mod gets used without BlueMap.
124+
* Use {@link BlueMapAPI#onEnable(Consumer)} and {@link BlueMapAPI#onDisable(Consumer)} instead.
116125
*/
126+
@Deprecated
117127
public static synchronized void registerListener(BlueMapAPIListener listener) {
118128
BlueMapAPI.listener.add(listener);
119129
if (BlueMapAPI.instance != null) listener.onEnable(BlueMapAPI.instance);
@@ -124,7 +134,11 @@ public static synchronized void registerListener(BlueMapAPIListener listener) {
124134
* @param listener the {@link BlueMapAPIListener} instance that has been registered previously
125135
*
126136
* @return <code>true</code> if a listener was removed as a result of this call
137+
*
138+
* @deprecated Implementing {@link BlueMapAPIListener} can cause a ClassNotFoundException when you soft-depend on BlueMap and your plugin/mod gets used without BlueMap.
139+
* Use {@link BlueMapAPI#onEnable(Consumer)} and {@link BlueMapAPI#onDisable(Consumer)} instead.
127140
*/
141+
@Deprecated
128142
public static synchronized boolean unregisterListener(BlueMapAPIListener listener) {
129143
return BlueMapAPI.listener.remove(listener);
130144
}
@@ -136,19 +150,50 @@ public static synchronized boolean unregisterListener(BlueMapAPIListener listene
136150
public static synchronized Optional<BlueMapAPI> getInstance() {
137151
return Optional.ofNullable(instance);
138152
}
153+
154+
/**
155+
* Registers a {@link Consumer} that will be called when BlueMap has been loaded and started and the API is ready to use.<br>
156+
* If {@link BlueMapAPI} is already enabled when this listener is registered this method will be called immediately <i>(on the same thread)</i>!
157+
* <p><i>(Note: This method will likely be called asynchronously, <b>not</b> on the server-thread!</i></p>
158+
* @param consumer the {@link Consumer}
159+
*/
160+
public static synchronized void onEnable(Consumer<BlueMapAPI> consumer) {
161+
onEnableConsumers.add(consumer);
162+
}
163+
164+
/**
165+
* Registers a {@link Consumer} that will be called <b>before</b> BlueMap is being unloaded and stopped, after this method returns the API is no longer usable!<br>
166+
* Unlike {@link BlueMapAPIListener#onEnable(BlueMapAPI)}, if {@link BlueMapAPI} is not enabled when this listener is registered this method will <b>not</b> be called immediately.
167+
* <p><i>(Note: This method will likely be called asynchronously, <b>not</b> on the server-thread!</i></p>
168+
* @param blueMapApi the {@link BlueMapAPI}
169+
*/
170+
public static synchronized void onDisable(Consumer<BlueMapAPI> consumer) {
171+
onDisableConsumers.add(consumer);
172+
}
139173

140174
/**
141175
* Used by BlueMap to register the API and call the listeners properly.
142176
* @param instance the {@link BlueMapAPI}-instance
143177
* @return <code>true</code> if the instance has been registered, <code>false</code> if there already was an instance registered
144178
* @throws ExecutionException if a {@link BlueMapAPIListener} threw an exception during the registration
145179
*/
180+
@SuppressWarnings("deprecation")
146181
protected static synchronized boolean registerInstance(BlueMapAPI instance) throws ExecutionException {
147182
if (BlueMapAPI.instance != null) return false;
148183

149184
BlueMapAPI.instance = instance;
150185

151186
List<Exception> thrownExceptions = new ArrayList<>(0);
187+
188+
for (Consumer<BlueMapAPI> listener : BlueMapAPI.onEnableConsumers) {
189+
try {
190+
listener.accept(BlueMapAPI.instance);
191+
} catch (Exception ex) {
192+
thrownExceptions.add(ex);
193+
}
194+
}
195+
196+
// backwards compatibility
152197
for (BlueMapAPIListener listener : BlueMapAPI.listener) {
153198
try {
154199
listener.onEnable(BlueMapAPI.instance);
@@ -174,10 +219,21 @@ protected static synchronized boolean registerInstance(BlueMapAPI instance) thro
174219
* @return <code>true</code> if the instance was unregistered, <code>false</code> if there was no or an other instance registered
175220
* @throws ExecutionException if a {@link BlueMapAPIListener} threw an exception during the un-registration
176221
*/
222+
@SuppressWarnings("deprecation")
177223
protected static synchronized boolean unregisterInstance(BlueMapAPI instance) throws ExecutionException {
178224
if (BlueMapAPI.instance != instance) return false;
179225

180226
List<Exception> thrownExceptions = new ArrayList<>(0);
227+
228+
for (Consumer<BlueMapAPI> listener : BlueMapAPI.onDisableConsumers) {
229+
try {
230+
listener.accept(BlueMapAPI.instance);
231+
} catch (Exception ex) {
232+
thrownExceptions.add(ex);
233+
}
234+
}
235+
236+
// backwards compatibility
181237
for (BlueMapAPIListener listener : BlueMapAPI.listener) {
182238
try {
183239
listener.onDisable(BlueMapAPI.instance);

src/main/java/de/bluecolored/bluemap/api/BlueMapAPIListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
*/
2525
package de.bluecolored.bluemap.api;
2626

27+
/**
28+
* @deprecated Implementing {@link BlueMapAPIListener} can cause a ClassNotFoundException when you soft-depend on BlueMap and your plugin/mod gets used without BlueMap.
29+
* Use {@link BlueMapAPI#onEnable(Consumer)} and {@link BlueMapAPI#onDisable(Consumer)} instead.
30+
*/
31+
@Deprecated
2732
public interface BlueMapAPIListener {
2833

2934
/**

0 commit comments

Comments
 (0)