loading doesn't cause unavoidable lag (removed excessive blocking);

switched to a blocking queue list to manage album cover loading; threads
that should be daemons are daemons now;
This commit is contained in:
Harrison Deng 2018-08-23 22:21:33 -05:00
parent 211e37866e
commit b97d772ee9
3 changed files with 77 additions and 69 deletions

View File

@ -149,6 +149,7 @@ public class MusicList extends Observable {
@Override @Override
public void run() { public void run() {
Gdx.app.debug("MusicList", "recursive async search beginning.");
Array<FileHandle> obtainedAudioFiles = recursiveMusicSearch(directory); Array<FileHandle> obtainedAudioFiles = recursiveMusicSearch(directory);
Sort.instance().sort(obtainedAudioFiles, compare); Sort.instance().sort(obtainedAudioFiles, compare);
if (work) { if (work) {
@ -164,6 +165,7 @@ public class MusicList extends Observable {
if (thread == null) { if (thread == null) {
work = true; work = true;
thread = new Thread(this, threadName); thread = new Thread(this, threadName);
thread.setDaemon(true);
thread.start(); thread.start();
return true; return true;
} else { } else {

View File

@ -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() { public boolean isDone() {
return (metadataArray.size == musicList.getMusicArray().size); return (metadataArray.size == musicList.getMusicArray().size);
} }
@ -52,16 +56,12 @@ public class MusicMetadataController extends Observable implements Disposable, O
} }
public int size() { public int size() {
synchronized (loadingThread) {
return metadataArray.size; return metadataArray.size;
} }
}
public AudioMetadata getMetadata(int index) { public AudioMetadata getMetadata(int index) {
synchronized (loadingThread) {
return metadataArray.get(index); return metadataArray.get(index);
} }
}
public AudioMetadata getInfo(FileHandle filehandle) { public AudioMetadata getInfo(FileHandle filehandle) {
@ -80,28 +80,25 @@ public class MusicMetadataController extends Observable implements Disposable, O
@Override @Override
public void run() { public void run() {
Gdx.app.debug(name, "loading..."); Gdx.app.debug(name, "loading...");
clear();
searching = true; searching = true;
for (int i = 0; i < metadataArray.size; i++) { Array<AudioMetadata> tempMetadataArray = new Array<>();
metadataArray.get(i).dispose();
}
metadataArray.clear();
for (int i = 0; i < musicList.getTotal() && work; i++) { for (int i = 0; i < musicList.getTotal() && work; i++) {
FileHandle musicFile = musicList.getMusicArray().get(i); FileHandle musicFile = musicList.getMusicArray().get(i);
synchronized (this) {
switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) { switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) {
case MP3: case MP3:
metadataArray.add(new MP3Metadata(musicFile)); tempMetadataArray.add(new MP3Metadata(musicFile));
break; break;
case WAV: case WAV:
metadataArray.add(new WAVMetadata(musicFile)); tempMetadataArray.add(new WAVMetadata(musicFile));
break; break;
default: default:
break; break;
}
}
}
}
}
if (work) { if (work) {
metadataArray = tempMetadataArray;
searching = false; searching = false;
Gdx.app.debug(name, "load complete."); Gdx.app.debug(name, "load complete.");
setChanged(); setChanged();
@ -130,4 +127,11 @@ public class MusicMetadataController extends Observable implements Disposable, O
loadAudioMetadata(); loadAudioMetadata();
} }
} }
public void clear() {
for (int i = 0; i < metadataArray.size; i++) {
metadataArray.get(i).dispose();
}
metadataArray.clear();
}
} }

View File

@ -2,6 +2,7 @@ package zero1hd.rhythmbullet.desktop.screens.main;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.concurrent.LinkedBlockingQueue;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
@ -178,6 +179,7 @@ public class MusicSelectionPage extends Page implements Observer {
private synchronized void updateList(float delta) { private synchronized void updateList(float delta) {
if (mc.getMusicList().isSearched()) { if (mc.getMusicList().isSearched()) {
if (mc.getMusicList().getTotal() != 0) { if (mc.getMusicList().getTotal() != 0) {
if (mmc.isDone() && !mmc.isSearching()) {
if (selectables.size() != mmc.size()) { if (selectables.size() != mmc.size()) {
MusicSelectable selectable = new MusicSelectable(mmc.getMetadata(selectables.size())); MusicSelectable selectable = new MusicSelectable(mmc.getMetadata(selectables.size()));
selectables.add(selectable); selectables.add(selectable);
@ -196,6 +198,8 @@ public class MusicSelectionPage extends Page implements Observer {
} }
} }
} }
}
} else { } else {
//TODO: Error message reporting empty music list or something //TODO: Error message reporting empty music list or something
} }
@ -219,6 +223,7 @@ public class MusicSelectionPage extends Page implements Observer {
@Override @Override
public void dispose() { public void dispose() {
mc.getMusicList().deleteObserver(this); mc.getMusicList().deleteObserver(this);
selectionLoaderThread.stop();
super.dispose(); super.dispose();
} }
@ -231,13 +236,15 @@ public class MusicSelectionPage extends Page implements Observer {
selectables.setChecked(mc.getCurrentMusicFileHandle()); selectables.setChecked(mc.getCurrentMusicFileHandle());
} }
} else if (o == mc.getMusicList()) { } else if (o == mc.getMusicList()) {
synchronized (this) {
if (arg == mc.getMusicList().states.LOADING) { if (arg == mc.getMusicList().states.LOADING) {
synchronized (this) {
vGroup.clear(); vGroup.clear();
selectables.clear(); selectables.clear();
musicInfoTable.setToDefault(); musicInfoTable.setToDefault();
selectionLoaderThread.clear();
} }
} }
} }
} }
@ -250,31 +257,23 @@ public class MusicSelectionPage extends Page implements Observer {
private class musicSelectionLoaderThread implements Runnable { private class musicSelectionLoaderThread implements Runnable {
private Thread thread; private Thread thread;
private Array<AudioMetadata> queueList;
private String name = "Music-Selection-Loader-Thread"; private String name = "Music-Selection-Loader-Thread";
private volatile boolean work = true; private volatile boolean work = true;
private LinkedBlockingQueue<AudioMetadata> queue;
public musicSelectionLoaderThread() { public musicSelectionLoaderThread() {
queueList = new Array<>(); queue = new LinkedBlockingQueue<>();
} }
@Override @Override
public void run() { public void run() {
while (work) { while (work) {
while (queueList.size != 0) {
AudioMetadata metadata; AudioMetadata metadata;
synchronized (this) { try {
metadata = queueList.pop(); metadata = queue.take();
metadata.loadAlbumCover(); metadata.loadAlbumCover();
simpleDebug("Loading " + metadata.getTitle()); simpleDebug("Loading " + metadata.getTitle());
}
}
synchronized (this) {
try {
wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); simpleDebug("Thread was interupted.");
}
} }
} }
} }
@ -282,21 +281,25 @@ public class MusicSelectionPage extends Page implements Observer {
public boolean start() { public boolean start() {
if (thread == null) { if (thread == null) {
thread = new Thread(this, name); thread = new Thread(this, name);
thread.setDaemon(true);
thread.start(); thread.start();
return true; return true;
} else {
synchronized (this) {
notify();
}
} }
return false; return false;
} }
public void queue(AudioMetadata metadata) { public void stop() {
if (!queueList.contains(metadata, true)) { clear();
queueList.add(metadata); thread.interrupt();
start(); work = false;
} }
public void clear() {
queue.clear();
}
public void queue(AudioMetadata metadata) {
queue.add(metadata);
} }
} }
@ -348,7 +351,7 @@ public class MusicSelectionPage extends Page implements Observer {
actualCoords.x = getX() + getParent().getX(); actualCoords.x = getX() + getParent().getX();
actualCoords.y = getY() + getParent().getY(); 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); offScreenAct(delta);
} else { } else {
onScreenAct(delta); onScreenAct(delta);
@ -365,10 +368,9 @@ public class MusicSelectionPage extends Page implements Observer {
if (offScreen) { if (offScreen) {
offScreen = false; offScreen = false;
timeSinceChanged = 0; timeSinceChanged = 0;
} else if (timeSinceChanged < 0.75f) { } else if (timeSinceChanged < 0.075f) {
timeSinceChanged += delta; timeSinceChanged += delta;
} } else {
if (timeSinceChanged >= 0.75f) {
if (!frameUsed && metadata.getAlbumCover() != null && !albumArtDisplayed) { if (!frameUsed && metadata.getAlbumCover() != null && !albumArtDisplayed) {
updateAlbumArtImage(metadata.getAlbumCover()); updateAlbumArtImage(metadata.getAlbumCover());
albumArtDisplayed = true; albumArtDisplayed = true;