19
19
20
20
package com .sk89q .worldedit .extension .platform ;
21
21
22
+ import com .google .common .collect .Maps ;
23
+ import com .google .common .util .concurrent .ListeningExecutorService ;
24
+ import com .google .common .util .concurrent .MoreExecutors ;
22
25
import com .sk89q .worldedit .LocalConfiguration ;
23
26
import com .sk89q .worldedit .LocalSession ;
24
27
import com .sk89q .worldedit .WorldEdit ;
41
44
import com .sk89q .worldedit .util .HandSide ;
42
45
import com .sk89q .worldedit .util .Location ;
43
46
import com .sk89q .worldedit .util .SideEffect ;
47
+ import com .sk89q .worldedit .util .concurrency .EvenMoreExecutors ;
44
48
import com .sk89q .worldedit .util .eventbus .Subscribe ;
49
+ import com .sk89q .worldedit .util .lifecycle .SimpleLifecycled ;
45
50
import com .sk89q .worldedit .world .World ;
46
51
import org .apache .logging .log4j .Logger ;
47
52
@@ -69,7 +74,8 @@ public class PlatformManager {
69
74
70
75
private final WorldEdit worldEdit ;
71
76
private final PlatformCommandManager platformCommandManager ;
72
- private final List <Platform > platforms = new ArrayList <>();
77
+ private final SimpleLifecycled <ListeningExecutorService > executorService ;
78
+ private final Map <Platform , Boolean > platforms = Maps .newHashMap ();
73
79
private final Map <Capability , Platform > preferences = new EnumMap <>(Capability .class );
74
80
private @ Nullable String firstSeenVersion ;
75
81
private final AtomicBoolean initialized = new AtomicBoolean ();
@@ -84,6 +90,7 @@ public PlatformManager(WorldEdit worldEdit) {
84
90
checkNotNull (worldEdit );
85
91
this .worldEdit = worldEdit ;
86
92
this .platformCommandManager = new PlatformCommandManager (worldEdit , this );
93
+ this .executorService = SimpleLifecycled .invalid ();
87
94
88
95
// Register this instance for events
89
96
worldEdit .getEventBus ().register (this );
@@ -101,7 +108,7 @@ public synchronized void register(Platform platform) {
101
108
102
109
// Just add the platform to the list of platforms: we'll pick favorites
103
110
// once all the platforms have been loaded
104
- platforms .add (platform );
111
+ platforms .put (platform , false );
105
112
106
113
// Make sure that versions are in sync
107
114
if (firstSeenVersion != null ) {
@@ -126,7 +133,7 @@ public synchronized void register(Platform platform) {
126
133
public synchronized boolean unregister (Platform platform ) {
127
134
checkNotNull (platform );
128
135
129
- boolean removed = platforms .remove (platform );
136
+ boolean removed = platforms .remove (platform ) != null ;
130
137
131
138
if (removed ) {
132
139
LOGGER .info ("Unregistering " + platform .getClass ().getCanonicalName () + " from WorldEdit" );
@@ -212,7 +219,7 @@ private synchronized void choosePreferred() {
212
219
Platform preferred = null ;
213
220
Preference highest = null ;
214
221
215
- for (Platform platform : platforms ) {
222
+ for (Platform platform : platforms . keySet () ) {
216
223
Preference preference = platform .getCapabilities ().get (capability );
217
224
if (preference != null && (highest == null || preference .isPreferredOver (highest ))) {
218
225
preferred = platform ;
@@ -231,7 +238,7 @@ private synchronized void choosePreferred() {
231
238
* @return a list of platforms
232
239
*/
233
240
public synchronized List <Platform > getPlatforms () {
234
- return new ArrayList <>(platforms );
241
+ return new ArrayList <>(platforms . keySet () );
235
242
}
236
243
237
244
/**
@@ -284,6 +291,21 @@ public PlatformCommandManager getPlatformCommandManager() {
284
291
return platformCommandManager ;
285
292
}
286
293
294
+ /**
295
+ * Get the executor service. Internal, not for API use.
296
+ *
297
+ * @return the executor service
298
+ */
299
+ public ListeningExecutorService getExecutorService () {
300
+ return executorService .valueOrThrow ();
301
+ }
302
+
303
+ private static ListeningExecutorService createExecutor () {
304
+ return MoreExecutors .listeningDecorator (
305
+ EvenMoreExecutors .newBoundedCachedThreadPool (
306
+ 0 , 1 , 20 , "WorldEdit Task Executor - %s" ));
307
+ }
308
+
287
309
/**
288
310
* Get the current configuration.
289
311
*
@@ -340,6 +362,10 @@ public void handlePlatformsRegistered(PlatformsRegisteredEvent event) {
340
362
@ Subscribe
341
363
public void handleNewPlatformReady (PlatformReadyEvent event ) {
342
364
preferences .forEach ((cap , platform ) -> cap .ready (this , platform ));
365
+ platforms .put (event .getPlatform (), true );
366
+ if (!executorService .isValid ()) {
367
+ executorService .newValue (createExecutor ());
368
+ }
343
369
}
344
370
345
371
/**
@@ -348,6 +374,11 @@ public void handleNewPlatformReady(PlatformReadyEvent event) {
348
374
@ Subscribe
349
375
public void handleNewPlatformUnready (PlatformUnreadyEvent event ) {
350
376
preferences .forEach ((cap , platform ) -> cap .unready (this , platform ));
377
+ platforms .put (event .getPlatform (), false );
378
+ if (!platforms .containsValue (true )) {
379
+ executorService .value ().ifPresent (ListeningExecutorService ::shutdownNow );
380
+ executorService .invalidate ();
381
+ }
351
382
}
352
383
353
384
@ Subscribe
0 commit comments