diff --git a/core/src/zero1hd/rhythmbullet/audio/MusicList.java b/core/src/zero1hd/rhythmbullet/audio/MusicList.java index 5251b5a..b94fa0e 100755 --- a/core/src/zero1hd/rhythmbullet/audio/MusicList.java +++ b/core/src/zero1hd/rhythmbullet/audio/MusicList.java @@ -149,6 +149,7 @@ public class MusicList extends Observable { @Override public void run() { + Gdx.app.debug("MusicList", "recursive async search beginning."); Array obtainedAudioFiles = recursiveMusicSearch(directory); Sort.instance().sort(obtainedAudioFiles, compare); if (work) { @@ -164,6 +165,7 @@ public class MusicList extends Observable { if (thread == null) { work = true; thread = new Thread(this, threadName); + thread.setDaemon(true); thread.start(); return true; } else { diff --git a/core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java b/core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java index e8612e7..5ebe9b0 100755 --- a/core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java +++ b/core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java @@ -40,6 +40,10 @@ public class MusicMetadataController extends Observable implements Disposable, O } } + /** + * if there is the same amount of metadata as there is music in the music list. + * @return whether or not both sizes are equal. + */ public boolean isDone() { return (metadataArray.size == musicList.getMusicArray().size); } @@ -52,15 +56,11 @@ public class MusicMetadataController extends Observable implements Disposable, O } public int size() { - synchronized (loadingThread) { - return metadataArray.size; - } + return metadataArray.size; } public AudioMetadata getMetadata(int index) { - synchronized (loadingThread) { - return metadataArray.get(index); - } + return metadataArray.get(index); } @@ -80,28 +80,25 @@ public class MusicMetadataController extends Observable implements Disposable, O @Override public void run() { Gdx.app.debug(name, "loading..."); + clear(); searching = true; - for (int i = 0; i < metadataArray.size; i++) { - metadataArray.get(i).dispose(); - } - metadataArray.clear(); + Array tempMetadataArray = new Array<>(); for (int i = 0; i < musicList.getTotal() && work; i++) { FileHandle musicFile = musicList.getMusicArray().get(i); - synchronized (this) { - switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) { - case MP3: - metadataArray.add(new MP3Metadata(musicFile)); - break; - case WAV: - metadataArray.add(new WAVMetadata(musicFile)); - break; - default: - break; - - } + switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) { + case MP3: + tempMetadataArray.add(new MP3Metadata(musicFile)); + break; + case WAV: + tempMetadataArray.add(new WAVMetadata(musicFile)); + break; + default: + break; } } + if (work) { + metadataArray = tempMetadataArray; searching = false; Gdx.app.debug(name, "load complete."); setChanged(); @@ -130,4 +127,11 @@ public class MusicMetadataController extends Observable implements Disposable, O loadAudioMetadata(); } } + + public void clear() { + for (int i = 0; i < metadataArray.size; i++) { + metadataArray.get(i).dispose(); + } + metadataArray.clear(); + } } diff --git a/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java b/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java index a0b54b7..65f295d 100755 --- a/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java +++ b/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java @@ -2,6 +2,7 @@ package zero1hd.rhythmbullet.desktop.screens.main; import java.util.Observable; import java.util.Observer; +import java.util.concurrent.LinkedBlockingQueue; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; @@ -178,24 +179,27 @@ public class MusicSelectionPage extends Page implements Observer { private synchronized void updateList(float delta) { if (mc.getMusicList().isSearched()) { if (mc.getMusicList().getTotal() != 0) { - if (selectables.size() != mmc.size()) { - MusicSelectable selectable = new MusicSelectable(mmc.getMetadata(selectables.size())); - selectables.add(selectable); - } else if (selectables.size() != vGroup.getChildren().size) { - vGroup.addActor(selectables.getButtons().get(vGroup.getChildren().size)); - } else { - if (selectables.getChecked() == null) { - selectables.setMinCheckCount(1); - selectables.setChecked(mc.getCurrentMusicFileHandle()); - scrollPane.scrollTo(selectables.getChecked().getX(), selectables.getChecked().getY(), selectables.getChecked().getWidth(), selectables.getChecked().getHeight()); - } else if (selectables.getChecked().getMetadata().getFileHandle() != mc.getCurrentMusicFileHandle()) { - musicSelectDelay += delta; - if (musicSelectDelay >= 1f) { - mc.setMusicByFileHandle(selectables.getChecked().getMetadata().getFileHandle()); - musicSelectDelay = 0; + if (mmc.isDone() && !mmc.isSearching()) { + if (selectables.size() != mmc.size()) { + MusicSelectable selectable = new MusicSelectable(mmc.getMetadata(selectables.size())); + selectables.add(selectable); + } else if (selectables.size() != vGroup.getChildren().size) { + vGroup.addActor(selectables.getButtons().get(vGroup.getChildren().size)); + } else { + if (selectables.getChecked() == null) { + selectables.setMinCheckCount(1); + selectables.setChecked(mc.getCurrentMusicFileHandle()); + scrollPane.scrollTo(selectables.getChecked().getX(), selectables.getChecked().getY(), selectables.getChecked().getWidth(), selectables.getChecked().getHeight()); + } else if (selectables.getChecked().getMetadata().getFileHandle() != mc.getCurrentMusicFileHandle()) { + musicSelectDelay += delta; + if (musicSelectDelay >= 1f) { + mc.setMusicByFileHandle(selectables.getChecked().getMetadata().getFileHandle()); + musicSelectDelay = 0; + } } } } + } else { //TODO: Error message reporting empty music list or something } @@ -219,6 +223,7 @@ public class MusicSelectionPage extends Page implements Observer { @Override public void dispose() { mc.getMusicList().deleteObserver(this); + selectionLoaderThread.stop(); super.dispose(); } @@ -231,13 +236,15 @@ public class MusicSelectionPage extends Page implements Observer { selectables.setChecked(mc.getCurrentMusicFileHandle()); } } else if (o == mc.getMusicList()) { - synchronized (this) { - if (arg == mc.getMusicList().states.LOADING) { + if (arg == mc.getMusicList().states.LOADING) { + synchronized (this) { vGroup.clear(); selectables.clear(); musicInfoTable.setToDefault(); + selectionLoaderThread.clear(); } } + } } @@ -250,31 +257,23 @@ public class MusicSelectionPage extends Page implements Observer { private class musicSelectionLoaderThread implements Runnable { private Thread thread; - private Array queueList; - private String name = "Music-Selection-Loader-Thread"; + private String name = "Music-Selection-Loader-Thread"; private volatile boolean work = true; - + private LinkedBlockingQueue queue; public musicSelectionLoaderThread() { - queueList = new Array<>(); + queue = new LinkedBlockingQueue<>(); } @Override public void run() { while (work) { - while (queueList.size != 0) { - AudioMetadata metadata; - synchronized (this) { - metadata = queueList.pop(); - metadata.loadAlbumCover(); - simpleDebug("Loading " + metadata.getTitle()); - } - } - synchronized (this) { - try { - wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + AudioMetadata metadata; + try { + metadata = queue.take(); + metadata.loadAlbumCover(); + simpleDebug("Loading " + metadata.getTitle()); + } catch (InterruptedException e) { + simpleDebug("Thread was interupted."); } } } @@ -282,21 +281,25 @@ public class MusicSelectionPage extends Page implements Observer { public boolean start() { if (thread == null) { thread = new Thread(this, name); + thread.setDaemon(true); thread.start(); return true; - } else { - synchronized (this) { - notify(); - } } return false; } + public void stop() { + clear(); + thread.interrupt(); + work = false; + } + + public void clear() { + queue.clear(); + } + public void queue(AudioMetadata metadata) { - if (!queueList.contains(metadata, true)) { - queueList.add(metadata); - start(); - } + queue.add(metadata); } } @@ -348,7 +351,7 @@ public class MusicSelectionPage extends Page implements Observer { actualCoords.x = getX() + getParent().getX(); actualCoords.y = getY() + getParent().getY(); - if ((actualCoords.y < 0 - getHeight() || actualCoords.y > getStage().getHeight() || actualCoords.x < 0 - getWidth() || actualCoords.x > getStage().getWidth()) && selectables.getChecked() != this) { + if ((actualCoords.y < 0 - getHeight() - getStage().getHeight()*1.5f || actualCoords.y > getStage().getHeight()*1.5f) && selectables.getChecked() != this) { offScreenAct(delta); } else { onScreenAct(delta); @@ -365,10 +368,9 @@ public class MusicSelectionPage extends Page implements Observer { if (offScreen) { offScreen = false; timeSinceChanged = 0; - } else if (timeSinceChanged < 0.75f) { + } else if (timeSinceChanged < 0.075f) { timeSinceChanged += delta; - } - if (timeSinceChanged >= 0.75f) { + } else { if (!frameUsed && metadata.getAlbumCover() != null && !albumArtDisplayed) { updateAlbumArtImage(metadata.getAlbumCover()); albumArtDisplayed = true;