Made OsuGroupList a singleton.

(This makes a lot more sense than storing the single pointer in Opsu.groups.)

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han
2015-01-11 14:17:33 -05:00
parent af8512c080
commit 4152af4977
6 changed files with 41 additions and 30 deletions

View File

@@ -54,11 +54,6 @@ import org.newdawn.slick.util.ResourceLoader;
* Creates game container, adds all other states, and initializes song data. * Creates game container, adds all other states, and initializes song data.
*/ */
public class Opsu extends StateBasedGame { public class Opsu extends StateBasedGame {
/**
* Song group structure (each group contains of an ArrayList of OsuFiles).
*/
public static OsuGroupList groups = new OsuGroupList();
/** /**
* Game states. * Game states.
*/ */
@@ -93,6 +88,9 @@ public class Opsu extends StateBasedGame {
addState(new Options(STATE_OPTIONS)); addState(new Options(STATE_OPTIONS));
} }
/**
* Launches opsu!.
*/
public static void main(String[] args) { public static void main(String[] args) {
// log all errors to a file // log all errors to a file
Log.setVerbose(false); Log.setVerbose(false);

View File

@@ -30,6 +30,11 @@ import java.util.regex.Pattern;
* Indexed, expanding, doubly-linked list data type for song groups. * Indexed, expanding, doubly-linked list data type for song groups.
*/ */
public class OsuGroupList { public class OsuGroupList {
/**
* Song group structure (each group contains of an ArrayList of OsuFiles).
*/
private static OsuGroupList list = new OsuGroupList();
/** /**
* Search pattern for conditional expressions. * Search pattern for conditional expressions.
*/ */
@@ -64,10 +69,15 @@ public class OsuGroupList {
*/ */
private String lastQuery = ""; private String lastQuery = "";
/**
* Returns the single instance of this class.
*/
public static OsuGroupList get() { return list; }
/** /**
* Constructor. * Constructor.
*/ */
public OsuGroupList() { private OsuGroupList() {
parsedNodes = new ArrayList<OsuGroupNode>(); parsedNodes = new ArrayList<OsuGroupNode>();
nodes = parsedNodes; nodes = parsedNodes;
} }

View File

@@ -93,7 +93,7 @@ public class OsuParser {
} }
if (!osuFiles.isEmpty()) { // add entry if non-empty if (!osuFiles.isEmpty()) { // add entry if non-empty
Collections.sort(osuFiles); Collections.sort(osuFiles);
Opsu.groups.addSongGroup(osuFiles); OsuGroupList.get().addSongGroup(osuFiles);
} }
} }

View File

@@ -22,6 +22,7 @@ import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.MenuButton; import itdelatrisu.opsu.MenuButton;
import itdelatrisu.opsu.Opsu; import itdelatrisu.opsu.Opsu;
import itdelatrisu.opsu.OsuFile; import itdelatrisu.opsu.OsuFile;
import itdelatrisu.opsu.OsuGroupList;
import itdelatrisu.opsu.OsuGroupNode; import itdelatrisu.opsu.OsuGroupNode;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.audio.MusicController; import itdelatrisu.opsu.audio.MusicController;
@@ -217,7 +218,7 @@ public class MainMenu extends BasicGameState {
g.setFont(Utils.FONT_MEDIUM); g.setFont(Utils.FONT_MEDIUM);
int lineHeight = Utils.FONT_MEDIUM.getLineHeight(); int lineHeight = Utils.FONT_MEDIUM.getLineHeight();
g.drawString(String.format("Loaded %d songs and %d beatmaps.", g.drawString(String.format("Loaded %d songs and %d beatmaps.",
Opsu.groups.size(), Opsu.groups.getMapCount()), 25, 25); OsuGroupList.get().size(), OsuGroupList.get().getMapCount()), 25, 25);
if (MusicController.isTrackLoading()) if (MusicController.isTrackLoading())
g.drawString("Track loading...", 25, 25 + lineHeight); g.drawString("Track loading...", 25, 25 + lineHeight);
else if (MusicController.trackExists()) { else if (MusicController.trackExists()) {
@@ -349,7 +350,7 @@ public class MainMenu extends BasicGameState {
} else if (musicNext.contains(x, y)) { } else if (musicNext.contains(x, y)) {
boolean isTheme = MusicController.isThemePlaying(); boolean isTheme = MusicController.isThemePlaying();
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU); SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
OsuGroupNode node = menu.setFocus(Opsu.groups.getRandomNode(), -1, true); OsuGroupNode node = menu.setFocus(OsuGroupList.get().getRandomNode(), -1, true);
boolean sameAudio = false; boolean sameAudio = false;
if (node != null) { if (node != null) {
sameAudio = MusicController.getOsuFile().audioFilename.equals(node.osuFiles.get(0).audioFilename); sameAudio = MusicController.getOsuFile().audioFilename.equals(node.osuFiles.get(0).audioFilename);
@@ -361,7 +362,7 @@ public class MainMenu extends BasicGameState {
} else if (musicPrevious.contains(x, y)) { } else if (musicPrevious.contains(x, y)) {
if (!previous.isEmpty()) { if (!previous.isEmpty()) {
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU); SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
menu.setFocus(Opsu.groups.getBaseNode(previous.pop()), -1, true); menu.setFocus(OsuGroupList.get().getBaseNode(previous.pop()), -1, true);
if (Options.isDynamicBackgroundEnabled()) if (Options.isDynamicBackgroundEnabled())
bgAlpha = 0f; bgAlpha = 0f;
} else } else

View File

@@ -22,6 +22,7 @@ import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.MenuButton; import itdelatrisu.opsu.MenuButton;
import itdelatrisu.opsu.Opsu; import itdelatrisu.opsu.Opsu;
import itdelatrisu.opsu.OsuFile; import itdelatrisu.opsu.OsuFile;
import itdelatrisu.opsu.OsuGroupList;
import itdelatrisu.opsu.OsuGroupNode; import itdelatrisu.opsu.OsuGroupNode;
import itdelatrisu.opsu.OsuParser; import itdelatrisu.opsu.OsuParser;
import itdelatrisu.opsu.SongSort; import itdelatrisu.opsu.SongSort;
@@ -287,7 +288,7 @@ public class SongMenu extends BasicGameState {
g.setColor(Utils.COLOR_BLACK_ALPHA); g.setColor(Utils.COLOR_BLACK_ALPHA);
g.fillRoundRect(width - 10, scrollStartY, 5, scrollEndY, 4); g.fillRoundRect(width - 10, scrollStartY, 5, scrollEndY, 4);
g.setColor(Color.white); g.setColor(Color.white);
g.fillRoundRect(width - 10, scrollStartY + (scrollEndY * startNode.index / Opsu.groups.size()), 5, 20, 4); g.fillRoundRect(width - 10, scrollStartY + (scrollEndY * startNode.index / OsuGroupList.get().size()), 5, 20, 4);
} }
// back button // back button
@@ -313,30 +314,30 @@ public class SongMenu extends BasicGameState {
// store the start/focus nodes // store the start/focus nodes
if (focusNode != null) { if (focusNode != null) {
oldFocusNode = Opsu.groups.getBaseNode(focusNode.index); oldFocusNode = OsuGroupList.get().getBaseNode(focusNode.index);
oldFileIndex = focusNode.osuFileIndex; oldFileIndex = focusNode.osuFileIndex;
} }
if (Opsu.groups.search(search.getText())) { if (OsuGroupList.get().search(search.getText())) {
// empty search // empty search
if (search.getText().isEmpty()) if (search.getText().isEmpty())
searchResultString = "Type to search!"; searchResultString = "Type to search!";
// search produced new list: re-initialize it // search produced new list: re-initialize it
startNode = focusNode = null; startNode = focusNode = null;
if (Opsu.groups.size() > 0) { if (OsuGroupList.get().size() > 0) {
Opsu.groups.init(); OsuGroupList.get().init();
if (search.getText().isEmpty()) { // cleared search if (search.getText().isEmpty()) { // cleared search
// use previous start/focus if possible // use previous start/focus if possible
if (oldFocusNode != null) if (oldFocusNode != null)
setFocus(oldFocusNode, oldFileIndex, true); setFocus(oldFocusNode, oldFileIndex, true);
else else
setFocus(Opsu.groups.getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true);
} else { } else {
int size = Opsu.groups.size(); int size = OsuGroupList.get().size();
searchResultString = String.format("%d match%s found!", searchResultString = String.format("%d match%s found!",
size, (size == 1) ? "" : "es"); size, (size == 1) ? "" : "es");
setFocus(Opsu.groups.getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true);
} }
oldFocusNode = null; oldFocusNode = null;
oldFileIndex = -1; oldFileIndex = -1;
@@ -362,7 +363,7 @@ public class SongMenu extends BasicGameState {
OsuGroupNode node = startNode; OsuGroupNode node = startNode;
boolean isHover = false; boolean isHover = false;
for (int i = 0; i < MAX_BUTTONS && node != null; i++, node = node.next) { for (int i = 0; i < MAX_BUTTONS && node != null; i++, node = node.next) {
float cx = (node.index == Opsu.groups.getExpandedIndex()) ? buttonX * 0.9f : buttonX; float cx = (node.index == OsuGroupList.get().getExpandedIndex()) ? buttonX * 0.9f : buttonX;
if ((mouseX > cx && mouseX < cx + buttonWidth) && if ((mouseX > cx && mouseX < cx + buttonWidth) &&
(mouseY > buttonY + (i * buttonOffset) && mouseY < buttonY + (i * buttonOffset) + buttonHeight)) { (mouseY > buttonY + (i * buttonOffset) && mouseY < buttonY + (i * buttonOffset) + buttonHeight)) {
if (i == hoverIndex) { if (i == hoverIndex) {
@@ -418,10 +419,10 @@ public class SongMenu extends BasicGameState {
if (sort != SongSort.getSort()) { if (sort != SongSort.getSort()) {
SongSort.setSort(sort); SongSort.setSort(sort);
SoundController.playSound(SoundEffect.MENUCLICK); SoundController.playSound(SoundEffect.MENUCLICK);
OsuGroupNode oldFocusBase = Opsu.groups.getBaseNode(focusNode.index); OsuGroupNode oldFocusBase = OsuGroupList.get().getBaseNode(focusNode.index);
int oldFocusFileIndex = focusNode.osuFileIndex; int oldFocusFileIndex = focusNode.osuFileIndex;
focusNode = null; focusNode = null;
Opsu.groups.init(); OsuGroupList.get().init();
setFocus(oldFocusBase, oldFocusFileIndex, true); setFocus(oldFocusBase, oldFocusFileIndex, true);
} }
return; return;
@@ -429,7 +430,7 @@ public class SongMenu extends BasicGameState {
} }
// song buttons // song buttons
int expandedIndex = Opsu.groups.getExpandedIndex(); int expandedIndex = OsuGroupList.get().getExpandedIndex();
OsuGroupNode node = startNode; OsuGroupNode node = startNode;
for (int i = 0; i < MAX_BUTTONS && node != null; i++, node = node.next) { for (int i = 0; i < MAX_BUTTONS && node != null; i++, node = node.next) {
// is button at this index clicked? // is button at this index clicked?
@@ -484,7 +485,7 @@ public class SongMenu extends BasicGameState {
game.enterState(Opsu.STATE_OPTIONS, new EmptyTransition(), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_OPTIONS, new EmptyTransition(), new FadeInTransition(Color.black));
break; break;
case Input.KEY_F2: case Input.KEY_F2:
setFocus(Opsu.groups.getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true);
break; break;
case Input.KEY_F12: case Input.KEY_F12:
Utils.takeScreenShot(); Utils.takeScreenShot();
@@ -598,7 +599,7 @@ public class SongMenu extends BasicGameState {
n++; n++;
shifted = true; shifted = true;
} else if (n > 0 && startNode.next != null && } else if (n > 0 && startNode.next != null &&
Opsu.groups.getNode(startNode, MAX_BUTTONS) != null) { OsuGroupList.get().getNode(startNode, MAX_BUTTONS) != null) {
startNode = startNode.next; startNode = startNode.next;
buttonY -= buttonOffset / 4; buttonY -= buttonOffset / 4;
if (buttonY < height * 0.14f) if (buttonY < height * 0.14f)
@@ -632,9 +633,9 @@ public class SongMenu extends BasicGameState {
OsuGroupNode oldFocus = focusNode; OsuGroupNode oldFocus = focusNode;
// expand node before focusing it // expand node before focusing it
int expandedIndex = Opsu.groups.getExpandedIndex(); int expandedIndex = OsuGroupList.get().getExpandedIndex();
if (node.index != expandedIndex) { if (node.index != expandedIndex) {
node = Opsu.groups.expand(node.index); node = OsuGroupList.get().expand(node.index);
// if start node was previously expanded, move it // if start node was previously expanded, move it
if (startNode != null && startNode.index == expandedIndex) if (startNode != null && startNode.index == expandedIndex)
@@ -649,13 +650,13 @@ public class SongMenu extends BasicGameState {
// change the focus node // change the focus node
if (flag || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null)) if (flag || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null))
startNode = node; startNode = node;
focusNode = Opsu.groups.getNode(node, pos); focusNode = OsuGroupList.get().getNode(node, pos);
OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex); OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex);
MusicController.play(osu, true); MusicController.play(osu, true);
Utils.loadGlyphs(osu); Utils.loadGlyphs(osu);
// check startNode bounds // check startNode bounds
while (startNode.index >= Opsu.groups.size() + length - MAX_BUTTONS && startNode.prev != null) while (startNode.index >= OsuGroupList.get().size() + length - MAX_BUTTONS && startNode.prev != null)
startNode = startNode.prev; startNode = startNode.prev;
// make sure focusNode is on the screen (TODO: cleanup...) // make sure focusNode is on the screen (TODO: cleanup...)

View File

@@ -20,6 +20,7 @@ package itdelatrisu.opsu.states;
import itdelatrisu.opsu.GameImage; import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.Opsu; import itdelatrisu.opsu.Opsu;
import itdelatrisu.opsu.OsuGroupList;
import itdelatrisu.opsu.OsuParser; import itdelatrisu.opsu.OsuParser;
import itdelatrisu.opsu.OszUnpacker; import itdelatrisu.opsu.OszUnpacker;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
@@ -133,8 +134,8 @@ public class Splash extends BasicGameState {
// change states when loading complete // change states when loading complete
if (finished && alpha >= 1f) { if (finished && alpha >= 1f) {
// initialize song list // initialize song list
Opsu.groups.init(); OsuGroupList.get().init();
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(Opsu.groups.getRandomNode(), -1, true); ((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(OsuGroupList.get().getRandomNode(), -1, true);
// play the theme song // play the theme song
if (Options.isThemSongEnabled()) if (Options.isThemSongEnabled())