1414import com .ss .editor .ui .event .impl .RequestedRefreshAssetEvent ;
1515import com .ss .editor .util .EditorUtil ;
1616import com .ss .editor .util .SimpleFileVisitor ;
17+ import com .ss .editor .util .SimpleFolderVisitor ;
1718
1819import java .io .IOException ;
1920import java .net .URL ;
3536import rlib .util .ArrayUtils ;
3637import rlib .util .FileUtils ;
3738import rlib .util .StringUtils ;
39+ import rlib .util .Util ;
3840import rlib .util .array .Array ;
3941import rlib .util .array .ArrayComparator ;
4042import rlib .util .array .ArrayFactory ;
@@ -100,13 +102,14 @@ public static ResourceManager getInstance() {
100102 private final Array <String > materialDefinitions ;
101103
102104 /**
103- * Ключ для слежения за изменением папок.
105+ * Ключи для слежения за изменением папок.
104106 */
105- private volatile WatchKey watchKey ;
107+ private final Array < WatchKey > watchKeys ;
106108
107109 public ResourceManager () {
108110 InitializeManager .valid (getClass ());
109111
112+ this .watchKeys = ArrayFactory .newArray (WatchKey .class );
110113 this .classLoaders = ArrayFactory .newArray (URLClassLoader .class );
111114 this .resourcesInClasspath = ArrayFactory .newArray (String .class );
112115 this .materialDefinitionsInClasspath = ArrayFactory .newArray (String .class );
@@ -353,12 +356,9 @@ public Array<String> getAvailableMaterialDefinitions() {
353356 */
354357 private synchronized void reload () {
355358
356- final WatchKey currentWatchKey = getWatchKey ();
357-
358- if (currentWatchKey != null ) {
359- currentWatchKey .cancel ();
360- setWatchKey (null );
361- }
359+ final Array <WatchKey > watchKeys = getWatchKeys ();
360+ watchKeys .forEach (WatchKey ::cancel );
361+ watchKeys .clear ();
362362
363363 final Editor editor = Editor .getInstance ();
364364 final AssetManager assetManager = editor .getAssetManager ();
@@ -381,13 +381,19 @@ private synchronized void reload() {
381381 }
382382
383383 try {
384- final WatchKey watchKey = currentAsset .register (WATCH_SERVICE , ENTRY_CREATE , ENTRY_DELETE );
385- setWatchKey ( watchKey );
384+ watchKeys . add ( currentAsset .register (WATCH_SERVICE , ENTRY_CREATE , ENTRY_DELETE ) );
385+ Files . walkFileTree ( currentAsset , ( SimpleFolderVisitor ) ( file , attrs ) -> registerFolder ( watchKeys , file ) );
386386 } catch (IOException e ) {
387387 LOGGER .warning (e );
388388 }
389389 }
390390
391+ private static void registerFolder (final Array <WatchKey > watchKeys , final Path file ) {
392+ watchKeys .add (Util .safeExecute (file , first -> {
393+ return first .register (WATCH_SERVICE , ENTRY_CREATE , ENTRY_DELETE );
394+ }));
395+ }
396+
391397 /**
392398 * Обработка файла в папаке asset.
393399 */
@@ -425,35 +431,71 @@ public void run() {
425431 while (true ) {
426432 ThreadUtils .sleep (200 );
427433
428- final WatchKey watchKey = getWatchKey ();
429- final List <WatchEvent <?>> watchEvents = watchKey .pollEvents ();
434+ final Array <WatchKey > watchKeys = getWatchKeys ();
435+
436+ List <WatchEvent <?>> watchEvents = null ;
437+ WatchKey watchKey = null ;
438+
439+ synchronized (this ) {
440+ for (final WatchKey key : watchKeys ) {
441+ watchKey = key ;
442+ watchEvents = key .pollEvents ();
443+ if (!watchEvents .isEmpty ()) break ;
444+ }
445+ }
430446
431- if (watchEvents .isEmpty ()) continue ;
447+ if (watchEvents == null || watchEvents .isEmpty ()) continue ;
432448
433449 for (final WatchEvent <?> watchEvent : watchEvents ) {
434450
435451 final Path file = (Path ) watchEvent .context ();
436- final Path realFile = EditorUtil .getRealFile (file );
452+ final Path folder = (Path ) watchKey .watchable ();
453+ final Path realFile = folder .resolve (file );
437454
438455 if (watchEvent .kind () == ENTRY_CREATE ) {
439456
440457 final CreatedFileEvent event = new CreatedFileEvent ();
441458 event .setFile (realFile );
442459 event .setNeedSelect (false );
443460
461+ if (Files .isDirectory (realFile )) {
462+ registerWatchKey (realFile );
463+ }
464+
444465 FX_EVENT_MANAGER .notify (event );
445466
446467 } else if (watchEvent .kind () == ENTRY_DELETE ) {
447468
448469 final DeletedFileEvent event = new DeletedFileEvent ();
449470 event .setFile (realFile );
450471
472+ removeWatchKeyFor (realFile );
473+
451474 FX_EVENT_MANAGER .notify (event );
452475 }
453476 }
454477 }
455478 }
456479
480+ private synchronized WatchKey findWatchKey (final Path path ) {
481+ final Array <WatchKey > watchKeys = getWatchKeys ();
482+ return watchKeys .search (path , (toCheck , watchKey ) -> watchKey .watchable ().equals (toCheck ));
483+ }
484+
485+ private synchronized void removeWatchKeyFor (final Path path ) {
486+
487+ final WatchKey watchKey = findWatchKey (path );
488+
489+ if (watchKey != null ) {
490+ getWatchKeys ().fastRemove (watchKey );
491+ watchKey .cancel ();
492+ }
493+ }
494+
495+ private synchronized void registerWatchKey (final Path dir ) {
496+ Util .safeExecute (() -> getWatchKeys ().add (dir .register (WATCH_SERVICE , ENTRY_CREATE , ENTRY_DELETE )));
497+ }
498+
457499 /**
458500 * Обработка обновления Asset.
459501 */
@@ -469,16 +511,9 @@ private void processChangeAsset() {
469511 }
470512
471513 /**
472- * @return ключ для слежения за изменением папок.
473- */
474- private WatchKey getWatchKey () {
475- return watchKey ;
476- }
477-
478- /**
479- * @param watchKey ключ для слежения за изменением папок.
514+ * @return ключи для слежения за изменением папок.
480515 */
481- private void setWatchKey ( final WatchKey watchKey ) {
482- this . watchKey = watchKey ;
516+ private Array < WatchKey > getWatchKeys ( ) {
517+ return watchKeys ;
483518 }
484519}
0 commit comments