From b5f1e566b2bd6ee5baf72f1b696a3358dd4fdc22 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 6 Sep 2019 21:21:30 -0400 Subject: [PATCH 1/2] New Android file chooser implementation --- .../io/anuke/mindustry/AndroidLauncher.java | 48 +++++++++++++------ core/assets/bundles/bundle.properties | 1 + .../src/io/anuke/mindustry/content/Items.java | 2 +- core/src/io/anuke/mindustry/core/Control.java | 31 ------------ .../src/io/anuke/mindustry/core/Platform.java | 29 ++++++----- .../mindustry/editor/MapEditorDialog.java | 20 ++++---- .../io/anuke/mindustry/game/GlobalData.java | 9 ++-- core/src/io/anuke/mindustry/game/Saves.java | 3 -- core/src/io/anuke/mindustry/maps/Maps.java | 30 +----------- .../mindustry/ui/dialogs/LoadDialog.java | 11 ++--- .../mindustry/ui/dialogs/MapsDialog.java | 12 ++--- .../ui/dialogs/SettingsMenuDialog.java | 28 ++++------- .../mindustry/desktop/DesktopPlatform.java | 5 -- 13 files changed, 87 insertions(+), 142 deletions(-) diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index f8f7552ca1..d7dd912ca8 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -1,10 +1,12 @@ package io.anuke.mindustry; import android.*; +import android.app.*; import android.content.*; import android.content.pm.*; import android.net.*; import android.os.*; +import android.os.Build.*; import android.provider.Settings.*; import android.telephony.*; import io.anuke.arc.*; @@ -93,21 +95,39 @@ public class AndroidLauncher extends AndroidApplication{ } @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ - chooser = new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons); - if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && - checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ - chooser.show(); - chooser = null; + public void showFileChooser(boolean open, String extension, Consumer cons){ + if(VERSION.SDK_INT >= 19){ + + Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + addResultListener(i -> startActivityForResult(intent, i), (code, in) -> { + if(code == Activity.RESULT_OK && in != null && in.getData() != null){ + Uri uri = in.getData(); + + Core.app.post(() -> Core.app.post(() -> cons.accept(new FileHandle(uri.getPath()){ + @Override + public InputStream read(){ + try{ + return getContentResolver().openInputStream(uri); + }catch(IOException e){ + throw new ArcRuntimeException(e); + } + } + + @Override + public OutputStream write(boolean append){ + try{ + return getContentResolver().openOutputStream(uri); + }catch(IOException e){ + throw new ArcRuntimeException(e); + } + } + }))); + } + }); }else{ - ArrayList perms = new ArrayList<>(); - if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ - perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ - perms.add(Manifest.permission.READ_EXTERNAL_STORAGE); - } - requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE); + super.showFileChooser(open, extension, cons); } } diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index da5d2ca45b..64da450d11 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -235,6 +235,7 @@ editor.errorload = Error loading file:\n[accent]{0} editor.errorsave = Error saving file:\n[accent]{0} editor.errorimage = That's an image, not a map. Don't go around changing extensions expecting it to work.\n\nIf you want to import a legacy map, use the 'import legacy map' button in the editor. editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. +editor.errornot = This is not a map file. editor.errorheader = This map file is either not valid or corrupt. editor.errorname = Map has no name defined. Are you trying to load a save file? editor.update = Update diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index b8c567bfcc..f367c9656c 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -39,7 +39,7 @@ public class Items implements ContentList{ }}; coal = new Item("coal", Color.valueOf("272727")){{ - explosiveness = 0.4f; + explosiveness = 0.2f; flammability = 1f; hardness = 2; }}; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 1ffb6badde..3a80a5883d 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.core; import io.anuke.arc.*; import io.anuke.arc.assets.*; -import io.anuke.arc.files.*; import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.input.*; @@ -174,35 +173,6 @@ public class Control implements ApplicationListener, Loadable{ saves.load(); } - //checks for existing 3.5 app data, android only - public void checkClassicData(){ - try{ - if(files.local("mindustry-maps").exists() || files.local("mindustry-saves").exists()){ - settings.getBoolOnce("classic-backup-check", () -> { - app.post(() -> app.post(() -> ui.showConfirm("$classic.export", "$classic.export.text", () -> { - try{ - platform.requestExternalPerms(() -> { - FileHandle external = files.external("MindustryClassic"); - if(files.local("mindustry-maps").exists()){ - files.local("mindustry-maps").copyTo(external); - } - - if(files.local("mindustry-saves").exists()){ - files.local("mindustry-saves").copyTo(external); - } - }); - }catch(Exception e){ - e.printStackTrace(); - ui.showError(Strings.parseException(e, true)); - } - }))); - }); - } - }catch(Throwable t){ - t.printStackTrace(); - } - } - void createPlayer(){ player = new Player(); player.name = Core.settings.getString("name"); @@ -379,7 +349,6 @@ public class Control implements ApplicationListener, Loadable{ if(android){ Sounds.empty.loop(0f, 1f, 0f); - checkClassicData(); } } diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 085242a3f6..7e008136a5 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -1,13 +1,13 @@ package io.anuke.mindustry.core; -import io.anuke.arc.Core; -import io.anuke.arc.Input.TextInput; -import io.anuke.arc.files.FileHandle; -import io.anuke.arc.function.Consumer; -import io.anuke.arc.function.Predicate; -import io.anuke.arc.math.RandomXS128; -import io.anuke.arc.scene.ui.TextField; -import io.anuke.arc.util.serialization.Base64Coder; +import io.anuke.arc.*; +import io.anuke.arc.Input.*; +import io.anuke.arc.files.*; +import io.anuke.arc.function.*; +import io.anuke.arc.math.*; +import io.anuke.arc.scene.ui.*; +import io.anuke.arc.util.serialization.*; +import io.anuke.mindustry.ui.dialogs.*; import static io.anuke.mindustry.Vars.mobile; @@ -70,13 +70,18 @@ public interface Platform{ /** * Show a file chooser. - * @param text File chooser title text - * @param content Description of the type of files to be loaded * @param cons Selection listener * @param open Whether to open or save files - * @param filetype File extension to filter + * @param extension File extension to filter */ - default void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ + default void showFileChooser(boolean open, String extension, Consumer cons){ + new FileChooser(open ? "$open" : "$save", file -> file.extension().toLowerCase().equals(extension), open, file -> { + if(!open){ + cons.accept(file.parent().child(file.nameWithoutExtension() + "." + extension)); + }else{ + cons.accept(file); + } + }).show(); } /** Hide the app. Android only. */ diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 3647577151..4ec5d34037 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -91,20 +91,18 @@ public class MapEditorDialog extends Dialog implements Disposable{ createDialog("$editor.import", "$editor.importmap", "$editor.importmap.description", "icon-load-map", (Runnable)loadDialog::show, "$editor.importfile", "$editor.importfile.description", "icon-file", (Runnable)() -> - platform.showFileChooser("$editor.loadmap", "Map Files", file -> ui.loadAnd(() -> { + platform.showFileChooser(true, mapExtension, file -> ui.loadAnd(() -> { maps.tryCatchMapError(() -> { if(MapIO.isImage(file)){ ui.showInfo("$editor.errorimage"); - }else if(file.extension().equalsIgnoreCase(oldMapExtension)){ - editor.beginEdit(maps.makeLegacyMap(file)); }else{ editor.beginEdit(MapIO.createMap(file, true)); } }); - }), true, FileChooser.anyMapFiles), + })), "$editor.importimage", "$editor.importimage.description", "icon-file-image", (Runnable)() -> - platform.showFileChooser("$loadimage", "Image Files", file -> + platform.showFileChooser(true, "png", file -> ui.loadAnd(() -> { try{ Pixmap pixmap = new Pixmap(file); @@ -114,27 +112,25 @@ public class MapEditorDialog extends Dialog implements Disposable{ ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); Log.err(e); } - }), true, FileChooser.pngFiles)) + }))) ); } Cell cell = t.addImageTextButton("$editor.export", "icon-save-map", isize, () -> { if(!ios){ - platform.showFileChooser("$editor.savemap", "Map Files", file -> { - file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); - FileHandle result = file; + platform.showFileChooser(false, mapExtension, file -> { ui.loadAnd(() -> { try{ if(!editor.getTags().containsKey("name")){ - editor.getTags().put("name", result.nameWithoutExtension()); + editor.getTags().put("name", file.nameWithoutExtension()); } - MapIO.writeMap(result, editor.createMap(result)); + MapIO.writeMap(file, editor.createMap(file)); }catch(Exception e){ ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, true))); Log.err(e); } }); - }, false, FileChooser.mapFiles); + }); }else{ ui.loadAnd(() -> { try{ diff --git a/core/src/io/anuke/mindustry/game/GlobalData.java b/core/src/io/anuke/mindustry/game/GlobalData.java index 43b8095937..a782dc3f07 100644 --- a/core/src/io/anuke/mindustry/game/GlobalData.java +++ b/core/src/io/anuke/mindustry/game/GlobalData.java @@ -52,10 +52,12 @@ public class GlobalData{ } public void importData(FileHandle file){ - FileHandle zipped = new ZipFileHandle(file); + FileHandle dest = Core.files.local("zipdata.zip"); + file.copyTo(dest); + FileHandle zipped = new ZipFileHandle(dest); FileHandle base = Core.settings.getDataDirectory(); - if(!base.child("settings.bin").exists()){ + if(!zipped.child("settings.bin").exists()){ throw new IllegalArgumentException("Not valid save data."); } @@ -63,12 +65,13 @@ public class GlobalData{ for(FileHandle f : base.list()){ if(f.isDirectory()){ f.deleteDirectory(); - }else{ + }else if(!f.name().equals("zipdata.zip")){ f.delete(); } } zipped.walk(f -> f.copyTo(base.child(f.path()))); + dest.delete(); } public void modified(){ diff --git a/core/src/io/anuke/mindustry/game/Saves.java b/core/src/io/anuke/mindustry/game/Saves.java index 7f3cb40f59..74046d2fa4 100644 --- a/core/src/io/anuke/mindustry/game/Saves.java +++ b/core/src/io/anuke/mindustry/game/Saves.java @@ -297,9 +297,6 @@ public class Saves{ public void exportFile(FileHandle file) throws IOException{ try{ - if(!file.extension().equals(saveExtension)){ - file = file.parent().child(file.nameWithoutExtension() + "." + saveExtension); - } SaveIO.fileFor(index).copyTo(file); }catch(Exception e){ throw new IOException(e); diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index 81a4e6da49..bfd32b7a02 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -196,7 +196,7 @@ public class Maps{ Log.err(e); if("Outdated legacy map format".equals(e.getMessage())){ - ui.showError("$editor.errorlegacy"); + ui.showError("$editor.errornot"); }else if(e.getMessage() != null && e.getMessage().contains("Incorrect header!")){ ui.showError("$editor.errorheader"); }else{ @@ -290,34 +290,6 @@ public class Maps{ return str == null ? null : str.equals("[]") ? new Array<>() : Array.with(json.fromJson(SpawnGroup[].class, str)); } - public void loadLegacyMaps(){ - boolean convertedAny = false; - for(FileHandle file : customMapDirectory.list()){ - if(file.extension().equalsIgnoreCase(oldMapExtension)){ - try{ - convertedAny = true; - LegacyMapIO.convertMap(file, file.sibling(file.nameWithoutExtension() + "." + mapExtension)); - //delete old, converted file; it is no longer useful - file.delete(); - Log.info("Converted file {0}", file); - }catch(Exception e){ - //rename the file to a 'mmap_conversion_failed' extension to keep it there just in case - //but don't delete it - file.copyTo(file.sibling(file.name() + "_conversion_failed")); - file.delete(); - Log.err(e); - } - } - } - - //free up any potential memory that was used up during conversion - if(convertedAny){ - world.createTiles(1, 1); - //reload maps to load the converted ones - reload(); - } - } - public void loadPreviews(){ for(Map map : maps){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index f535d65d0a..1be788d6b8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -9,7 +9,6 @@ import io.anuke.arc.scene.style.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; -import io.anuke.mindustry.*; import io.anuke.mindustry.core.GameState.*; import io.anuke.mindustry.game.Saves.*; import io.anuke.mindustry.io.*; @@ -91,17 +90,17 @@ public class LoadDialog extends FloatingDialog{ t.addImageButton("icon-save", "empty", iconsize, () -> { if(!ios){ - platform.showFileChooser(Core.bundle.get("save.export"), "Mindustry Save", file -> { + platform.showFileChooser(false, saveExtension, file -> { try{ slot.exportFile(file); setup(); }catch(IOException e){ ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true))); } - }, false, FileChooser.saveFiles); + }); }else{ try{ - FileHandle file = Core.files.local("save-" + slot.getName() + "." + Vars.saveExtension); + FileHandle file = Core.files.local("save-" + slot.getName() + "." + saveExtension); slot.exportFile(file); platform.shareFile(file); }catch(Exception e){ @@ -172,7 +171,7 @@ public class LoadDialog extends FloatingDialog{ if(ios) return; slots.addImageTextButton("$save.import", "icon-add", iconsize, () -> { - platform.showFileChooser(Core.bundle.get("save.import"), "Mindustry Save", file -> { + platform.showFileChooser(true, saveExtension, file -> { if(SaveIO.isSaveValid(file)){ try{ control.saves.importSave(file); @@ -184,7 +183,7 @@ public class LoadDialog extends FloatingDialog{ }else{ ui.showError("$save.import.invalid"); } - }, true, FileChooser.saveFiles); + }); }).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index 1f2c04873b..0ec1195aa4 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -61,7 +61,7 @@ public class MapsDialog extends FloatingDialog{ if(!ios){ buttons.addImageTextButton("$editor.importmap", "icon-load", iconsize, () -> { - platform.showFileChooser("$editor.importmap", "Map File", file -> { + platform.showFileChooser(true, mapExtension, file -> { ui.loadAnd(() -> { maps.tryCatchMapError(() -> { if(MapIO.isImage(file)){ @@ -69,12 +69,8 @@ public class MapsDialog extends FloatingDialog{ return; } - Map map; - if(file.extension().equalsIgnoreCase(mapExtension)){ - map = MapIO.createMap(file, true); - }else{ - map = maps.makeLegacyMap(file); - } + Map map = MapIO.createMap(file, true); + //when you attempt to import a save, it will have no name, so generate one String name = map.tags.getOr("name", () -> { @@ -109,7 +105,7 @@ public class MapsDialog extends FloatingDialog{ }); }); - }, true, FileChooser.anyMapFiles); + }); }).size(210f, 64f); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 4bc481f992..8670df7aa3 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -102,14 +102,6 @@ public class SettingsMenuDialog extends SettingsDialog{ t.row(); - if(android && (Core.files.local("mindustry-maps").exists() || Core.files.local("mindustry-saves").exists())){ - t.addButton("$classic.export", style, () -> { - control.checkClassicData(); - }); - } - - t.row(); - t.addButton("$data.export", style, () -> { if(ios){ FileHandle file = Core.files.local("mindustry-data-export.zip"); @@ -120,19 +112,15 @@ public class SettingsMenuDialog extends SettingsDialog{ } platform.shareFile(file); }else{ - platform.showFileChooser("$data.export", "Zip Files", file -> { - FileHandle ff = file; - if(!ff.extension().equals("zip")){ - ff = ff.sibling(ff.nameWithoutExtension() + ".zip"); - } + platform.showFileChooser(false, "zip", file -> { try{ - data.exportData(ff); + data.exportData(file); ui.showInfo("$data.exported"); }catch(Exception e){ e.printStackTrace(); ui.showError(Strings.parseException(e, true)); } - }, false, f -> false); + }); } }); @@ -140,7 +128,7 @@ public class SettingsMenuDialog extends SettingsDialog{ //iOS doesn't have a file chooser. if(!ios){ - t.addButton("$data.import", style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> platform.showFileChooser("$data.import", "Zip Files", file -> { + t.addButton("$data.import", style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> platform.showFileChooser(true, "zip", file -> { try{ data.importData(file); Core.app.exit(); @@ -148,9 +136,13 @@ public class SettingsMenuDialog extends SettingsDialog{ ui.showError("$data.invalid"); }catch(Exception e){ e.printStackTrace(); - ui.showError(Strings.parseException(e, true)); + if(e.getMessage() == null || !e.getMessage().contains("too short")){ + ui.showError(Strings.parseException(e, true)); + }else{ + ui.showError("$data.invalid"); + } } - }, true, f -> f.equalsIgnoreCase("zip")))); + }))); } }); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 8679d29e7d..7417b37948 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -65,11 +65,6 @@ public class DesktopPlatform extends ClientLauncher{ }); } - @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ - new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons).show(); - } - @Override public void updateRPC(){ if(!useDiscord) return; From 168011586bd35071cd4a820a929444891c250f8c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 6 Sep 2019 22:09:54 -0400 Subject: [PATCH 2/2] More file chooser fixes --- android/AndroidManifest.xml | 25 +--------------------- core/assets/bundles/bundle.properties | 4 ++-- core/src/io/anuke/mindustry/maps/Maps.java | 21 +++++++++++++----- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 6e42e10a0c..a4202d4364 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -32,32 +32,9 @@ - - - - - - - - - + - - - - - - - - - - - - - diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 64da450d11..c451cfd568 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -233,7 +233,7 @@ editor.removeunit = Remove Unit editor.teams = Teams editor.errorload = Error loading file:\n[accent]{0} editor.errorsave = Error saving file:\n[accent]{0} -editor.errorimage = That's an image, not a map. Don't go around changing extensions expecting it to work.\n\nIf you want to import a legacy map, use the 'import legacy map' button in the editor. +editor.errorimage = That's an image, not a map.\n\nIf you want to import a 3.5/build 40 map, use the 'Import Legacy Map' button in the editor. editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. editor.errornot = This is not a map file. editor.errorheader = This map file is either not valid or corrupt. @@ -254,7 +254,7 @@ editor.importmap = Import Map editor.importmap.description = Import an already existing map editor.importfile = Import File editor.importfile.description = Import an external map file -editor.importimage = Import Legacy Image +editor.importimage = Import Legacy Map editor.importimage.description = Import an external map image file editor.export = Export... editor.exportfile = Export File diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index bfd32b7a02..d751f5fc7d 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -184,7 +184,18 @@ public class Maps{ FileHandle dest = findFile(); file.copyTo(dest); - createNewPreview(loadMap(dest, true)); + Map map = loadMap(dest, true); + Exception[] error = {null}; + + createNewPreview(map, e -> { + maps.remove(map); + error[0] = e; + }); + + if(error[0] != null){ + throw new IOException(error[0]); + } + } /** Attempts to run the following code; @@ -313,7 +324,7 @@ public class Maps{ private void createAllPreviews(){ Core.app.post(() -> { for(Map map : previewList){ - createNewPreview(map); + createNewPreview(map, e -> Core.app.post(() -> map.texture = new Texture("sprites/error.png"))); } previewList.clear(); }); @@ -323,7 +334,7 @@ public class Maps{ Core.app.post(() -> previewList.add(map)); } - private void createNewPreview(Map map){ + private void createNewPreview(Map map, Consumer failed){ try{ //if it's here, then the preview failed to load or doesn't exist, make it //this has to be done synchronously! @@ -337,9 +348,9 @@ public class Maps{ e.printStackTrace(); } }); - }catch(IOException e){ + }catch(Exception e){ + failed.accept(e); Log.err("Failed to generate preview!", e); - Core.app.post(() -> map.texture = new Texture("sprites/error.png")); } }