From 6d974c98377db9101e595f3fd908e42b684fa8fb Mon Sep 17 00:00:00 2001 From: exch-bms2 Date: Sun, 3 Sep 2017 01:35:01 +0900 Subject: [PATCH] Music Select : show status of song/table updater, refactor, fix previous merge --- src/bms/player/beatoraja/MainController.java | 80 ++- .../player/beatoraja/TableDataAccessor.java | 15 +- .../beatoraja/external/BMSSearchAccessor.java | 8 +- src/bms/player/beatoraja/select/Bar.java | 650 ------------------ .../player/beatoraja/select/BarRenderer.java | 1 + .../player/beatoraja/select/BarSorter.java | 3 + .../select/MusicSelectInputProcessor.java | 1 + .../beatoraja/select/MusicSelector.java | 47 +- .../beatoraja/select/SearchTextField.java | 1 + .../select/SkinDistributionGraph.java | 11 +- src/bms/player/beatoraja/select/bar/Bar.java | 33 + .../beatoraja/select/bar/CommandBar.java | 87 +++ .../beatoraja/select/bar/ContainerBar.java | 25 + .../beatoraja/select/bar/DirectoryBar.java | 38 + .../beatoraja/select/bar/FolderBar.java | 109 +++ .../player/beatoraja/select/bar/GradeBar.java | 104 +++ .../player/beatoraja/select/bar/HashBar.java | 100 +++ .../beatoraja/select/bar/SameFolderBar.java | 42 ++ .../beatoraja/select/bar/SearchWordBar.java | 40 ++ .../beatoraja/select/bar/SelectableBar.java | 30 + .../player/beatoraja/select/bar/SongBar.java | 46 ++ .../player/beatoraja/select/bar/TableBar.java | 90 +++ 22 files changed, 858 insertions(+), 703 deletions(-) delete mode 100644 src/bms/player/beatoraja/select/Bar.java create mode 100644 src/bms/player/beatoraja/select/bar/Bar.java create mode 100644 src/bms/player/beatoraja/select/bar/CommandBar.java create mode 100644 src/bms/player/beatoraja/select/bar/ContainerBar.java create mode 100644 src/bms/player/beatoraja/select/bar/DirectoryBar.java create mode 100644 src/bms/player/beatoraja/select/bar/FolderBar.java create mode 100644 src/bms/player/beatoraja/select/bar/GradeBar.java create mode 100644 src/bms/player/beatoraja/select/bar/HashBar.java create mode 100644 src/bms/player/beatoraja/select/bar/SameFolderBar.java create mode 100644 src/bms/player/beatoraja/select/bar/SearchWordBar.java create mode 100644 src/bms/player/beatoraja/select/bar/SelectableBar.java create mode 100644 src/bms/player/beatoraja/select/bar/SongBar.java create mode 100644 src/bms/player/beatoraja/select/bar/TableBar.java diff --git a/src/bms/player/beatoraja/MainController.java b/src/bms/player/beatoraja/MainController.java index ce05c08b1..ce8e9eeb3 100644 --- a/src/bms/player/beatoraja/MainController.java +++ b/src/bms/player/beatoraja/MainController.java @@ -8,6 +8,7 @@ import java.util.logging.Logger; import bms.player.beatoraja.play.TargetProperty; +import bms.player.beatoraja.select.bar.TableBar; import bms.player.beatoraja.skin.SkinLoader; import bms.player.beatoraja.skin.SkinProperty; import com.badlogic.gdx.Graphics; @@ -338,7 +339,12 @@ public void render() { systemfont.draw(sprite, "Screen shot saved : " + screenshot.path, 100, config.getResolution().height - 2); sprite.end(); - } + } else if(updateSong != null && updateSong.isAlive()) { + sprite.begin(); + systemfont.setColor(0,1,1,0.5f + (System.currentTimeMillis() % 500) / 1000.0f); + systemfont.draw(sprite, updateSong.message, 100, config.getResolution().height - 2); + sprite.end(); + } final long time = System.currentTimeMillis(); if(time > prevtime) { @@ -530,4 +536,76 @@ public void run() { savetime = System.currentTimeMillis(); } } + + private UpdateThread updateSong; + + public void updateSong(String path) { + if (updateSong == null || !updateSong.isAlive()) { + updateSong = new SongUpdateThread(path); + updateSong.start(); + } else { + Logger.getGlobal().warning("楽曲更新中のため、更新要求は取り消されました"); + } + } + + public void updateTable(TableBar reader) { + if (updateSong == null || !updateSong.isAlive()) { + updateSong = new TableUpdateThread(reader); + updateSong.start(); + } else { + Logger.getGlobal().warning("楽曲更新中のため、更新要求は取り消されました"); + } + } + + abstract class UpdateThread extends Thread { + + private String message; + + public UpdateThread(String message) { + this.message = message; + } + } + + /** + * 楽曲データベース更新用スレッド + * + * @author exch + */ + class SongUpdateThread extends UpdateThread { + + private final String path; + + public SongUpdateThread(String path) { + super("updating folder : " + (path == null ? "ALL" : path)); + this.path = path; + } + + public void run() { + getSongDatabase().updateSongDatas(path, false, getInfoDatabase()); + } + } + + /** + * 難易度表更新用スレッド + * + * @author exch + */ + class TableUpdateThread extends UpdateThread { + + private final TableBar accessor; + + public TableUpdateThread(TableBar bar) { + super("updating table : " + bar.getReader().name); + accessor = bar; + } + + public void run() { + TableData td = accessor.getReader().read(); + if (td != null) { + new TableDataAccessor().write(td); + accessor.setTableData(td); + } + } + } + } diff --git a/src/bms/player/beatoraja/TableDataAccessor.java b/src/bms/player/beatoraja/TableDataAccessor.java index 24433ed9e..9815f42bf 100644 --- a/src/bms/player/beatoraja/TableDataAccessor.java +++ b/src/bms/player/beatoraja/TableDataAccessor.java @@ -147,16 +147,23 @@ public TableData read(String name) { return td; } - public interface TableReader { + public static abstract class TableReader { - public TableData read(); + public final String name; + + public TableReader(String name) { + this.name = name; + } + + public abstract TableData read(); } - public static class DifficultyTableReader implements TableReader { + public static class DifficultyTableReader extends TableReader { - private final String url; + private String url; public DifficultyTableReader(String url) { + super(url); this.url = url; } diff --git a/src/bms/player/beatoraja/external/BMSSearchAccessor.java b/src/bms/player/beatoraja/external/BMSSearchAccessor.java index 48c6391d9..a1885c3cb 100644 --- a/src/bms/player/beatoraja/external/BMSSearchAccessor.java +++ b/src/bms/player/beatoraja/external/BMSSearchAccessor.java @@ -12,8 +12,12 @@ import bms.player.beatoraja.*; import bms.player.beatoraja.TableData.TableFolder; -public class BMSSearchAccessor implements TableDataAccessor.TableReader { - +public class BMSSearchAccessor extends TableDataAccessor.TableReader { + + public BMSSearchAccessor() { + super("BMS Search"); + } + public TableData read() { TableData td = null; try (InputStream input = new URL("http://qstol.info/bmssearch/api/services/?method=bms.new").openStream()) { diff --git a/src/bms/player/beatoraja/select/Bar.java b/src/bms/player/beatoraja/select/Bar.java deleted file mode 100644 index ef6ebc9ee..000000000 --- a/src/bms/player/beatoraja/select/Bar.java +++ /dev/null @@ -1,650 +0,0 @@ -package bms.player.beatoraja.select; - -import bms.player.beatoraja.*; -import bms.player.beatoraja.CourseData.TrophyData; -import bms.player.beatoraja.song.FolderData; -import bms.player.beatoraja.song.*; - -import com.badlogic.gdx.graphics.Pixmap; -import java.io.File; -import java.nio.file.Paths; -import java.util.*; - -public abstract class Bar { - - private IRScoreData score; - - public abstract String getTitle(); - - public IRScoreData getScore() { - return score; - } - - public void setScore(IRScoreData score) { - this.score = score; - } - - public abstract int getLamp(); -} - -abstract class SelectableBar extends Bar { - - /** - * リプレイデータが存在するか - */ - private boolean[] existsReplay = new boolean[0]; - - public boolean existsReplayData() { - for (boolean b : existsReplay) { - if (b) { - return b; - } - } - return false; - } - - public boolean[] getExistsReplayData() { - return existsReplay; - } - - public void setExistsReplayData(boolean[] existsReplay) { - this.existsReplay = existsReplay; - } - -} - -class SongBar extends SelectableBar { - - private SongData song; - - private Pixmap banner; - - public SongBar(SongData song) { - this.song = song; - } - - public SongData getSongData() { - return song; - } - - public boolean existsSong() { - return song.getPath() != null; - } - - public Pixmap getBanner() { - return banner; - } - - public void setBanner(Pixmap banner) { - this.banner = banner; - } - - @Override - public String getTitle() { - return song.getFullTitle(); - } - - public int getLamp() { - if (getScore() != null) { - return getScore().getClear(); - } - return 0; - } -} - -class GradeBar extends SelectableBar { - - private SongData[] songs; - private String name; - - private CourseData course; - private IRScoreData mscore; - private IRScoreData rscore; - - public GradeBar(String name, SongData[] songs, CourseData course) { - this.songs = songs; - this.name = name; - this.course = course; - } - - public SongData[] getSongDatas() { - return songs; - } - - @Override - public String getTitle() { - return (course.isClassCourse() ? "段位認定 " : "") + name; - } - - public boolean existsAllSongs() { - for (SongData song : songs) { - if (song == null) { - return false; - } - } - return true; - } - - public IRScoreData getMirrorScore() { - return mscore; - } - - public void setMirrorScore(IRScoreData score) { - this.mscore = score; - } - - public IRScoreData getRandomScore() { - return rscore; - } - - public void setRandomScore(IRScoreData score) { - this.rscore = score; - } - - public CourseData.CourseDataConstraint[] getConstraint() { - if (course.getConstraint() != null) { - return course.getConstraint(); - } - return new CourseData.CourseDataConstraint[0]; - } - - public TrophyData[] getAllTrophy() { - return course.getTrophy(); - } - - public TrophyData getTrophy() { - for (TrophyData trophy : course.getTrophy()) { - if (qualified(this.getScore(), trophy)) { - return trophy; - } - if (qualified(mscore, trophy)) { - return trophy; - } - if (qualified(rscore, trophy)) { - return trophy; - } - } - return null; - } - - private boolean qualified(IRScoreData score, TrophyData trophy) { - return score != null && score.getNotes() != 0 - && trophy.getMissrate() >= score.getMinbp() * 100.0 / score.getNotes() - && trophy.getScorerate() <= score.getExscore() * 100.0 / (score.getNotes() * 2); - } - - public int getLamp() { - int result = 0; - if (getScore() != null && getScore().getClear() > result) { - result = getScore().getClear(); - } - if (getMirrorScore() != null && getMirrorScore().getClear() > result) { - result = getMirrorScore().getClear(); - } - if (getRandomScore() != null && getRandomScore().getClear() > result) { - result = getRandomScore().getClear(); - } - return result; - } -} - -abstract class DirectoryBar extends Bar { - - private int[] lamps = new int[11]; - private int[] ranks = new int[0]; - - public int[] getLamps() { - return lamps; - } - - public void setLamps(int[] lamps) { - this.lamps = lamps; - } - - public int[] getRanks() { - return ranks; - } - - public void setRanks(int[] ranks) { - this.ranks = ranks; - } - - public int getLamp() { - for (int i = 0; i < lamps.length; i++) { - if (lamps[i] > 0) { - return i; - } - } - return 0; - } - - public abstract Bar[] getChildren(); - -} - -class FolderBar extends DirectoryBar { - - private FolderData folder; - private String crc; - private MusicSelector selector; - - public FolderBar(MusicSelector selector, FolderData folder, String crc) { - this.selector = selector; - this.folder = folder; - this.crc = crc; - } - - public FolderData getFolderData() { - return folder; - } - - public String getCRC() { - return crc; - } - - @Override - public String getTitle() { - return folder.getTitle(); - } - - @Override - public Bar[] getChildren() { - List l = new ArrayList(); - final String rootpath = Paths.get(".").toAbsolutePath().toString(); - SongDatabaseAccessor songdb = selector.getSongDatabase(); - FolderData[] folders = songdb.getFolderDatas("parent", crc); - SongData[] songs = songdb.getSongDatas("parent", crc); - if (songs.length == 0) { - for (FolderData folder : folders) { - String path = folder.getPath(); - if (path.endsWith(String.valueOf(File.separatorChar))) { - path = path.substring(0, path.length() - 1); - } - - String ccrc = SongUtils.crc32(path, new String[0], rootpath); - FolderBar cfolder = new FolderBar(selector, folder, ccrc); - l.add(cfolder); - } - } else { - List sha = new ArrayList(); - for (SongData song : songs) { - if(!sha.contains(song.getSha256())) { - l.add(new SongBar(song)); - sha.add(song.getSha256()); - } - } - } - return l.toArray(new Bar[0]); - } - - public void updateFolderStatus() { - SongDatabaseAccessor songdb = selector.getSongDatabase(); - String path = folder.getPath(); - if (path.endsWith(String.valueOf(File.separatorChar))) { - path = path.substring(0, path.length() - 1); - } - final String ccrc = SongUtils.crc32(path, new String[0], new File(".").getAbsolutePath()); - int clear = 255; - int[] clears = new int[11]; - int[] ranks = new int[28]; - final SongData[] songdatas = songdb.getSongDatas("parent", ccrc); - final Map scores = selector.getScoreDataCache().readScoreDatas(songdatas, selector.getMainController().getPlayerResource().getPlayerConfig() - .getLnmode()); - for (SongData sd : songdatas) { - final IRScoreData score = scores.get(sd.getSha256()); - if (score != null) { - clears[score.getClear()]++; - if (score.getNotes() != 0) { - ranks[(score.getExscore() * 27 / (score.getNotes() * 2))]++; - } else { - ranks[0]++; - } - if (score.getClear() < clear) { - clear = score.getClear(); - } - } else { - ranks[0]++; - clears[0]++; - clear = 0; - } - } - setLamps(clears); - setRanks(ranks); - - } -} - -class ContainerBar extends DirectoryBar { - - private String title; - private Bar[] childbar; - - public ContainerBar(String title, Bar[] bar) { - this.title = title; - childbar = bar; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public Bar[] getChildren() { - return childbar; - } -} - -class SameFolderBar extends DirectoryBar { - - private MusicSelector selector; - private String crc; - private String title; - - public SameFolderBar(MusicSelector selector, String title, String crc) { - this.selector = selector; - this.crc = crc; - this.title = title; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public Bar[] getChildren() { - List l = new ArrayList(); - SongData[] songs = selector.getSongDatabase().getSongDatas("folder", crc); - List sha = new ArrayList(); - for (SongData song : songs) { - if(!sha.contains(song.getSha256())) { - l.add(new SongBar(song)); - sha.add(song.getSha256()); - } - } - return l.toArray(new Bar[0]); - } -} - -class TableBar extends DirectoryBar { - - private TableData td; - private HashBar[] levels; - private GradeBar[] grades; - private MusicSelector selector; - private TableDataAccessor.TableReader tr; - - public TableBar(MusicSelector selector, TableData td, TableDataAccessor.TableReader tr) { - this.selector = selector; - this.tr = tr; - setTableData(td); - } - - @Override - public String getTitle() { - return td.getName(); - } - - public TableDataAccessor.TableReader getReader() { - return tr; - } - - public void setTableData(TableData td) { - this.td = td; - - final long t = System.currentTimeMillis(); - List levels = new ArrayList(); - for (TableData.TableFolder lv : td.getFolder()) { - levels.add(new HashBar(selector, lv.getName(), lv.getSong())); - } - - this.levels = levels.toArray(new HashBar[levels.size()]); - List l = new ArrayList(); - - Set hashset = new HashSet(); - for (CourseData course : td.getCourse()) { - for (SongData hash : course.getSong()) { - hashset.add(hash.getSha256().length() > 0 ? hash.getSha256() : hash.getMd5()); - } - } - SongData[] songs = selector.getSongDatabase().getSongDatas(hashset.toArray(new String[hashset.size()])); - - for (CourseData course : td.getCourse()) { - List songlist = new ArrayList(); - for (SongData hash : course.getSong()) { - SongData song = null; - for(SongData sd :songs) { - if((hash.getMd5().length() > 0 && hash.getMd5().equals(sd.getMd5())) || (hash.getSha256().length() > 0 && hash.getSha256().equals(sd.getSha256()))) { - song = sd; - break; - } - } - songlist.add(song); - } - - l.add(new GradeBar(course.getName(), songlist.toArray(new SongData[0]), course)); - } - grades = l.toArray(new GradeBar[l.size()]); - } - - public HashBar[] getLevels() { - return levels; - } - - public GradeBar[] getGrades() { - return grades; - } - - @Override - public Bar[] getChildren() { - List l = new ArrayList(); - l.addAll(Arrays.asList(getLevels())); - l.addAll(Arrays.asList(getGrades())); - return l.toArray(new Bar[0]); - } -} - - - -/** - * ハッシュ集合を持ち、各ハッシュ値に該当する楽曲を含むフォルダバー - * - * @author exch - */ -class HashBar extends DirectoryBar { - private String title; - private SongData[] elements; - private MusicSelector selector; - private SongData[] songs; - - public HashBar(MusicSelector selector, String title, SongData[] elements) { - this.selector = selector; - this.title = title; - this.elements = elements; - } - - @Override - public String getTitle() { - return title; - } - - public SongData[] getElements() { - return elements; - } - - public void setElements(SongData[] elements) { - this.elements = elements; - songs = null; - } - - @Override - public Bar[] getChildren() { - List songbars = new ArrayList(); - String[] hashes = new String[elements.length]; - for(int i = 0;i < hashes.length;i++) { - hashes[i] = elements[i].getSha256().length() > 0 ? elements[i].getSha256() : elements[i].getMd5(); - } - if(songs == null) { - songs = selector.getSongDatabase().getSongDatas(hashes); - } - for(SongData element : elements) { - boolean exist = false; - for (SongData song : songs) { - if((element.getMd5().length() > 0 && element.getMd5().equals(song.getMd5())) - || (element.getSha256().length() > 0 && element.getSha256().equals(song.getSha256()))) { - songbars.add(new SongBar(song)); - exist = true; - break; - } - } - if(!exist && element.getTitle() != null) { - songbars.add(new SongBar(element)); - } - } - - return songbars.toArray(new Bar[0]); - } - - public void updateFolderStatus() { - int clear = 255; - int[] clears = new int[11]; - int[] ranks = new int[28]; - String[] hashes = new String[elements.length]; - for(int i = 0;i < hashes.length;i++) { - hashes[i] = elements[i].getSha256().length() > 0 ? elements[i].getSha256() : elements[i].getMd5(); - } - songs = selector.getSongDatabase().getSongDatas(hashes); - final Map scores = selector.getScoreDataCache() - .readScoreDatas(songs, selector.getMainController().getPlayerResource().getPlayerConfig().getLnmode()); - for (SongData song : songs) { - final IRScoreData score = scores.get(song.getSha256()); - if (score != null) { - clears[score.getClear()]++; - if (score.getNotes() != 0) { - ranks[(score.getExscore() * 27 / (score.getNotes() * 2))]++; - } else { - ranks[0]++; - } - if (score.getClear() < clear) { - clear = score.getClear(); - } - } else { - ranks[0]++; - clears[0]++; - clear = 0; - } - } - setLamps(clears); - setRanks(ranks); - } -} - -/** - * SQLで問い合わせた楽曲を表示するためのバー - * - * @author exch - */ -class CommandBar extends DirectoryBar { - - // TODO song.dbへの問い合わせの追加 - - private MainController main; - private MusicSelector selector; - private String title; - private String sql; - private int type; - - public CommandBar(MainController main, MusicSelector selector, String title, String sql) { - this(main, selector, title, sql, 0); - } - - public CommandBar(MainController main, MusicSelector selector, String title, String sql, int type) { - this.main = main; - this.selector = selector; - this.title = title; - this.sql = sql; - this.type = type; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public int getLamp() { - return 0; - } - - @Override - public Bar[] getChildren() { - if(type == 2) { - if(main.getInfoDatabase() == null) { - return new Bar[0]; - } - SongInformation[] infos = main.getInfoDatabase().getInformations(sql); - List l = new ArrayList(); - for (SongInformation info : infos) { - SongData[] song = selector.getSongDatabase().getSongDatas("sha256", info.getSha256()); - if(song.length > 0) { - l.add(new SongBar(song[0])); - } - } - return l.toArray(new Bar[l.size()]); - } else if(type == 1) { - SongData[] infos = main.getSongDatabase().getSongDatas(sql); - List l = new ArrayList(); - for (SongData info : infos) { - SongData[] song = selector.getSongDatabase().getSongDatas("sha256", info.getSha256()); - if(song.length > 0) { - l.add(new SongBar(song[0])); - } - } - return l.toArray(new Bar[l.size()]); - } else{ - List scores = main.getPlayDataAccessor().readScoreDatas(sql); - List l = new ArrayList(); - for (IRScoreData score : scores) { - SongData[] song = selector.getSongDatabase().getSongDatas("sha256", score.getSha256()); - if (song.length > 0 && (!song[0].hasUndefinedLongNote() || selector.getMainController().getPlayerResource().getPlayerConfig().getLnmode() == score.getMode())) { - l.add(new SongBar(song[0])); - } - } - return l.toArray(new Bar[l.size()]); - } - } - -} - -/** - * 検索用バー - * - * @author exch - */ -class SearchWordBar extends DirectoryBar { - - private String text; - private MusicSelector selector; - - public SearchWordBar(MusicSelector selector, String text) { - this.selector = selector; - this.text = text; - } - - @Override - public Bar[] getChildren() { - List songbars = new ArrayList(); - SongData[] songs = selector.getSongDatabase().getSongDatasByText(text, new File(".").getAbsolutePath()); - for (SongData song : songs) { - songbars.add(new SongBar(song)); - } - return songbars.toArray(new Bar[0]); - } - - @Override - public String getTitle() { - return "Search : '" + text + "'"; - } - -} diff --git a/src/bms/player/beatoraja/select/BarRenderer.java b/src/bms/player/beatoraja/select/BarRenderer.java index c7fe16107..efd3306c3 100644 --- a/src/bms/player/beatoraja/select/BarRenderer.java +++ b/src/bms/player/beatoraja/select/BarRenderer.java @@ -5,6 +5,7 @@ import java.util.logging.Logger; import bms.player.beatoraja.input.BMSPlayerInputProcessor; +import bms.player.beatoraja.select.bar.*; import bms.player.beatoraja.skin.*; import com.badlogic.gdx.graphics.g2d.SpriteBatch; diff --git a/src/bms/player/beatoraja/select/BarSorter.java b/src/bms/player/beatoraja/select/BarSorter.java index 3c54be8ee..71e7d6160 100644 --- a/src/bms/player/beatoraja/select/BarSorter.java +++ b/src/bms/player/beatoraja/select/BarSorter.java @@ -1,5 +1,8 @@ package bms.player.beatoraja.select; +import bms.player.beatoraja.select.bar.Bar; +import bms.player.beatoraja.select.bar.SongBar; + import java.util.Comparator; /** diff --git a/src/bms/player/beatoraja/select/MusicSelectInputProcessor.java b/src/bms/player/beatoraja/select/MusicSelectInputProcessor.java index ebb330089..28f3b7e2b 100644 --- a/src/bms/player/beatoraja/select/MusicSelectInputProcessor.java +++ b/src/bms/player/beatoraja/select/MusicSelectInputProcessor.java @@ -3,6 +3,7 @@ import bms.player.beatoraja.*; import bms.player.beatoraja.input.BMSPlayerInputProcessor; import bms.player.beatoraja.play.TargetProperty; +import bms.player.beatoraja.select.bar.*; import bms.player.beatoraja.song.SongData; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; diff --git a/src/bms/player/beatoraja/select/MusicSelector.java b/src/bms/player/beatoraja/select/MusicSelector.java index 1af8b9478..64148a4fd 100644 --- a/src/bms/player/beatoraja/select/MusicSelector.java +++ b/src/bms/player/beatoraja/select/MusicSelector.java @@ -12,13 +12,13 @@ import bms.model.Mode; import bms.player.beatoraja.*; import bms.player.beatoraja.input.BMSPlayerInputProcessor; +import bms.player.beatoraja.select.bar.*; import bms.player.beatoraja.skin.*; import bms.player.beatoraja.song.SongData; import bms.player.beatoraja.song.SongDatabaseAccessor; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.*; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.*; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; @@ -75,8 +75,6 @@ public class MusicSelector extends MainState { private SearchTextField search; - private Thread updateSong; - /** * 楽曲が選択されてからbmsを読み込むまでの時間(ms) */ @@ -116,8 +114,7 @@ public MusicSelector(MainController main, boolean songUpdated) { musicinput = new MusicSelectInputProcessor(this); if (!songUpdated && main.getPlayerResource().getConfig().isUpdatesong()) { - updateSong = new SongUpdateThread(null); - updateSong.start(); + main.updateSong(null); } } @@ -548,7 +545,7 @@ private String getCourseTitle(int index) { return ""; } - SongDatabaseAccessor getSongDatabase() { + public SongDatabaseAccessor getSongDatabase() { return songdb; } @@ -830,11 +827,10 @@ public BarRenderer getBarRender() { } public void updateSong(Bar selected) { - if (updateSong == null || !updateSong.isAlive()) { - updateSong = new MusicSelector.SongUpdateThread(selected); - updateSong.start(); - } else { - Logger.getGlobal().warning("楽曲更新中のため、更新要求は取り消されました"); + if(selected instanceof FolderBar) { + getMainController().updateSong(((FolderBar) selected).getFolderData().getPath()); + } else if(selected instanceof TableBar) { + getMainController().updateTable((TableBar) selected); } } @@ -855,34 +851,7 @@ public void selectSong(int mode) { } } - /** - * 楽曲データベース更新用スレッド - * - * @author exch - */ - class SongUpdateThread extends Thread { - - private final Bar selected; + public void updateTable(TableDataAccessor.TableReader reader) { - public SongUpdateThread(Bar bar) { - selected = bar; - } - - public void run() { - if (selected == null) { - getSongDatabase().updateSongDatas(null, false, getMainController().getInfoDatabase()); - } else if (selected instanceof FolderBar) { - FolderBar fb = (FolderBar) selected; - getSongDatabase().updateSongDatas(fb.getFolderData().getPath(), false, - getMainController().getInfoDatabase()); - } else if (selected instanceof TableBar) { - TableBar tb = (TableBar) selected; - TableData td = tb.getReader().read(); - if (td != null) { - new TableDataAccessor().write(td); - tb.setTableData(td); - } - } - } } } diff --git a/src/bms/player/beatoraja/select/SearchTextField.java b/src/bms/player/beatoraja/select/SearchTextField.java index ba65bb009..2e20adb8a 100644 --- a/src/bms/player/beatoraja/select/SearchTextField.java +++ b/src/bms/player/beatoraja/select/SearchTextField.java @@ -1,6 +1,7 @@ package bms.player.beatoraja.select; import bms.player.beatoraja.Resolution; +import bms.player.beatoraja.select.bar.SearchWordBar; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; diff --git a/src/bms/player/beatoraja/select/SkinDistributionGraph.java b/src/bms/player/beatoraja/select/SkinDistributionGraph.java index 02342dbd6..34f6a9fb5 100644 --- a/src/bms/player/beatoraja/select/SkinDistributionGraph.java +++ b/src/bms/player/beatoraja/select/SkinDistributionGraph.java @@ -1,20 +1,22 @@ package bms.player.beatoraja.select; import bms.player.beatoraja.MainState; +import bms.player.beatoraja.select.bar.DirectoryBar; import bms.player.beatoraja.skin.*; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Rectangle; /** - * Created by exch on 2016/11/03. + * フォルダのランプ分布、ランク分布に使用される棒グラフ */ public class SkinDistributionGraph extends SkinObject { + // TODO 分布計算はフォルダ選択時にのみ行う + private SkinSource[] lampimage; private int type; @@ -53,11 +55,6 @@ public SkinDistributionGraph(int type) { } } - public SkinDistributionGraph(int tupe, SkinSource[] lampimage) { - this.type = type; - this.lampimage = lampimage; - } - @Override public void draw(SpriteBatch sprite, long time, MainState state) { final Rectangle r = getDestination(time, state); diff --git a/src/bms/player/beatoraja/select/bar/Bar.java b/src/bms/player/beatoraja/select/bar/Bar.java new file mode 100644 index 000000000..85234d4b4 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/Bar.java @@ -0,0 +1,33 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.IRScoreData; +import bms.player.beatoraja.MainController; +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.*; + +import java.io.File; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by exch on 2017/09/03. + */ +public abstract class Bar { + + private IRScoreData score; + + public abstract String getTitle(); + + public IRScoreData getScore() { + return score; + } + + public void setScore(IRScoreData score) { + this.score = score; + } + + public abstract int getLamp(); +} + diff --git a/src/bms/player/beatoraja/select/bar/CommandBar.java b/src/bms/player/beatoraja/select/bar/CommandBar.java new file mode 100644 index 000000000..2e1d9c674 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/CommandBar.java @@ -0,0 +1,87 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.IRScoreData; +import bms.player.beatoraja.MainController; +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.SongData; +import bms.player.beatoraja.song.SongInformation; + +import java.util.ArrayList; +import java.util.List; + +/** + * SQLで問い合わせた楽曲を表示するためのバー + * + * @author exch + */ +public class CommandBar extends DirectoryBar { + + // TODO song.dbへの問い合わせの追加 + + private MainController main; + private MusicSelector selector; + private String title; + private String sql; + private int type; + + public CommandBar(MainController main, MusicSelector selector, String title, String sql) { + this(main, selector, title, sql, 0); + } + + public CommandBar(MainController main, MusicSelector selector, String title, String sql, int type) { + this.main = main; + this.selector = selector; + this.title = title; + this.sql = sql; + this.type = type; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public int getLamp() { + return 0; + } + + @Override + public Bar[] getChildren() { + if(type == 2) { + if(main.getInfoDatabase() == null) { + return new Bar[0]; + } + SongInformation[] infos = main.getInfoDatabase().getInformations(sql); + List l = new ArrayList(); + for (SongInformation info : infos) { + SongData[] song = selector.getSongDatabase().getSongDatas("sha256", info.getSha256()); + if(song.length > 0) { + l.add(new SongBar(song[0])); + } + } + return l.toArray(new Bar[l.size()]); + } else if(type == 1) { + SongData[] infos = main.getSongDatabase().getSongDatas(sql); + List l = new ArrayList(); + for (SongData info : infos) { + SongData[] song = selector.getSongDatabase().getSongDatas("sha256", info.getSha256()); + if(song.length > 0) { + l.add(new SongBar(song[0])); + } + } + return l.toArray(new Bar[l.size()]); + } else{ + List scores = main.getPlayDataAccessor().readScoreDatas(sql); + List l = new ArrayList(); + for (IRScoreData score : scores) { + SongData[] song = selector.getSongDatabase().getSongDatas("sha256", score.getSha256()); + if (song.length > 0 && (!song[0].hasUndefinedLongNote() || selector.getMainController().getPlayerResource().getPlayerConfig().getLnmode() == score.getMode())) { + l.add(new SongBar(song[0])); + } + } + return l.toArray(new Bar[l.size()]); + } + } + +} diff --git a/src/bms/player/beatoraja/select/bar/ContainerBar.java b/src/bms/player/beatoraja/select/bar/ContainerBar.java new file mode 100644 index 000000000..9605ac03e --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/ContainerBar.java @@ -0,0 +1,25 @@ +package bms.player.beatoraja.select.bar; + +/** + * Created by exch on 2017/09/03. + */ +public class ContainerBar extends DirectoryBar { + + private String title; + private Bar[] childbar; + + public ContainerBar(String title, Bar[] bar) { + this.title = title; + childbar = bar; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public Bar[] getChildren() { + return childbar; + } +} diff --git a/src/bms/player/beatoraja/select/bar/DirectoryBar.java b/src/bms/player/beatoraja/select/bar/DirectoryBar.java new file mode 100644 index 000000000..f77e2d2e8 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/DirectoryBar.java @@ -0,0 +1,38 @@ +package bms.player.beatoraja.select.bar; + +/** + * Created by exch on 2017/09/02. + */ +public abstract class DirectoryBar extends Bar { + + private int[] lamps = new int[11]; + private int[] ranks = new int[0]; + + public int[] getLamps() { + return lamps; + } + + public void setLamps(int[] lamps) { + this.lamps = lamps; + } + + public int[] getRanks() { + return ranks; + } + + public void setRanks(int[] ranks) { + this.ranks = ranks; + } + + public int getLamp() { + for (int i = 0; i < lamps.length; i++) { + if (lamps[i] > 0) { + return i; + } + } + return 0; + } + + public abstract Bar[] getChildren(); + +} diff --git a/src/bms/player/beatoraja/select/bar/FolderBar.java b/src/bms/player/beatoraja/select/bar/FolderBar.java new file mode 100644 index 000000000..21611e5f5 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/FolderBar.java @@ -0,0 +1,109 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.IRScoreData; +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.FolderData; +import bms.player.beatoraja.song.SongData; +import bms.player.beatoraja.song.SongDatabaseAccessor; +import bms.player.beatoraja.song.SongUtils; + +import java.io.File; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by exch on 2017/09/03. + */ +public class FolderBar extends DirectoryBar { + + private FolderData folder; + private String crc; + private MusicSelector selector; + + public FolderBar(MusicSelector selector, FolderData folder, String crc) { + this.selector = selector; + this.folder = folder; + this.crc = crc; + } + + public FolderData getFolderData() { + return folder; + } + + public String getCRC() { + return crc; + } + + @Override + public String getTitle() { + return folder.getTitle(); + } + + @Override + public Bar[] getChildren() { + List l = new ArrayList(); + final String rootpath = Paths.get(".").toAbsolutePath().toString(); + SongDatabaseAccessor songdb = selector.getSongDatabase(); + FolderData[] folders = songdb.getFolderDatas("parent", crc); + SongData[] songs = songdb.getSongDatas("parent", crc); + if (songs.length == 0) { + for (FolderData folder : folders) { + String path = folder.getPath(); + if (path.endsWith(String.valueOf(File.separatorChar))) { + path = path.substring(0, path.length() - 1); + } + + String ccrc = SongUtils.crc32(path, new String[0], rootpath); + FolderBar cfolder = new FolderBar(selector, folder, ccrc); + l.add(cfolder); + } + } else { + List sha = new ArrayList(); + for (SongData song : songs) { + if(!sha.contains(song.getSha256())) { + l.add(new SongBar(song)); + sha.add(song.getSha256()); + } + } + } + return l.toArray(new Bar[0]); + } + + public void updateFolderStatus() { + SongDatabaseAccessor songdb = selector.getSongDatabase(); + String path = folder.getPath(); + if (path.endsWith(String.valueOf(File.separatorChar))) { + path = path.substring(0, path.length() - 1); + } + final String ccrc = SongUtils.crc32(path, new String[0], new File(".").getAbsolutePath()); + int clear = 255; + int[] clears = new int[11]; + int[] ranks = new int[28]; + final SongData[] songdatas = songdb.getSongDatas("parent", ccrc); + final Map scores = selector.getScoreDataCache().readScoreDatas(songdatas, selector.getMainController().getPlayerResource().getPlayerConfig() + .getLnmode()); + for (SongData sd : songdatas) { + final IRScoreData score = scores.get(sd.getSha256()); + if (score != null) { + clears[score.getClear()]++; + if (score.getNotes() != 0) { + ranks[(score.getExscore() * 27 / (score.getNotes() * 2))]++; + } else { + ranks[0]++; + } + if (score.getClear() < clear) { + clear = score.getClear(); + } + } else { + ranks[0]++; + clears[0]++; + clear = 0; + } + } + setLamps(clears); + setRanks(ranks); + + } +} diff --git a/src/bms/player/beatoraja/select/bar/GradeBar.java b/src/bms/player/beatoraja/select/bar/GradeBar.java new file mode 100644 index 000000000..01b76388c --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/GradeBar.java @@ -0,0 +1,104 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.CourseData; +import bms.player.beatoraja.IRScoreData; +import bms.player.beatoraja.song.SongData; + +/** + * Created by exch on 2017/09/02. + */ +public class GradeBar extends SelectableBar { + + private SongData[] songs; + private String name; + + private CourseData course; + private IRScoreData mscore; + private IRScoreData rscore; + + public GradeBar(String name, SongData[] songs, CourseData course) { + this.songs = songs; + this.name = name; + this.course = course; + } + + public SongData[] getSongDatas() { + return songs; + } + + @Override + public String getTitle() { + return (course.isClassCourse() ? "段位認定 " : "") + name; + } + + public boolean existsAllSongs() { + for (SongData song : songs) { + if (song == null) { + return false; + } + } + return true; + } + + public IRScoreData getMirrorScore() { + return mscore; + } + + public void setMirrorScore(IRScoreData score) { + this.mscore = score; + } + + public IRScoreData getRandomScore() { + return rscore; + } + + public void setRandomScore(IRScoreData score) { + this.rscore = score; + } + + public CourseData.CourseDataConstraint[] getConstraint() { + if (course.getConstraint() != null) { + return course.getConstraint(); + } + return new CourseData.CourseDataConstraint[0]; + } + + public CourseData.TrophyData[] getAllTrophy() { + return course.getTrophy(); + } + + public CourseData.TrophyData getTrophy() { + for (CourseData.TrophyData trophy : course.getTrophy()) { + if (qualified(this.getScore(), trophy)) { + return trophy; + } + if (qualified(mscore, trophy)) { + return trophy; + } + if (qualified(rscore, trophy)) { + return trophy; + } + } + return null; + } + + private boolean qualified(IRScoreData score, CourseData.TrophyData trophy) { + return score != null && score.getNotes() != 0 + && trophy.getMissrate() >= score.getMinbp() * 100.0 / score.getNotes() + && trophy.getScorerate() <= score.getExscore() * 100.0 / (score.getNotes() * 2); + } + + public int getLamp() { + int result = 0; + if (getScore() != null && getScore().getClear() > result) { + result = getScore().getClear(); + } + if (getMirrorScore() != null && getMirrorScore().getClear() > result) { + result = getMirrorScore().getClear(); + } + if (getRandomScore() != null && getRandomScore().getClear() > result) { + result = getRandomScore().getClear(); + } + return result; + } +} diff --git a/src/bms/player/beatoraja/select/bar/HashBar.java b/src/bms/player/beatoraja/select/bar/HashBar.java new file mode 100644 index 000000000..e869a6e07 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/HashBar.java @@ -0,0 +1,100 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.IRScoreData; +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.SongData; + +import java.util.*; + +/** + * ハッシュ集合を持ち、各ハッシュ値に該当する楽曲を含むフォルダバー + * + * @author exch + */ +public class HashBar extends DirectoryBar { + private String title; + private SongData[] elements; + private MusicSelector selector; + private SongData[] songs; + + public HashBar(MusicSelector selector, String title, SongData[] elements) { + this.selector = selector; + this.title = title; + this.elements = elements; + } + + @Override + public String getTitle() { + return title; + } + + public SongData[] getElements() { + return elements; + } + + public void setElements(SongData[] elements) { + this.elements = elements; + songs = null; + } + + @Override + public Bar[] getChildren() { + List songbars = new ArrayList(); + String[] hashes = new String[elements.length]; + for(int i = 0;i < hashes.length;i++) { + hashes[i] = elements[i].getSha256().length() > 0 ? elements[i].getSha256() : elements[i].getMd5(); + } + if(songs == null) { + songs = selector.getSongDatabase().getSongDatas(hashes); + } + for(SongData element : elements) { + boolean exist = false; + for (SongData song : songs) { + if((element.getMd5().length() > 0 && element.getMd5().equals(song.getMd5())) + || (element.getSha256().length() > 0 && element.getSha256().equals(song.getSha256()))) { + songbars.add(new SongBar(song)); + exist = true; + break; + } + } + if(!exist && element.getTitle() != null) { + songbars.add(new SongBar(element)); + } + } + + return songbars.toArray(new Bar[0]); + } + + public void updateFolderStatus() { + int clear = 255; + int[] clears = new int[11]; + int[] ranks = new int[28]; + String[] hashes = new String[elements.length]; + for(int i = 0;i < hashes.length;i++) { + hashes[i] = elements[i].getSha256().length() > 0 ? elements[i].getSha256() : elements[i].getMd5(); + } + songs = selector.getSongDatabase().getSongDatas(hashes); + final Map scores = selector.getScoreDataCache() + .readScoreDatas(songs, selector.getMainController().getPlayerResource().getPlayerConfig().getLnmode()); + for (SongData song : songs) { + final IRScoreData score = scores.get(song.getSha256()); + if (score != null) { + clears[score.getClear()]++; + if (score.getNotes() != 0) { + ranks[(score.getExscore() * 27 / (score.getNotes() * 2))]++; + } else { + ranks[0]++; + } + if (score.getClear() < clear) { + clear = score.getClear(); + } + } else { + ranks[0]++; + clears[0]++; + clear = 0; + } + } + setLamps(clears); + setRanks(ranks); + } +} diff --git a/src/bms/player/beatoraja/select/bar/SameFolderBar.java b/src/bms/player/beatoraja/select/bar/SameFolderBar.java new file mode 100644 index 000000000..19e00412b --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/SameFolderBar.java @@ -0,0 +1,42 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.SongData; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by exch on 2017/09/03. + */ +public class SameFolderBar extends DirectoryBar { + + private MusicSelector selector; + private String crc; + private String title; + + public SameFolderBar(MusicSelector selector, String title, String crc) { + this.selector = selector; + this.crc = crc; + this.title = title; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public Bar[] getChildren() { + List l = new ArrayList(); + SongData[] songs = selector.getSongDatabase().getSongDatas("folder", crc); + List sha = new ArrayList(); + for (SongData song : songs) { + if(!sha.contains(song.getSha256())) { + l.add(new SongBar(song)); + sha.add(song.getSha256()); + } + } + return l.toArray(new Bar[0]); + } +} diff --git a/src/bms/player/beatoraja/select/bar/SearchWordBar.java b/src/bms/player/beatoraja/select/bar/SearchWordBar.java new file mode 100644 index 000000000..d61834d8f --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/SearchWordBar.java @@ -0,0 +1,40 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.select.MusicSelector; +import bms.player.beatoraja.song.SongData; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * 検索用バー + * + * @author exch + */ +public class SearchWordBar extends DirectoryBar { + + private String text; + private MusicSelector selector; + + public SearchWordBar(MusicSelector selector, String text) { + this.selector = selector; + this.text = text; + } + + @Override + public Bar[] getChildren() { + List songbars = new ArrayList(); + SongData[] songs = selector.getSongDatabase().getSongDatasByText(text, new File(".").getAbsolutePath()); + for (SongData song : songs) { + songbars.add(new SongBar(song)); + } + return songbars.toArray(new Bar[0]); + } + + @Override + public String getTitle() { + return "Search : '" + text + "'"; + } + +} diff --git a/src/bms/player/beatoraja/select/bar/SelectableBar.java b/src/bms/player/beatoraja/select/bar/SelectableBar.java new file mode 100644 index 000000000..6a448bd72 --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/SelectableBar.java @@ -0,0 +1,30 @@ +package bms.player.beatoraja.select.bar; + +/** + * Created by exch on 2017/09/02. + */ +public abstract class SelectableBar extends Bar { + + /** + * リプレイデータが存在するか + */ + private boolean[] existsReplay = new boolean[0]; + + public boolean existsReplayData() { + for (boolean b : existsReplay) { + if (b) { + return b; + } + } + return false; + } + + public boolean[] getExistsReplayData() { + return existsReplay; + } + + public void setExistsReplayData(boolean[] existsReplay) { + this.existsReplay = existsReplay; + } + +} diff --git a/src/bms/player/beatoraja/select/bar/SongBar.java b/src/bms/player/beatoraja/select/bar/SongBar.java new file mode 100644 index 000000000..b1608893e --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/SongBar.java @@ -0,0 +1,46 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.song.SongData; +import com.badlogic.gdx.graphics.Pixmap; + +/** + * Created by exch on 2017/09/02. + */ +public class SongBar extends SelectableBar { + + private SongData song; + + private Pixmap banner; + + public SongBar(SongData song) { + this.song = song; + } + + public SongData getSongData() { + return song; + } + + public boolean existsSong() { + return song.getPath() != null; + } + + public Pixmap getBanner() { + return banner; + } + + public void setBanner(Pixmap banner) { + this.banner = banner; + } + + @Override + public String getTitle() { + return song.getFullTitle(); + } + + public int getLamp() { + if (getScore() != null) { + return getScore().getClear(); + } + return 0; + } +} diff --git a/src/bms/player/beatoraja/select/bar/TableBar.java b/src/bms/player/beatoraja/select/bar/TableBar.java new file mode 100644 index 000000000..b2b7417dd --- /dev/null +++ b/src/bms/player/beatoraja/select/bar/TableBar.java @@ -0,0 +1,90 @@ +package bms.player.beatoraja.select.bar; + +import bms.player.beatoraja.CourseData; +import bms.player.beatoraja.TableData; +import bms.player.beatoraja.TableDataAccessor; +import bms.player.beatoraja.select.*; +import bms.player.beatoraja.song.SongData; + +import java.util.*; + +/** + * Created by exch on 2017/09/02. + */ +public class TableBar extends DirectoryBar { + + private TableData td; + private HashBar[] levels; + private GradeBar[] grades; + private MusicSelector selector; + private TableDataAccessor.TableReader tr; + + public TableBar(MusicSelector selector, TableData td, TableDataAccessor.TableReader tr) { + this.selector = selector; + this.tr = tr; + setTableData(td); + } + + @Override + public String getTitle() { + return td.getName(); + } + + public TableDataAccessor.TableReader getReader() { + return tr; + } + + public void setTableData(TableData td) { + this.td = td; + + final long t = System.currentTimeMillis(); + List levels = new ArrayList(); + for (TableData.TableFolder lv : td.getFolder()) { + levels.add(new HashBar(selector, lv.getName(), lv.getSong())); + } + + this.levels = levels.toArray(new HashBar[levels.size()]); + List l = new ArrayList(); + + Set hashset = new HashSet(); + for (CourseData course : td.getCourse()) { + for (SongData hash : course.getSong()) { + hashset.add(hash.getSha256().length() > 0 ? hash.getSha256() : hash.getMd5()); + } + } + SongData[] songs = selector.getSongDatabase().getSongDatas(hashset.toArray(new String[hashset.size()])); + + for (CourseData course : td.getCourse()) { + List songlist = new ArrayList(); + for (SongData hash : course.getSong()) { + SongData song = null; + for(SongData sd :songs) { + if((hash.getMd5().length() > 0 && hash.getMd5().equals(sd.getMd5())) || (hash.getSha256().length() > 0 && hash.getSha256().equals(sd.getSha256()))) { + song = sd; + break; + } + } + songlist.add(song); + } + + l.add(new GradeBar(course.getName(), songlist.toArray(new SongData[0]), course)); + } + grades = l.toArray(new GradeBar[l.size()]); + } + + public HashBar[] getLevels() { + return levels; + } + + public GradeBar[] getGrades() { + return grades; + } + + @Override + public Bar[] getChildren() { + List l = new ArrayList(); + l.addAll(Arrays.asList(getLevels())); + l.addAll(Arrays.asList(getGrades())); + return l.toArray(new Bar[0]); + } +}