From 623079b45f66341b9038568748c53c06c7f5b6d3 Mon Sep 17 00:00:00 2001 From: CreepyCre Date: Mon, 11 Oct 2021 12:26:08 +0200 Subject: [PATCH] extract resource loading into ResourceUtil --- .../dimdev/dimdoors/pockets/PocketLoader.java | 66 +++----------- .../dimdev/dimdoors/util/ResourceUtil.java | 85 +++++++++++++++++++ .../dimdoors/world/decay/LimboDecay.java | 37 +------- 3 files changed, 99 insertions(+), 89 deletions(-) create mode 100644 src/main/java/org/dimdev/dimdoors/util/ResourceUtil.java diff --git a/src/main/java/org/dimdev/dimdoors/pockets/PocketLoader.java b/src/main/java/org/dimdev/dimdoors/pockets/PocketLoader.java index 8c17e09a..5f27aaed 100644 --- a/src/main/java/org/dimdev/dimdoors/pockets/PocketLoader.java +++ b/src/main/java/org/dimdev/dimdoors/pockets/PocketLoader.java @@ -1,16 +1,9 @@ package org.dimdev.dimdoors.pockets; -import java.io.IOException; -import java.io.InputStreamReader; import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.stream.Collectors; -import com.google.gson.*; -import com.mojang.serialization.JsonOps; - import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; import net.minecraft.nbt.*; import net.minecraft.resource.ResourceManager; @@ -24,11 +17,11 @@ import org.dimdev.dimdoors.api.util.SimpleTree; import org.dimdev.dimdoors.pockets.generator.PocketGenerator; import org.dimdev.dimdoors.pockets.virtual.VirtualPocket; import org.dimdev.dimdoors.api.util.WeightedList; +import org.dimdev.dimdoors.util.ResourceUtil; import org.dimdev.dimdoors.util.schematic.Schematic; public class PocketLoader implements SimpleSynchronousResourceReloadListener { private static final Logger LOGGER = LogManager.getLogger(); - private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create(); private static final PocketLoader INSTANCE = new PocketLoader(); private SimpleTree pocketGenerators = new SimpleTree<>(String.class); private SimpleTree pocketGroups = new SimpleTree<>(String.class); @@ -47,12 +40,12 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener { templates.clear(); dataTree.clear(); - dataTree = loadResourcePathFromJsonToTree(manager, "pockets/json", t -> t).join(); + dataTree = ResourceUtil.loadResourcePathToMap(manager, "pockets/json", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.composeIdentity(), ResourceUtil.PATH_KEY_PROVIDER).join(); - CompletableFuture> futurePocketGeneratorMap = loadResourcePathFromJsonToTree(manager, "pockets/generators", this::loadPocketGenerator); - CompletableFuture> futurePocketGroups = loadResourcePathFromJsonToTree(manager, "pockets/groups", this::loadVirtualPocket); - CompletableFuture> futureVirtualPockets = loadResourcePathFromJsonToTree(manager, "pockets/virtual", this::loadVirtualPocket); - CompletableFuture> futureTemplates = loadResourcePathFromCompressedNbtToTree(manager, "pockets/schematic", ".schem", this::loadPocketTemplate); + CompletableFuture> futurePocketGeneratorMap = ResourceUtil.loadResourcePathToMap(manager, "pockets/generators", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.andThenReader(this::loadPocketGenerator), ResourceUtil.PATH_KEY_PROVIDER); + CompletableFuture> futurePocketGroups = ResourceUtil.loadResourcePathToMap(manager, "pockets/groups", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.andThenReader(this::loadVirtualPocket), ResourceUtil.PATH_KEY_PROVIDER); + CompletableFuture> futureVirtualPockets = ResourceUtil.loadResourcePathToMap(manager, "pockets/virtual", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.andThenReader(this::loadVirtualPocket), ResourceUtil.PATH_KEY_PROVIDER); + CompletableFuture> futureTemplates = ResourceUtil.loadResourcePathToMap(manager, "pockets/schematic", ".schem", new SimpleTree<>(String.class), ResourceUtil.COMPRESSED_NBT_READER.andThenReader(this::loadPocketTemplate), ResourceUtil.PATH_KEY_PROVIDER); pocketGenerators = futurePocketGeneratorMap.join(); @@ -64,45 +57,6 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener { virtualPockets.values().forEach(VirtualPocket::init); } - private CompletableFuture> loadResourcePathFromJsonToTree(ResourceManager manager, String startingPath, Function reader) { - int sub = startingPath.endsWith("/") ? 0 : 1; - - Collection ids = manager.findResources(startingPath, str -> str.endsWith(".json")); - return CompletableFuture.supplyAsync(() -> { - SimpleTree tree = new SimpleTree<>(String.class); - tree.putAll(ids.parallelStream().unordered().collect(Collectors.toConcurrentMap( - id -> Path.stringPath(id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + sub)), - id -> { - try { - JsonElement json = GSON.fromJson(new InputStreamReader(manager.getResource(id).getInputStream()), JsonElement.class); - return reader.apply(JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, json)); - } catch (IOException e) { - throw new RuntimeException("Error loading resource: " + id); - } - }))); - return tree; - }); - } - - private CompletableFuture> loadResourcePathFromCompressedNbtToTree(ResourceManager manager, String startingPath, String extension, BiFunction reader) { - int sub = startingPath.endsWith("/") ? 0 : 1; - Function> normalizer = id -> Path.stringPath(id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + sub)); - Collection ids = manager.findResources(startingPath, str -> str.endsWith(extension)); - return CompletableFuture.supplyAsync(() -> { - SimpleTree tree = new SimpleTree<>(String.class); - tree.putAll(ids.parallelStream().unordered().collect(Collectors.toConcurrentMap( - normalizer, - id -> { - try { - return reader.apply(NbtIo.readCompressed(manager.getResource(id).getInputStream()), normalizer.apply(id).reduce(String::concat).get()); - } catch (IOException e) { - throw new RuntimeException("Error loading resource: " + id); - } - }))); - return tree; - }); - } - // public void load() { // long startTime = System.currentTimeMillis(); // @@ -132,17 +86,17 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener { return NbtUtil.asNbtCompound(getDataNbt(id), "Could not convert NbtElement \"" + id + "\" to NbtCompound!"); } - private VirtualPocket loadVirtualPocket(NbtElement nbt) { + private VirtualPocket loadVirtualPocket(NbtElement nbt, Path ignore) { return VirtualPocket.deserialize(nbt); } - private PocketGenerator loadPocketGenerator(NbtElement nbt) { + private PocketGenerator loadPocketGenerator(NbtElement nbt, Path ignore) { return PocketGenerator.deserialize(NbtUtil.asNbtCompound(nbt, "Could not load PocketGenerator since its json does not represent an NbtCompound!")); } - private PocketTemplate loadPocketTemplate(NbtCompound nbt, String id) { + private PocketTemplate loadPocketTemplate(NbtCompound nbt, Path id) { try { - return new PocketTemplate(Schematic.fromNbt(nbt), new Identifier(id)); + return new PocketTemplate(Schematic.fromNbt(nbt), new Identifier(id.reduce(String::concat).orElseThrow())); } catch (Exception e) { throw new RuntimeException("Error loading " + nbt.toString(), e); } diff --git a/src/main/java/org/dimdev/dimdoors/util/ResourceUtil.java b/src/main/java/org/dimdev/dimdoors/util/ResourceUtil.java new file mode 100644 index 00000000..9aa92fe4 --- /dev/null +++ b/src/main/java/org/dimdev/dimdoors/util/ResourceUtil.java @@ -0,0 +1,85 @@ +package org.dimdev.dimdoors.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.mojang.serialization.JsonOps; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.NbtOps; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import org.dimdev.dimdoors.api.util.Path; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ResourceUtil { + private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create(); + + public static final BiFunction> PATH_KEY_PROVIDER = (startingPath, id) -> Path.stringPath(id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + (startingPath.endsWith("/") ? 0 : 1))); + + public static final ComposableFunction JSON_TO_NBT = json -> JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, json); + + public static final ComposableFunction JSON_READER = inputStream -> GSON.fromJson(new InputStreamReader(inputStream), JsonElement.class); + public static final ComposableFunction NBT_READER = JSON_READER.andThenComposable(JSON_TO_NBT); + public static final ComposableFunction COMPRESSED_NBT_READER = inputStream -> { + try { + return NbtIo.readCompressed(inputStream); + } catch (IOException e) { + throw new RuntimeException(); + } + }; + + public static > CompletableFuture loadResourcePathToMap(ResourceManager manager, String startingPath, String extension, M map, BiFunction reader, BiFunction keyProvider) { + Collection ids = manager.findResources(startingPath, str -> str.endsWith(extension)); + return CompletableFuture.supplyAsync(() -> { + map.putAll(ids.parallelStream().unordered().collect(Collectors.toConcurrentMap( + id -> keyProvider.apply(startingPath, id), + id -> { + try { + return reader.apply(manager.getResource(id).getInputStream(), keyProvider.apply(startingPath, id)); + } catch (IOException | RuntimeException e) { + throw new RuntimeException("Error loading resource: " + id); + } + }))); + return map; + }); + } + + public static > CompletableFuture loadResourcePathToCollection(ResourceManager manager, String startingPath, String extension, M collection, BiFunction reader) { + Collection ids = manager.findResources(startingPath, str -> str.endsWith(extension)); + return CompletableFuture.supplyAsync(() -> { + collection.addAll(ids.parallelStream().unordered().map(id -> { + try { + return reader.apply(manager.getResource(id).getInputStream(), id); + } catch (IOException e) { + throw new RuntimeException("Error loading resource: " + id); + } + }).collect(Collectors.toList())); // TODO: change this to smthn concurrent + return collection; + }); + } + + public interface ComposableFunction extends Function { + default BiFunction andThenReader(BiFunction function) { + return (t, k) -> function.apply(apply(t), k); + } + + default BiFunction composeIdentity() { + return (t, k) -> apply(t); + } + + default ComposableFunction andThenComposable(Function after) { + return (T t) -> after.apply(apply(t)); + } + } +} diff --git a/src/main/java/org/dimdev/dimdoors/world/decay/LimboDecay.java b/src/main/java/org/dimdev/dimdoors/world/decay/LimboDecay.java index 377de0a6..bc017d54 100644 --- a/src/main/java/org/dimdev/dimdoors/world/decay/LimboDecay.java +++ b/src/main/java/org/dimdev/dimdoors/world/decay/LimboDecay.java @@ -1,21 +1,12 @@ package org.dimdev.dimdoors.world.decay; -import java.io.IOException; -import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.stream.Collectors; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; @@ -25,9 +16,7 @@ import net.minecraft.resource.ResourceManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dimdev.dimdoors.DimensionalDoorsInitializer; -import org.dimdev.dimdoors.api.util.Path; -import org.dimdev.dimdoors.api.util.SimpleTree; -import org.dimdev.dimdoors.world.decay.DecayPattern; +import org.dimdev.dimdoors.util.ResourceUtil; import org.jetbrains.annotations.NotNull; import net.minecraft.util.Identifier; @@ -86,7 +75,6 @@ public final class LimboDecay { public static class DecayLoader implements SimpleSynchronousResourceReloadListener { private static final Logger LOGGER = LogManager.getLogger(); - private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create(); private static final DecayLoader INSTANCE = new DecayLoader(); private List patterns = new ArrayList<>(); @@ -100,29 +88,12 @@ public final class LimboDecay { @Override public void reload(ResourceManager manager) { patterns.clear(); - CompletableFuture> futurePatternMap = loadResourcePathFromJsonToTree(manager, "decay_patterns", this::loadPattern); + CompletableFuture> futurePatternMap = ResourceUtil.loadResourcePathToCollection(manager, "decay_patterns", ".json", new ArrayList<>(), ResourceUtil.JSON_READER.andThenReader(this::loadPattern)); patterns = futurePatternMap.join(); } - private DecayPattern loadPattern(JsonObject object) { - return DecayPattern.deserialize(object); - } - - private CompletableFuture> loadResourcePathFromJsonToTree(ResourceManager manager, String startingPath, Function reader) { - Collection ids = manager.findResources(startingPath, str -> str.endsWith(".json")); - return CompletableFuture.supplyAsync(() -> { - List tree = new ArrayList<>(); - ids.parallelStream().unordered().map( - id -> { - try { - JsonElement json = GSON.fromJson(new InputStreamReader(manager.getResource(id).getInputStream()), JsonElement.class); - return reader.apply(json.getAsJsonObject()); - } catch (IOException e) { - throw new RuntimeException("Error loading resource: " + id); - } - }).forEach(tree::add); - return tree; - }); + private DecayPattern loadPattern(JsonElement object, Identifier ignored) { + return DecayPattern.deserialize(object.getAsJsonObject()); } public @NotNull Collection getPatterns() {