progress on untested framework

This commit is contained in:
2018-08-02 09:21:25 -05:00
parent 590cb39902
commit 45da676d0d
21 changed files with 428 additions and 495 deletions

View File

@@ -36,7 +36,7 @@ public class RhythmBullet extends Game {
private AssetManager assetManager = new AssetManager();
private Skin skin;
TextureAtlas skinAtlas;
private Preferences prefs;
private Preferences preferences;
private RoundingResolutionHandler rRHandler;
private Screen initialScreen;
private AssetPack assetPack;
@@ -58,7 +58,7 @@ public class RhythmBullet extends Game {
assetPack.initiateResources();
prefs = Gdx.app.getPreferences("RhythmBullet Preferences");
preferences = Gdx.app.getPreferences("RhythmBullet Preferences");
Resolution[] resolution = {
new Resolution(1280, 720, "1280x720"),
@@ -78,7 +78,7 @@ public class RhythmBullet extends Game {
assetManager.setLoader(ParticleEffect.class, new ParticleEffectLoader(genericFileFinder));
assetManager.setLoader(Sound.class, new SoundLoader(genericFileFinder));
rRHandler.setResolution(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
rRHandler.setResolution(getPreferences().getInteger("screen-width"), getPreferences().getInteger("screen-height"));
screenWidth = Gdx.graphics.getWidth();
@@ -86,10 +86,10 @@ public class RhythmBullet extends Game {
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
if (getPrefs().getBoolean("fullscreen", true)) {
if (getPreferences().getBoolean("fullscreen", true)) {
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
} else {
Gdx.graphics.setWindowedMode(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
Gdx.graphics.setWindowedMode(getPreferences().getInteger("screen-width"), getPreferences().getInteger("screen-height"));
}
}
@@ -161,9 +161,9 @@ public class RhythmBullet extends Game {
} else {
throw new IllegalStateException("Cannot perform window resize on a screen that isn't using a resize ready screen.");
}
prefs.putInteger("screen-width", width);
prefs.putInteger("screen-height", height);
prefs.flush();
preferences.putInteger("screen-width", width);
preferences.putInteger("screen-height", height);
preferences.flush();
resizing = true;
assetManager.clear();
queueAssets();
@@ -185,8 +185,8 @@ public class RhythmBullet extends Game {
return skin;
}
public Preferences getPrefs() {
return prefs;
public Preferences getPreferences() {
return preferences;
}
@Override

View File

@@ -31,7 +31,11 @@ public class MusicList extends Observable {
* Also notifies listeners that are on the main thread.
*/
public void asyncSearch() {
searchThread.start();
if (!searchThread.start()) {
searchThread.stop();
searchThread = new RecursiveMusicSearchThread("Music Search Thread");
searchThread.start();
}
}
public void setSearchPath(String searchPath) {
@@ -96,6 +100,7 @@ public class MusicList extends Observable {
private Thread thread;
private String threadName;
private FileHandle directory;
private volatile boolean work;
public RecursiveMusicSearchThread(String name) {
this.threadName = name;
@@ -107,23 +112,32 @@ public class MusicList extends Observable {
@Override
public void run() {
musicList = recursiveMusicSearch(directory);
searchComplete();
Array<FileHandle> obtainedAudioFiles = recursiveMusicSearch(directory);
if (work) {
musicList = obtainedAudioFiles;
searchComplete();
}
}
public void start() {
if (thread == null && !thread.isAlive()) {
public boolean start() {
if (thread == null) {
work = true;
thread = new Thread(this, threadName);
thread.start();
return true;
} else {
throw new IllegalStateException("Two " + threadName + " instances (threads) were created. This is not allowed for optimization as there is no reason to have two running.");
return false;
}
}
public void stop() {
work = false;
}
private Array<FileHandle> recursiveMusicSearch(FileHandle fileHandle) {
Array<FileHandle> musicFiles = new Array<>();
FileHandle[] files = fileHandle.list();
for (int i = 0; i < files.length; i++) {
for (int i = 0; i < files.length && work; i++) {
if (files[i].isDirectory()) {
musicFiles.addAll(recursiveMusicSearch(files[i]));
} else {

View File

@@ -11,7 +11,7 @@ import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
import zero1hd.rhythmbullet.audio.metadata.MP3Metadata;
import zero1hd.rhythmbullet.audio.metadata.WAVMetadata;
public class MusicMetadataController implements Disposable, Observer {
public class MusicMetadataController extends Observable implements Disposable, Observer {
private MusicList musicList;
private Array<AudioMetadata> metadataArray;
private MetadataLoadingThread loadingThread;
@@ -20,6 +20,8 @@ public class MusicMetadataController implements Disposable, Observer {
public MusicMetadataController(MusicList musicList) {
this.musicList = musicList;
metadataArray = new Array<>();
loadingThread = new MetadataLoadingThread();
musicList.addObserver(this);
}
public MusicList getMusicList() {
@@ -29,8 +31,12 @@ public class MusicMetadataController implements Disposable, Observer {
/**
* Non-blocking, loads on separate thread.
*/
public void loadSongInfo() {
loadingThread.start();
public void loadAudioMetadata() {
if (!loadingThread.start()) {
loadingThread.stop();
loadingThread = new MetadataLoadingThread();
loadingThread.start();
}
}
public boolean isDone() {
@@ -66,6 +72,7 @@ public class MusicMetadataController implements Disposable, Observer {
private class MetadataLoadingThread implements Runnable {
private Thread thread;
private String name = "Metadata-Load";
private volatile boolean work;
@Override
public void run() {
@@ -74,7 +81,7 @@ public class MusicMetadataController implements Disposable, Observer {
metadataArray.get(i).dispose();
}
metadataArray.clear();
for (int i = 0; i < musicList.getTotal(); i++) {
for (int i = 0; i < musicList.getTotal() && work; i++) {
FileHandle musicFile = musicList.getMusicArray().get(i);
synchronized (this) {
switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) {
@@ -90,19 +97,32 @@ public class MusicMetadataController implements Disposable, Observer {
}
}
}
searching = false;
if (work) {
searching = false;
notifyObservers();
}
}
public void start() {
if (thread != null && !thread.isAlive()) {
public boolean start() {
if (thread == null) {
thread = new Thread(this, name);
thread.start();
return true;
} else {
return false;
}
}
public void stop() {
work = false;
}
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if (o == musicList) {
loadingThread.stop();
loadAudioMetadata();
}
}
}

View File

@@ -2,13 +2,12 @@ package zero1hd.rhythmbullet.audio.analyzer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.FloatArray;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
import zero1hd.rhythmbullet.audio.processor.AudioProcessor;
public class AudioAnalyzer implements Runnable, Disposable {
public class AudioAnalyzer implements Runnable {
private Thread thread;
private String threadName = "Audio-Analyzer";
@@ -38,15 +37,15 @@ public class AudioAnalyzer implements Runnable, Disposable {
private int PUID;
private int progress;
public AudioAnalyzer(AudioProcessor audioProcessor) {
this.processor = audioProcessor;
}
public void start() {
if (thread == null || !thread.isAlive()) {
public boolean start(AudioProcessor processor) {
if (thread == null) {
this.processor = processor;
work = true;
thread = new Thread(this, threadName);
thread.start();
return true;
} else {
return false;
}
}
@@ -282,13 +281,6 @@ public class AudioAnalyzer implements Runnable, Disposable {
public int getProgress() {
return progress;
}
@Override
public void dispose() {
if (thread != null) {
work = false;
}
}
public void stop() {
work = false;

View File

@@ -37,7 +37,13 @@ public interface AudioMetadata extends Disposable {
*
* @return the length of the song with proper fomatting.
*/
public String getLength();
public String getDuration();
/**
*
* @return the length of the song in seconds.
*/
public int getLength();
/**
*

View File

@@ -18,7 +18,8 @@ import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
public class MP3Metadata implements AudioMetadata {
private String title, author, length, genre;
private String title, author, duration, genre;
private int length;
private Texture albumCover;
private FileHandle fileHandle;
@@ -38,9 +39,9 @@ public class MP3Metadata implements AudioMetadata {
int lenInSec = mp3file.getAudioHeader().getTrackLength();
int min = (int) (lenInSec/60);
length = (lenInSec/60) + ":" + (lenInSec - (min*60));
length = mp3file.getAudioHeader().getTrackLength();
int min = (int) (length/60);
duration = (length/60) + ":" + (length - (min*60));
author = tag.getFirst(ID3v23FieldKey.ARTIST);
genre = tag.getFirst(ID3v23FieldKey.GENRE);
@@ -86,7 +87,12 @@ public class MP3Metadata implements AudioMetadata {
}
@Override
public String getLength() {
public String getDuration() {
return duration;
}
@Override
public int getLength() {
return length;
}

View File

@@ -17,7 +17,8 @@ import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
public class WAVMetadata implements AudioMetadata {
private String title, author, length, genre;
private String title, author, duration, genre;
private int length;
private Texture albumCover;
private FileHandle fileHandle;
@@ -26,9 +27,9 @@ public class WAVMetadata implements AudioMetadata {
try {
AudioFile wav = AudioFileIO.read(fileHandle.file());
int lenInSec = wav.getAudioHeader().getTrackLength();
int min = (int) (lenInSec/60);
this.length = (lenInSec/60) + ":" + (lenInSec - (min*60));
length = wav.getAudioHeader().getTrackLength();
int min = (int) (length/60);
this.duration = (length/60) + ":" + (length - (min*60));
Tag tag = wav.getTag();
title = tag.getFirst(FieldKey.TITLE);
@@ -70,9 +71,15 @@ public class WAVMetadata implements AudioMetadata {
return title;
}
@Override
public String getLength() {
public String getDuration() {
return duration;
}
@Override
public int getLength() {
return length;
}
@Override
public Texture getAlbumCover() {
return albumCover;

View File

@@ -0,0 +1,74 @@
package zero1hd.rhythmbullet.graphics.ui.components;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
public class MusicSelectable extends Button {
private Vector2 actualCoords;
private Image album;
private Table informationTable;
private ShortenedLabel name, artist;
private Label time;
private float timeSinceOnScreen;
private AudioMetadata metadata;
private Texture defaultAlbumArt;
public MusicSelectable(Skin skin, Texture defaultAlbumArt, AudioMetadata metadata) {
super(skin, "music-selectable");
this.metadata = metadata;
this.defaultAlbumArt = defaultAlbumArt;
album = new Image(defaultAlbumArt);
add(album).expand().left();
informationTable = new Table();
name = new ShortenedLabel(metadata.getTitle(), skin, "default-font", skin.getColor("default"));
informationTable.add(name).colspan(2).expandX();
informationTable.row();
artist = new ShortenedLabel(metadata.getTitle(), skin, "sub-font", skin.getColor("default"));
informationTable.add(artist).expandX();
time = new Label(metadata.getDuration(), skin, "sub-font", skin.getColor("default"));
informationTable.add(time).expandX();
add(informationTable).expand().fill();
}
@Override
public void act(float delta) {
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()) {
offScreenAct(delta);
} else {
onScreenAct(delta);
}
super.act(delta);
}
public void onScreenAct(float delta) {
timeSinceOnScreen = 0;
if (metadata.getAlbumCover() == null) {
metadata.loadAlbumCover();
album.setDrawable(new TextureRegionDrawable(new TextureRegion(metadata.getAlbumCover())));
}
}
public void offScreenAct(float delta) {
if (metadata.getAlbumCover() != null) {
timeSinceOnScreen += delta;
if (timeSinceOnScreen >= 2) {
metadata.unloadAlbumCover();
}
}
}
}

View File

@@ -89,6 +89,8 @@ public class ScrollText extends Widget {
@Override
public void layout() {
super.layout();
if (getHeight() < (textHeight+4)) {
setHeight(textHeight + 4);
}
@@ -98,7 +100,6 @@ public class ScrollText extends Widget {
if (text1Width < clipBounds.getWidth()) {
text1Offset = (clipBounds.getWidth()-text1Width)/2f;
}
super.layout();
}
@Override

View File

@@ -3,34 +3,37 @@ package zero1hd.rhythmbullet.graphics.ui.components;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
public class ShortenedTextLabel extends Label {
public class ShortenedLabel extends Label {
private String originalText;
private int targetWidth;
private GlyphLayout gl;
private BitmapFont font;
private Vector2 size;
public ShortenedTextLabel(CharSequence text, Skin skin, String fontName, Color color) {
super(text, skin, fontName, color);
public ShortenedLabel(CharSequence text, Skin skin, String fontName, Color color) {
super(null, skin, fontName, color);
originalText = text.toString();
font = skin.getFont(fontName);
if (text != null) {
gl = new GlyphLayout(skin.getFont(fontName), text);
}
}
public void setTargetWidth(int targetWidth) {
this.targetWidth = targetWidth;
size = new Vector2();
setWrap(true);
}
public void resize() {
setToOriginalText();
while (gl.width > targetWidth && (getText().length - 4) > 0) {
setText(getText().substring(0, getText().length - 4).concat("..."));
gl.setText(font, getText());
String text = getText().toString();
while (gl.width > targetWidth && (text.length() - 4) > 0) {
text = text.substring(0, text.length() - 4).concat("...");
gl.setText(font, text);
}
setText(text);
}
public void setToOriginalText() {
@@ -41,6 +44,10 @@ public class ShortenedTextLabel extends Label {
@Override
public void layout() {
super.layout();
size.x = getWidth();
size.y = getHeight();
targetWidth = (int) getStage().stageToScreenCoordinates(size).x;
resize();
}
public void setOriginalText(String originalText) {