Load world asynchronously

This commit is contained in:
huanghongxun 2019-01-22 14:59:01 +08:00
parent 2736b88a10
commit 3d04447c2f
2 changed files with 35 additions and 31 deletions

View File

@ -50,8 +50,13 @@ public class WorldListPage extends ListPage<WorldListItem> {
public void loadVersion(Profile profile, String id) { public void loadVersion(Profile profile, String id) {
this.savesDir = profile.getRepository().getRunDirectory(id).toPath().resolve("saves"); this.savesDir = profile.getRepository().getRunDirectory(id).toPath().resolve("saves");
itemsProperty().setAll(World.getWorlds(savesDir).stream() setLoading(true);
.map(WorldListItem::new).collect(Collectors.toList())); Task.ofResult(() -> World.getWorlds(savesDir).parallel().collect(Collectors.toList()))
.finalizedResult(Schedulers.javafx(), (result, isDependentsSucceeded) -> {
setLoading(false);
if (isDependentsSucceeded)
itemsProperty().setAll(result.stream().map(WorldListItem::new).collect(Collectors.toList()));
}).start();
} }
@Override @Override
@ -65,28 +70,26 @@ public class WorldListPage extends ListPage<WorldListItem> {
installWorld(res.get(0)); installWorld(res.get(0));
} }
public void installWorld(File zipFile) { private void installWorld(File zipFile) {
try { // Only accept one world file because user is required to confirm the new world name
// Only accept one world file because user is required to confirm the new world name // Or too many input dialogs are popped.
// Or too many input dialogs are popped. Task.ofResult(() -> new World(zipFile.toPath()))
World world = new World(zipFile.toPath()); .finalizedResult(Schedulers.javafx(), world -> {
Controllers.inputDialog(i18n("world.name.enter"), (name, resolve, reject) -> {
Controllers.inputDialog(i18n("world.name.enter"), (name, resolve, reject) -> { Task.of(() -> world.install(savesDir, name))
Task.of(() -> world.install(savesDir, name)) .finalized(Schedulers.javafx(), var -> {
.finalized(Schedulers.javafx(), var -> { itemsProperty().add(new WorldListItem(new World(savesDir.resolve(name))));
itemsProperty().add(new WorldListItem(new World(savesDir.resolve(name)))); resolve.run();
resolve.run(); }, e -> {
}, e -> { if (e instanceof FileAlreadyExistsException)
if (e instanceof FileAlreadyExistsException) reject.accept(i18n("world.import.failed", i18n("world.import.already_exists")));
reject.accept(i18n("world.import.failed", i18n("world.import.already_exists"))); else
else reject.accept(i18n("world.import.failed", e.getClass().getName() + ": " + e.getLocalizedMessage()));
reject.accept(i18n("world.import.failed", e.getClass().getName() + ": " + e.getLocalizedMessage())); }).start();
}).start(); }).setInitialText(world.getWorldName());
}).setInitialText(world.getWorldName()); }, e -> {
Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e);
} catch (IOException | IllegalArgumentException e) { Controllers.dialog(i18n("world.import.invalid"));
Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e); }).start();
Controllers.dialog(i18n("world.import.invalid"));
}
} }
} }

View File

@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
@ -202,20 +203,20 @@ public class World {
} }
} }
public static List<World> getWorlds(Path savesDir) { public static Stream<World> getWorlds(Path savesDir) {
List<World> worlds = new ArrayList<>();
try { try {
if (Files.exists(savesDir)) if (Files.exists(savesDir))
for (Path world : Files.newDirectoryStream(savesDir)) { return Files.list(savesDir).flatMap(world -> {
try { try {
worlds.add(new World(world)); return Stream.of(new World(world));
} catch (IOException | IllegalArgumentException e) { } catch (IOException | IllegalArgumentException e) {
Logging.LOG.log(Level.WARNING, "Failed to read world " + world, e); Logging.LOG.log(Level.WARNING, "Failed to read world " + world, e);
return Stream.empty();
} }
} });
} catch (IOException e) { } catch (IOException e) {
Logging.LOG.log(Level.WARNING, "Failed to read saves", e); Logging.LOG.log(Level.WARNING, "Failed to read saves", e);
} }
return worlds; return Stream.empty();
} }
} }