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

View File

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