Skip to content

Commit bcf8d12

Browse files
committed
Make WorldFormats registerable
1 parent cf31ed1 commit bcf8d12

6 files changed

Lines changed: 77 additions & 47 deletions

File tree

chunky/src/java/se/llbit/chunky/map/WorldMapLoader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import se.llbit.chunky.world.region.RegionParser;
2727
import se.llbit.chunky.world.region.RegionQueue;
2828
import se.llbit.chunky.world.listeners.ChunkTopographyListener;
29-
import se.llbit.chunky.world.worldformat.WorldFormat;
29+
import se.llbit.chunky.world.worldformat.WorldFormats;
3030
import se.llbit.log.Log;
3131

3232
import java.io.File;
@@ -71,7 +71,7 @@ public void loadWorldFromDirectory(File worldLocation) {
7171
if (worldLocation == null) {
7272
return;
7373
}
74-
this.loadWorld(WorldFormat.loadWorld(worldLocation).orElse(EmptyWorld.INSTANCE));
74+
this.loadWorld(WorldFormats.createWorld(worldLocation).orElse(EmptyWorld.INSTANCE));
7575
}
7676
/**
7777
* This is called when a new world is loaded

chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
import se.llbit.chunky.world.biome.Biome;
5454
import se.llbit.chunky.world.biome.BiomePalette;
5555
import se.llbit.chunky.world.biome.Biomes;
56-
import se.llbit.chunky.world.worldformat.WorldFormat;
56+
import se.llbit.chunky.world.worldformat.WorldFormats;
5757
import se.llbit.json.*;
5858
import se.llbit.log.Log;
5959
import se.llbit.math.*;
@@ -544,7 +544,7 @@ public synchronized void loadScene(RenderContext context, String sceneName, Task
544544
loadedWorld = EmptyWorld.INSTANCE;
545545
if (!worldPath.isEmpty()) {
546546
File worldDirectory = new File(worldPath);
547-
loadedWorld = WorldFormat.loadWorld(worldDirectory).orElse(EmptyWorld.INSTANCE);
547+
loadedWorld = WorldFormats.createWorld(worldDirectory).orElse(EmptyWorld.INSTANCE);
548548
loadedWorld.loadDimension(this.worldDimension);
549549
}
550550

chunky/src/java/se/llbit/chunky/ui/controller/WorldChooserController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import se.llbit.chunky.ui.TableSortConfigSerializer;
3535
import se.llbit.chunky.world.EmptyWorld;
3636
import se.llbit.chunky.world.World;
37-
import se.llbit.chunky.world.worldformat.WorldFormat;
37+
import se.llbit.chunky.world.worldformat.WorldFormats;
3838
import se.llbit.fxutil.Dialogs;
3939
import se.llbit.json.JsonArray;
4040
import se.llbit.log.Log;
@@ -134,7 +134,7 @@ public void populate(WorldMapLoader mapLoader) {
134134
File directory = chooser.showDialog(stage);
135135
if (directory != null) {
136136
if (directory.isDirectory()) {
137-
this.loadWorld(WorldFormat.loadWorld(directory).orElse(EmptyWorld.INSTANCE), mapLoader);
137+
this.loadWorld(WorldFormats.createWorld(directory).orElse(EmptyWorld.INSTANCE), mapLoader);
138138
stage.close();
139139
} else {
140140
Log.warn("Non-directory selected.");
@@ -195,7 +195,7 @@ protected List<World> call() {
195195
File[] worldDirs = worldSavesDir.listFiles();
196196
if (worldDirs != null) {
197197
for (File dir : worldDirs) {
198-
WorldFormat.loadWorld(dir).ifPresent(worlds::add);
198+
WorldFormats.createWorld(dir).ifPresent(worlds::add);
199199
}
200200
}
201201
}

chunky/src/java/se/llbit/chunky/world/worldformat/JavaWorldFormat.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,31 @@
33
import se.llbit.chunky.world.JavaWorld;
44
import se.llbit.chunky.world.World;
55

6-
import java.io.IOException;
76
import java.nio.file.Path;
87

98
public class JavaWorldFormat implements WorldFormat {
109
@Override
11-
public World loadWorld(Path path) throws IOException {
12-
return JavaWorld.loadWorld(path.toFile(), World.LoggedWarnings.SILENT);
10+
public String getName() {
11+
return "Java (Anvil)";
1312
}
1413

1514
@Override
16-
public String name() {
17-
return "Java (Anvil)";
15+
public String getDescription() {
16+
return "The Minecraft world format for Java worlds since 1.2.1 (12w07a)";
17+
}
18+
19+
@Override
20+
public String getId() {
21+
return "JAVA_ANVIL";
1822
}
1923

2024
@Override
2125
public boolean isValid(Path path) {
2226
return JavaWorld.isWorldDir(path.toFile());
2327
}
28+
29+
@Override
30+
public World loadWorld(Path path) {
31+
return JavaWorld.loadWorld(path.toFile(), World.LoggedWarnings.SILENT);
32+
}
2433
}

chunky/src/java/se/llbit/chunky/world/worldformat/WorldFormat.java

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,13 @@
11
package se.llbit.chunky.world.worldformat;
22

3-
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
4-
import se.llbit.chunky.world.EmptyWorld;
53
import se.llbit.chunky.world.World;
6-
import se.llbit.log.Log;
4+
import se.llbit.util.Registerable;
75

8-
import java.io.File;
96
import java.io.IOException;
107
import java.nio.file.Path;
11-
import java.util.*;
128

139
/** For worlds that have multiple dimensions, and fully support the map view */
14-
public interface WorldFormat {
15-
// TODO: Registerable
16-
Collection<WorldFormat> worldFormats = List.of(new JavaWorldFormat());
17-
18-
// Should this go somewhere else?
19-
static Optional<World> loadWorld(File dir) {
20-
Map<String, World> worldsByFormat = new Object2ObjectOpenHashMap<>();
21-
22-
for (WorldFormat worldFormat : WorldFormat.worldFormats) {
23-
if (worldFormat.isValid(dir.toPath())) {
24-
try {
25-
World world = worldFormat.loadWorld(dir.toPath());
26-
if (world != EmptyWorld.INSTANCE) {
27-
worldsByFormat.put(worldFormat.name(), world);
28-
}
29-
} catch (IOException e) {
30-
Log.error(String.format("An error occurred when trying to load a world using format `%s` from %s", worldFormat.name(), dir.getAbsolutePath()), e);
31-
}
32-
}
33-
}
34-
if (worldsByFormat.size() > 1) {
35-
// Maybe allow the user to select which?
36-
// This method is called from a variety of different popup/menu situations, is this ^ possible?
37-
Log.warn(String.format("The directory %s has multiple valid world formats: %s", dir.getAbsolutePath(), String.join(", ", worldsByFormat.keySet())));
38-
}
39-
return worldsByFormat.values().stream().findFirst();
40-
}
41-
42-
String name();
43-
10+
public interface WorldFormat extends Registerable {
4411
/**
4512
* This method will be called on every possible world directory (typically this is every directory in `.minecraft/saves`).
4613
*
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package se.llbit.chunky.world.worldformat;
2+
3+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
4+
import se.llbit.chunky.world.EmptyWorld;
5+
import se.llbit.chunky.world.World;
6+
import se.llbit.log.Log;
7+
8+
import java.io.File;
9+
import java.io.IOException;
10+
import java.util.*;
11+
12+
public class WorldFormats {
13+
private static final Map<String, WorldFormat> worldFormatsById = new Object2ObjectOpenHashMap<>();
14+
15+
public static void addWorldFormat(WorldFormat worldFormat) {
16+
worldFormatsById.put(worldFormat.getId(), worldFormat);
17+
}
18+
19+
public static Map<String, WorldFormat> getWorldFormats() {
20+
return Collections.unmodifiableMap(worldFormatsById);
21+
}
22+
23+
public static WorldFormat getWorldFormat(String id) {
24+
return worldFormatsById.get(id);
25+
}
26+
27+
static {
28+
addWorldFormat(new JavaWorldFormat());
29+
}
30+
31+
public static Optional<World> createWorld(File dir) {
32+
Map<String, World> providedWorlds = new Object2ObjectOpenHashMap<>();
33+
34+
getWorldFormats().forEach((id, format) -> {
35+
if (format.isValid(dir.toPath())) {
36+
try {
37+
World world = format.loadWorld(dir.toPath());
38+
if (world != EmptyWorld.INSTANCE) {
39+
providedWorlds.put(format.getId(), world);
40+
}
41+
} catch (IOException e) {
42+
Log.error(String.format("An error occurred when trying to load a world using format `%s` from %s", format.getName(), dir.getAbsolutePath()), e);
43+
}
44+
}
45+
});
46+
47+
if (providedWorlds.size() > 1) {
48+
// Maybe allow the user to select which?
49+
// This method is called from a variety of different popup/menu situations, is this ^ possible?
50+
Log.warn(String.format("The directory %s has multiple valid world formats: %s", dir.getAbsolutePath(), String.join(", ", providedWorlds.keySet())));
51+
}
52+
return providedWorlds.values().stream().findFirst();
53+
}
54+
}

0 commit comments

Comments
 (0)