diff --git a/core/src/bms/player/beatoraja/MainController.java b/core/src/bms/player/beatoraja/MainController.java index e836e0b69..9d29a4dcc 100644 --- a/core/src/bms/player/beatoraja/MainController.java +++ b/core/src/bms/player/beatoraja/MainController.java @@ -136,6 +136,8 @@ public class MainController { public List irSendStatus = new ArrayList(); + private boolean suspendPlaySceneTransition = false; + public MainController(Path f, Config config, PlayerConfig player, BMSPlayerMode auto, boolean songUpdated) { this.auto = auto; this.config = config; @@ -290,6 +292,10 @@ public void changeState(MainStateType state) { newState = decide; break; case PLAY: + if (suspendPlaySceneTransition) { + messageRenderer.addMessage("Cannot transition to play scene, please wait!", Color.CYAN, 1); + return ; + } if (bmsplayer != null) { bmsplayer.dispose(); } @@ -850,6 +856,14 @@ public void setHttpDownloadProcessor(HttpDownloadProcessor httpDownloadProcessor this.httpDownloadProcessor = httpDownloadProcessor; } + public boolean isSuspendPlaySceneTransition() { + return suspendPlaySceneTransition; + } + + public void setSuspendPlaySceneTransition(boolean suspendPlaySceneTransition) { + this.suspendPlaySceneTransition = suspendPlaySceneTransition; + } + public void switchTimer(int id, boolean on) { timer.switchTimer(id, on); } diff --git a/core/src/bms/tool/mdprocessor/HttpDownloadProcessor.java b/core/src/bms/tool/mdprocessor/HttpDownloadProcessor.java index 718e6b17f..4a752db6b 100644 --- a/core/src/bms/tool/mdprocessor/HttpDownloadProcessor.java +++ b/core/src/bms/tool/mdprocessor/HttpDownloadProcessor.java @@ -1,6 +1,7 @@ package bms.tool.mdprocessor; import bms.player.beatoraja.MainController; +import bms.player.beatoraja.play.BMSPlayer; import com.badlogic.gdx.graphics.Color; import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry; import org.apache.commons.compress.archivers.sevenz.SevenZFile; @@ -10,10 +11,7 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; @@ -59,9 +57,56 @@ public class HttpDownloadProcessor { private final MainController main; private final HttpDownloadSource httpDownloadSource; + // To delay the extract & update songdata.db steps if we're playing bms + private final Object waitingExtractLock = new Object(); + private final Queue waitingExtractArchives = new ConcurrentLinkedQueue<>(); + public HttpDownloadProcessor(MainController main, HttpDownloadSource httpDownloadSource) { this.main = main; this.httpDownloadSource = httpDownloadSource; + (new Thread(() -> { + while (true) { + try { + synchronized (waitingExtractLock) { + if (main.getCurrentState() instanceof BMSPlayer) { + // Do nothing + } else if (!waitingExtractArchives.isEmpty()) { + main.setSuspendPlaySceneTransition(true); + + List succeededPaths = new ArrayList<>(); + for (Path path : waitingExtractArchives) { + try { + extractCompressedFile(path.toFile(), null); + succeededPaths.add(path); + } catch (Exception e) { + e.printStackTrace(); + pushMessage(String.format("Failed extracting file: %s due to %s", path.getFileName(), e.getMessage())); + } + } + if (!succeededPaths.isEmpty()) { + pushMessage(String.format("Successfully extracted %d archives. Trying to rebuild download directory", succeededPaths.size())); + main.updateSong(DOWNLOAD_DIRECTORY); + // If everything works well, trying to delete the downloaded archive + for (Path path : succeededPaths) { + try { + Files.delete(path); + } catch (IOException e) { + e.printStackTrace(); + pushMessage(String.format("Failed deleting archive file at %s automatically", path)); + } + } + } + + main.setSuspendPlaySceneTransition(false); + waitingExtractArchives.clear(); + } + } + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + })).start(); } public static HttpDownloadSourceMeta getDefaultDownloadSource() { @@ -171,28 +216,9 @@ public void submitMD5Task(String md5, String taskName) { downloadTask.setDownloadTaskStatus(DownloadTask.DownloadTaskStatus.Error); return; } - // 2) Extract the compressed archive & update download directory automatically - boolean successfullyExtracted = false; - try { - extractCompressedFile(result.toFile(), null); - successfullyExtracted = true; - } catch (Exception e) { - e.printStackTrace(); - pushMessage(String.format("Failed extracting file: %s due to %s", result.getFileName(), e.getMessage())); - } - if (successfullyExtracted) { - // TODO: Directory update is protected, this might cause some uncovered situation. Personally speaking, - // I don't think this has any issue since user can always turn back to root directory - // and update the download directory manually - pushMessage("Successfully downloaded & extracted. Trying to rebuild download directory"); - main.updateSong(DOWNLOAD_DIRECTORY); - // If everything works well, trying to delete the downloaded archive - try { - Files.delete(result); - } catch (IOException e) { - e.printStackTrace(); - pushMessage("Failed deleting archive file automatically"); - } + // 2) Push the result to a queue as a buffer + synchronized (waitingExtractLock) { + waitingExtractArchives.add(result); } }); }