implement new tectonic depthtracker API

This commit is contained in:
dfsek
2021-12-27 23:01:48 -07:00
parent 8d7468457f
commit ea5dd297cb
38 changed files with 224 additions and 129 deletions

View File

@@ -13,6 +13,6 @@ dependencies {
implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:+")
implementation("org.ow2.asm:asm:9.2")
implementation("org.ow2.asm:asm-tree:9.2")
implementation("com.dfsek.tectonic:common:3.1.0")
implementation("com.dfsek.tectonic:common:4.2.0")
implementation("org.yaml:snakeyaml:1.27")
}

View File

@@ -1,6 +1,6 @@
object Versions {
object Libraries {
const val tectonic = "4.0.0"
const val tectonic = "4.2.0"
const val paralithic = "0.6.0"
const val strata = "1.1.1"

View File

@@ -1,5 +1,6 @@
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -21,7 +22,7 @@ public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> {
}
@Override
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
if(c.equals("SELF")) return BiomeDelegate.self();
return biomeRegistry
.getByID((String) c)

View File

@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.biome.holder;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -17,16 +18,18 @@ import java.util.Map;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import org.jetbrains.annotations.NotNull;
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
@SuppressWarnings("unchecked")
@Override
public PaletteHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
public PaletteHolder load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException {
List<Map<String, Integer>> palette = (List<Map<String, Integer>>) o;
PaletteHolderBuilder builder = new PaletteHolderBuilder();
for(Map<String, Integer> layer : palette) {
for(Map.Entry<String, Integer> entry : layer.entrySet()) {
builder.add(entry.getValue(), configLoader.loadType(Palette.class, entry.getKey()));
builder.add(entry.getValue(), configLoader.loadType(Palette.class, entry.getKey(), depthTracker));
}
}
return builder.build();

View File

@@ -79,8 +79,8 @@ public class NoiseAddon implements AddonInitializer {
NOISE_SAMPLER_TOKEN);
event.getPack()
.applyLoader(CellularSampler.DistanceFunction.class,
(t, o, l) -> CellularSampler.DistanceFunction.valueOf((String) o))
.applyLoader(CellularSampler.ReturnType.class, (t, o, l) -> CellularSampler.ReturnType.valueOf((String) o))
(type, o, loader, depthTracker) -> CellularSampler.DistanceFunction.valueOf((String) o))
.applyLoader(CellularSampler.ReturnType.class, (type, o, loader, depthTracker) -> CellularSampler.ReturnType.valueOf((String) o))
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
.applyLoader(FunctionTemplate.class, FunctionTemplate::new);

View File

@@ -56,7 +56,7 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
Map<String, Function> noiseFunctionMap = generateFunctions();
return new ExpressionFunction(noiseFunctionMap, equation, vars);
} catch(ParseException e) {
throw new LoadException("Failed to parse expression.", e);
throw new RuntimeException("Failed to parse expression.", e);
}
}

View File

@@ -31,7 +31,7 @@ public class PaletteAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
event.getPack().registerConfigType(new PaletteConfigType(platform), addon.key("PALETTE"), 2);
event.getPack().applyLoader(PaletteLayerHolder.class, new PaletteLayerLoader());
event.getPack().applyLoader(PaletteLayerHolder.class, PaletteLayerLoader::new);
})
.failThrough();
}

View File

@@ -7,6 +7,10 @@
package com.dfsek.terra.addons.palette.palette;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -18,33 +22,22 @@ import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unchecked")
public class PaletteLayerLoader implements TypeLoader<PaletteLayerHolder> {
private static final AnnotatedType BLOCK_DATA_PROBABILITY_COLLECTION_TYPE;
static {
try {
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = PaletteLayerLoader.class.getDeclaredField("blockStateProbabilityCollection")
.getAnnotatedType();
} catch(NoSuchFieldException e) {
throw new Error("this should never happen. i dont know what you did to make this happen but something is very wrong.", e);
}
}
@SuppressWarnings("unused")
private ProbabilityCollection<BlockState> blockStateProbabilityCollection;
public class PaletteLayerLoader implements ObjectTemplate<PaletteLayerHolder> {
@Value("materials")
private ProbabilityCollection<BlockState> collection;
@Value("sampler")
@Default
private NoiseSampler sampler = null;
@Value("layers")
private int layers;
@Override
public PaletteLayerHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) o;
ProbabilityCollection<BlockState> collection = (ProbabilityCollection<BlockState>) configLoader.loadType(
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE, map.get("materials"));
NoiseSampler sampler = null;
if(map.containsKey("sampler")) {
sampler = configLoader.loadType(NoiseSampler.class, map.get("sampler"));
}
if(collection == null) throw new LoadException("Collection is null: " + map.get("materials"));
return new PaletteLayerHolder(collection, sampler, (Integer) map.get("layers"));
public PaletteLayerHolder get() {
return new PaletteLayerHolder(collection, sampler, layers);
}
}

View File

@@ -10,20 +10,22 @@ package com.dfsek.terra.addons.manifest.impl.config.loaders;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
public class VersionLoader implements TypeLoader<Version> {
@Override
public Version load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public Version load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
try {
return Versions.parseVersion((String) c);
} catch(ParseException e) {
throw new LoadException("Failed to parse version", e);
throw new LoadException("Failed to parse version", e, depthTracker);
}
}
}

View File

@@ -10,20 +10,22 @@ package com.dfsek.terra.addons.manifest.impl.config.loaders;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.VersionRange;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
public class VersionRangeLoader implements TypeLoader<VersionRange> {
@Override
public VersionRange load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public VersionRange load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
try {
return Versions.parseVersionRange((String) c);
} catch(ParseException e) {
throw new LoadException("Failed to parse version range", e);
throw new LoadException("Failed to parse version range", e, depthTracker);
}
}
}

View File

@@ -23,7 +23,7 @@ public class PaletteBlockShortcutAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack()
.registerShortcut(Palette.class, "BLOCK",
(configLoader, input) -> new SingletonPalette(configLoader.loadType(BlockState.class, input))))
(configLoader, input, tracker) -> new SingletonPalette(configLoader.loadType(BlockState.class, input, tracker))))
.failThrough();
}
}

View File

@@ -23,7 +23,7 @@ public class StructureBlockShortcutAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack()
.registerShortcut(Structure.class, "BLOCK",
(configLoader, input) -> new SingletonStructure(configLoader.loadType(BlockState.class, input)
(configLoader, input, tracker) -> new SingletonStructure(configLoader.loadType(BlockState.class, input, tracker)
)))
.failThrough();
}

View File

@@ -53,7 +53,7 @@ public class TerraScriptAddon implements AddonInitializer {
lootRegistry,
event.getPack().getOrCreateRegistry(FunctionBuilder.class));
} catch(ParseException e) {
throw new LoadException("Failed to load script \"" + entry.getKey() + "\"", e);
throw new RuntimeException("Failed to load script \"" + entry.getKey() + "\"", e);
}
})
.toList()

View File

@@ -1,8 +1,9 @@
package com.dfsek.terra.api.tectonic;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.loader.ConfigLoader;
public interface ShortcutLoader<T> {
T load(ConfigLoader configLoader, String input);
T load(ConfigLoader configLoader, String input, DepthTracker tracker);
}

View File

@@ -57,9 +57,10 @@ public class GenericLoaders implements LoaderRegistrar {
if(platform != null) {
registry.registerLoader(BaseAddon.class, platform.getAddons())
.registerLoader(BlockType.class,
(t, object, cf) -> platform.getWorldHandle().createBlockState((String) object).getBlockType())
.registerLoader(BlockState.class, (t, object, cf) -> platform.getWorldHandle().createBlockState((String) object));
.registerLoader(BlockType.class, (type, object, configLoader, depthTracker) -> platform
.getWorldHandle().createBlockState((String) object).getBlockType())
.registerLoader(BlockState.class, (type, object, configLoader, depthTracker) -> platform
.getWorldHandle().createBlockState((String) object));
}
}
}

View File

@@ -18,6 +18,7 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.ConfigException;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
@@ -42,15 +43,13 @@ public class GenericTemplateSupplierLoader<T> implements TypeLoader<T> {
@SuppressWarnings("unchecked")
@Override
public T load(@NotNull AnnotatedType t, @NotNull Object c, ConfigLoader loader) throws LoadException {
public T load(@NotNull AnnotatedType t, @NotNull Object c, ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
Map<String, Object> map = (Map<String, Object>) c;
try {
return loader
.load(registry.getByID(((String) map.get("type")))
.orElseThrow(() -> new LoadException("No such entry: " + map.get("type")))
.get(), new MapConfiguration(map)).get();
} catch(ConfigException e) {
throw new LoadException("Unable to load object: ", e);
}
String type = (String) map.get("type");
return loader
.load(registry.getByID(type)
.orElseThrow(() -> new LoadException("No such entry: " + map.get("type"), depthTracker))
.get(), new MapConfiguration(map), depthTracker.intrinsic("With type \"" + type + "\"")).get();
}
}

View File

@@ -17,9 +17,11 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
@@ -30,16 +32,17 @@ import java.util.Map;
@SuppressWarnings("unchecked")
public class LinkedHashMapLoader implements TypeLoader<LinkedHashMap<Object, Object>> {
@Override
public LinkedHashMap<Object, Object> load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public LinkedHashMap<Object, Object> load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
Map<String, Object> config = (Map<String, Object>) c;
LinkedHashMap<Object, Object> map = new LinkedHashMap<>();
if(t instanceof AnnotatedParameterizedType pType) {
AnnotatedType key = pType.getAnnotatedActualTypeArguments()[0];
AnnotatedType value = pType.getAnnotatedActualTypeArguments()[1];
for(Map.Entry<String, Object> entry : config.entrySet()) {
map.put(loader.loadType(key, entry.getKey()), loader.loadType(value, entry.getValue()));
map.put(loader.loadType(key, entry.getKey(), depthTracker.entry(entry.getKey())),
loader.loadType(value, entry.getValue(), depthTracker.entry(entry.getKey())));
}
} else throw new LoadException("Unable to load config");
} else throw new LoadException("Unable to load config", depthTracker);
return map;
}

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -27,19 +28,21 @@ import java.util.List;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.util.collection.MaterialSet;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unchecked")
public class MaterialSetLoader implements TypeLoader<MaterialSet> {
@Override
public MaterialSet load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
public MaterialSet load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException {
List<String> stringData = (List<String>) o;
MaterialSet set = new MaterialSet();
for(String string : stringData) {
try {
set.add(configLoader.loadType(BlockType.class, string));
set.add(configLoader.loadType(BlockType.class, string, depthTracker));
} catch(NullPointerException e) {
throw new LoadException("Invalid data identifier \"" + string + "\"", e);
throw new LoadException("Invalid data identifier \"" + string + "\"", e, depthTracker);
}
}

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -25,38 +26,46 @@ import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unchecked")
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
@Override
public ProbabilityCollection<Object> load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
public ProbabilityCollection<Object> load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
if(type instanceof AnnotatedParameterizedType pType) {
AnnotatedType generic = pType.getAnnotatedActualTypeArguments()[0];
if(o instanceof Map) {
Map<Object, Integer> map = (Map<Object, Integer>) o;
for(Map.Entry<Object, Integer> entry : map.entrySet()) {
collection.add(configLoader.loadType(generic, entry.getKey()), entry.getValue());
Map<Object, Object> map = (Map<Object, Object>) o;
for(Map.Entry<Object, Object> entry : map.entrySet()) {
collection.add(configLoader.loadType(generic, entry.getKey(), depthTracker.entry((String) entry.getKey())),
configLoader.loadType(Integer.class, entry.getValue(), depthTracker.entry((String) entry.getKey())));
}
} else if(o instanceof List) {
List<Map<Object, Integer>> map = (List<Map<Object, Integer>>) o;
for(Map<Object, Integer> l : map) {
for(Map.Entry<Object, Integer> entry : l.entrySet()) {
if(entry.getValue() == null) throw new LoadException("No probability defined for entry \"" + entry.getKey() + "\"");
Object val = configLoader.loadType(generic, entry.getKey());
collection.add(val, entry.getValue());
List<Map<Object, Object>> map = (List<Map<Object, Object>>) o;
for(int i = 0; i < map.size(); i++) {
Map<Object, Object> l = map.get(i);
for(Entry<Object, Object> entry : l.entrySet()) {
if(entry.getValue() == null) throw new LoadException("No probability defined for entry \"" + entry.getKey() + "\"",
depthTracker);
Object val = configLoader.loadType(generic, entry.getKey(), depthTracker.index(i).entry((String) entry.getKey()));
collection.add(val,
configLoader.loadType(Integer.class, entry.getValue(), depthTracker.entry((String) entry.getKey())));
}
}
} else if(o instanceof String) {
return new ProbabilityCollection.Singleton<>(configLoader.loadType(generic, o));
return new ProbabilityCollection.Singleton<>(configLoader.loadType(generic, o, depthTracker));
} else {
throw new LoadException("Malformed Probability Collection: " + o);
throw new LoadException("Malformed Probability Collection: " + o, depthTracker);
}
} else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type);
} else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type, depthTracker);
return collection;

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -32,12 +33,12 @@ import com.dfsek.terra.api.util.Range;
@SuppressWarnings("unchecked")
public class RangeLoader implements TypeLoader<Range> {
@Override
public Range load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader) throws LoadException {
public Range load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException {
if(o instanceof Map) {
Map<String, Integer> map = (Map<String, Integer>) o;
return new ConstantRange(map.get("min"), map.get("max"));
} else {
int h = configLoader.loadType(Integer.class, o);
int h = configLoader.loadType(Integer.class, o, depthTracker);
return new ConstantRange(h, h + 1);
}
}

View File

@@ -3,6 +3,7 @@ package com.dfsek.terra.config.loaders;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -13,11 +14,11 @@ import java.lang.reflect.AnnotatedType;
public class VersionLoader implements TypeLoader<Version> {
@Override
public Version load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
public Version load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
try {
return Versions.parseVersion((String) c);
} catch(ParseException e) {
throw new LoadException("Failed to parse version", e);
throw new LoadException("Failed to parse version", e, depthTracker);
}
}
}

View File

@@ -20,20 +20,22 @@ package com.dfsek.terra.config.loaders;
import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.VersionRange;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
public class VersionRangeLoader implements TypeLoader<VersionRange> {
@Override
public VersionRange load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public VersionRange load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
try {
return Versions.parseVersionRange((String) c);
} catch(ParseException e) {
throw new LoadException("Failed to parse version range: ", e);
throw new LoadException("Failed to parse version range: ", e, depthTracker);
}
}
}

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.config.loaders.config;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -28,6 +29,8 @@ import java.lang.reflect.AnnotatedType;
import com.dfsek.terra.api.config.Loader;
import org.jetbrains.annotations.NotNull;
public class BufferedImageLoader implements TypeLoader<BufferedImage> {
private final Loader files;
@@ -37,11 +40,11 @@ public class BufferedImageLoader implements TypeLoader<BufferedImage> {
}
@Override
public BufferedImage load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public BufferedImage load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
try {
return ImageIO.read(files.get((String) c));
} catch(IOException e) {
throw new LoadException("Unable to load image", e);
throw new LoadException("Unable to load image", e, depthTracker);
}
}
}

View File

@@ -41,6 +41,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -127,7 +128,7 @@ public class ConfigPackImpl implements ConfigPack {
try {
return new YamlConfiguration(new FileInputStream(new File(folder, "pack.yml")), "pack.yml");
} catch(FileNotFoundException e) {
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath());
throw new UncheckedIOException("No pack.yml file found in " + folder.getAbsolutePath(), e);
}
}), platform);
}
@@ -141,12 +142,12 @@ public class ConfigPackImpl implements ConfigPack {
if(entry.getName().equals("pack.yml")) pack = entry;
}
if(pack == null) throw new LoadException("No pack.yml file found in " + file.getName());
if(pack == null) throw new IllegalArgumentException("No pack.yml file found in " + file.getName());
try {
return new YamlConfiguration(file.getInputStream(pack), "pack.yml");
} catch(IOException e) {
throw new LoadException("Unable to load pack.yml from ZIP file", e);
throw new UncheckedIOException("Unable to load pack.yml from ZIP file", e);
}
}), platform);
}

View File

@@ -18,9 +18,14 @@
package com.dfsek.terra.config.preprocessor;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.depth.IndexLevel;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.preprocessor.Result;
import com.dfsek.terra.api.util.generic.pair.Pair;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
@@ -28,6 +33,7 @@ import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.dfsek.terra.api.config.meta.Meta;
@@ -40,7 +46,7 @@ public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
@SuppressWarnings("unchecked")
@Override
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation, DepthTracker depthTracker) {
if(t.getType() instanceof ParameterizedType parameterizedType) {
if(parameterizedType.getRawType() instanceof Class<?> baseClass) { // Should always be true but we check anyways
@@ -58,21 +64,40 @@ public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
if(!s.startsWith("<< ")) continue;
String meta = s.substring(3);
Object metaValue = getMetaValue(meta);
Pair<Configuration, Object> pair = getMetaValue(meta, depthTracker);
Object metaValue = pair.getRight();
if(!(metaValue instanceof List)) {
throw new LoadException(
"MetaList/Set injection candidate must be list, is type " + metaValue.getClass().getCanonicalName());
"MetaList/Set injection candidate must be list, is type " + metaValue.getClass().getCanonicalName(), depthTracker);
}
List<Object> metaList = (List<Object>) metaValue;
newList.remove(i + offset); // Remove placeholder
newList.addAll(i + offset, metaList); // Add metalist values where placeholder was
int begin = i + offset;
offset += metaList.size() - 1; // add metalist size to offset, subtract one to account for placeholder.
int end = i + offset;
depthTracker.addIntrinsicLevel(level -> {
if(level instanceof IndexLevel indexLevel &&
indexLevel.getIndex() >= begin &&
indexLevel.getIndex() < end) {
String configName;
if(pair.getLeft().getName() == null) {
configName = "Anonymous Configuration";
} else {
configName = pair.getLeft().getName();
}
return Optional.of("From configuration \"" + configName + "\"");
}
return Optional.empty();
});
}
return (Result<T>) Result.overwrite(newList);
return (Result<T>) Result.overwrite(newList, depthTracker);
}
}
}

View File

@@ -18,9 +18,14 @@
package com.dfsek.terra.config.preprocessor;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.depth.EntryLevel;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.preprocessor.Result;
import com.dfsek.terra.api.util.generic.pair.Pair;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
@@ -28,6 +33,7 @@ import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.reflection.TypeKey;
@@ -43,7 +49,7 @@ public class MetaMapPreprocessor extends MetaPreprocessor<Meta> {
@SuppressWarnings("unchecked")
@Override
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation, DepthTracker depthTracker) {
if(t.getType() instanceof ParameterizedType parameterizedType) {
if(parameterizedType.getRawType() instanceof Class<?> baseClass) { // Should always be true but we check anyways
@@ -53,18 +59,33 @@ public class MetaMapPreprocessor extends MetaPreprocessor<Meta> {
if(map.containsKey("<<")) {
Map<Object, Object> newMap = new HashMap<>(map);
List<String> keys = (List<String>) loader.loadType(STRING_LIST.getAnnotatedType(), map.get("<<"));
List<String> keys = (List<String>) loader.loadType(STRING_LIST.getAnnotatedType(), map.get("<<"), depthTracker);
keys.forEach(key -> {
Object meta = getMetaValue(key);
Pair<Configuration, Object> pair = getMetaValue(key, depthTracker);
Object meta = pair.getRight();
if(!(meta instanceof Map)) {
throw new LoadException(
"MetaMap injection candidate must be list, is type " + meta.getClass().getCanonicalName());
"MetaMap injection candidate must be list, is type " + meta.getClass().getCanonicalName(), depthTracker);
}
newMap.putAll((Map<?, ?>) meta);
String configName;
if(pair.getLeft().getName() == null) {
configName = "Anonymous Configuration";
} else {
configName = pair.getLeft().getName();
}
depthTracker.addIntrinsicLevel(level -> {
if(level instanceof EntryLevel entryLevel && ((Map<?, ?>) meta).containsKey(entryLevel.getName())) {
return Optional.of("From configuration \"" + configName + "\"");
}
return Optional.empty();
});
});
newMap.putAll(map);
newMap.remove("<<"); // Remove placeholder
return (Result<T>) Result.overwrite(newMap);
return (Result<T>) Result.overwrite(newMap, depthTracker);
}
}
}

View File

@@ -20,6 +20,7 @@ package com.dfsek.terra.config.preprocessor;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.preprocessor.Result;
@@ -51,13 +52,13 @@ public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
@SuppressWarnings("unchecked")
@Override
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation, DepthTracker depthTracker) {
if(t.getType() instanceof Class && isNumber((Class<?>) t.getType()) && c instanceof String) {
String expression = (String) loader.loadType(META_STRING_KEY.getAnnotatedType(), c);
String expression = (String) loader.loadType(META_STRING_KEY.getAnnotatedType(), c, depthTracker);
try {
return (Result<T>) Result.overwrite(new Parser().parse(expression).evaluate());
return (Result<T>) Result.overwrite(new Parser().parse(expression).evaluate(), depthTracker);
} catch(ParseException e) {
throw new LoadException("Invalid expression: ", e);
throw new LoadException("Invalid expression: ", e, depthTracker);
}
}
return Result.noOp();

View File

@@ -18,9 +18,12 @@
package com.dfsek.terra.config.preprocessor;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.preprocessor.ValuePreprocessor;
import com.dfsek.terra.api.util.generic.pair.Pair;
import java.lang.annotation.Annotation;
import java.util.Map;
@@ -32,19 +35,19 @@ public abstract class MetaPreprocessor<A extends Annotation> implements ValuePre
this.configs = configs;
}
protected Object getMetaValue(String meta) {
protected Pair<Configuration, Object> getMetaValue(String meta, DepthTracker depthTracker) {
int sep = meta.indexOf(':');
String file = meta.substring(0, sep);
String key = meta.substring(sep + 1);
if(!configs.containsKey(file)) throw new LoadException("Cannot fetch metavalue: No such config: " + file);
if(!configs.containsKey(file)) throw new LoadException("Cannot fetch metavalue: No such config: " + file, depthTracker);
Configuration config = configs.get(file);
if(!config.contains(key)) {
throw new LoadException("Cannot fetch metavalue: No such key " + key + " in configuration " + config.getName());
throw new LoadException("Cannot fetch metavalue: No such key " + key + " in configuration " + config.getName(), depthTracker);
}
return config.get(key);
return Pair.of(config, config.get(key));
}
}

View File

@@ -18,6 +18,7 @@
package com.dfsek.terra.config.preprocessor;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.preprocessor.Result;
@@ -37,17 +38,17 @@ public class MetaStringPreprocessor extends MetaPreprocessor<Meta> {
@SuppressWarnings("unchecked")
@Override
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation, DepthTracker depthTracker) {
if(String.class.equals(t.getType()) && c instanceof String candidate) { // String is final so we use #equals
StringSubstitutor substitutor = new StringSubstitutor(key -> {
Object meta = getMetaValue(key);
Object meta = getMetaValue(key, depthTracker).getRight();
if(!(meta instanceof String) && !(meta instanceof Number) && !(meta instanceof Character) && !(meta instanceof Boolean)) {
throw new LoadException("MetaString template injection candidate must be string or primitive, is type " +
meta.getClass().getCanonicalName());
meta.getClass().getCanonicalName(), depthTracker);
}
return meta.toString();
});
return (Result<T>) Result.overwrite(substitutor.replace(candidate));
return (Result<T>) Result.overwrite(substitutor.replace(candidate), depthTracker);
}
return Result.noOp();
}

View File

@@ -18,8 +18,12 @@
package com.dfsek.terra.config.preprocessor;
import com.dfsek.tectonic.api.config.Configuration;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.preprocessor.Result;
import com.dfsek.terra.api.util.generic.pair.Pair;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
@@ -36,11 +40,20 @@ public class MetaValuePreprocessor extends MetaPreprocessor<Meta> {
@SuppressWarnings("unchecked")
@Override
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader configLoader, Meta annotation) {
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader configLoader, Meta annotation, DepthTracker depthTracker) {
if(c instanceof String) { // Can we do standard metaconfig?
String value = ((String) c).trim();
if(value.startsWith("$")) { // it's a meta value.
return (Result<T>) Result.overwrite(getMetaValue(value.substring(1)));
Pair<Configuration, Object> pair = getMetaValue(value.substring(1), depthTracker);
String configName;
if(pair.getLeft().getName() == null) {
configName = "Anonymous Configuration";
} else {
configName = pair.getLeft().getName();
}
return (Result<T>) Result.overwrite(pair.getRight(), depthTracker.intrinsic("From configuration \"" + configName + "\""));
}
}
return Result.noOp();

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
@@ -102,7 +103,7 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
}
@Override
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
return registry.load(t, c, loader);
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
return registry.load(t, c, loader, depthTracker);
}
}

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
@@ -89,7 +90,7 @@ public class LockedRegistryImpl<T> implements Registry<T> {
}
@Override
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
return registry.load(t, c, loader);
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) throws LoadException {
return registry.load(t, c, loader, depthTracker);
}
}

View File

@@ -17,6 +17,7 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
@@ -65,10 +66,10 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
}
@Override
public T load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader) throws LoadException {
public T load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException {
return getByID((String) o).orElseThrow(() -> new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o +
"\" was found in this registry. Registry contains items: " +
getItemsFormatted()));
getItemsFormatted(), depthTracker));
}
private String getItemsFormatted() {

View File

@@ -1,5 +1,6 @@
package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
@@ -34,15 +35,15 @@ public class ShortcutHolder<T> implements TypeLoader<T> {
}
@Override
public T load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader) throws LoadException {
public T load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException {
String id = (String) o;
if(id.contains(":")) {
String shortcut = id.substring(0, id.indexOf(":"));
if(shortcuts.containsKey(shortcut)) {
return shortcuts.get(shortcut).load(configLoader, id.substring(id.indexOf(":") + 1));
return shortcuts.get(shortcut).load(configLoader, id.substring(id.indexOf(":") + 1), depthTracker.intrinsic("Using shortcut \"" + shortcut + "\""));
}
throw new LoadException("Shortcut \"" + shortcut + "\" is not defined.");
throw new LoadException("Shortcut \"" + shortcut + "\" is not defined.", depthTracker);
}
return back.load(annotatedType, o, configLoader);
return back.load(annotatedType, o, configLoader, depthTracker);
}
}

View File

@@ -18,6 +18,7 @@
package com.dfsek.terra.bukkit;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
@@ -85,14 +86,14 @@ public class PlatformImpl extends AbstractPlatform {
@Override
public void register(TypeRegistry registry) {
super.register(registry);
registry.registerLoader(BlockState.class, (t, o, l) -> handle.createBlockState((String) o))
.registerLoader(PlatformBiome.class, (t, o, l) -> parseBiome((String) o))
.registerLoader(EntityType.class, (t, o, l) -> EntityType.valueOf((String) o));
registry.registerLoader(BlockState.class, (type, o, loader, depthTracker) -> handle.createBlockState((String) o))
.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
.registerLoader(EntityType.class, (type, o, loader, depthTracker) -> EntityType.valueOf((String) o));
}
private BukkitPlatformBiome parseBiome(String id) throws LoadException {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id);
private BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
return new BukkitPlatformBiome(org.bukkit.block.Biome.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
}
}

View File

@@ -51,7 +51,7 @@ public class BukkitWorldHandle implements WorldHandle {
@Override
public @NotNull EntityType getEntity(@NotNull String id) {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid entity identifier " + id);
if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id);
return new BukkitEntityType(org.bukkit.entity.EntityType.valueOf(id.toUpperCase(Locale.ROOT).substring(10)));
}

View File

@@ -60,6 +60,6 @@ public class CLIPlatform extends AbstractPlatform {
@Override
public void register(TypeRegistry registry) {
super.register(registry);
registry.registerLoader(PlatformBiome.class, (TypeLoader<PlatformBiome>) (annotatedType, o, configLoader) -> () -> o);
registry.registerLoader(PlatformBiome.class, (TypeLoader<PlatformBiome>) (annotatedType, o, configLoader, depthTracker) -> () -> o);
}
}

View File

@@ -21,6 +21,7 @@ import ca.solostudios.strata.Versions;
import ca.solostudios.strata.parser.tokenizer.ParseException;
import ca.solostudios.strata.version.Version;
import com.dfsek.tectonic.api.TypeRegistry;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.MinecraftVersion;
@@ -137,19 +138,19 @@ public class PlatformImpl extends AbstractPlatform {
@Override
public void register(TypeRegistry registry) {
super.register(registry);
registry.registerLoader(PlatformBiome.class, (t, o, l) -> parseBiome((String) o))
.registerLoader(Identifier.class, (t, o, l) -> {
registry.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker))
.registerLoader(Identifier.class, (type, o, loader, depthTracker) -> {
Identifier identifier = Identifier.tryParse((String) o);
if(identifier == null)
throw new LoadException("Invalid identifier: " + o);
throw new LoadException("Invalid identifier: " + o, depthTracker);
return identifier;
});
}
private ProtoPlatformBiome parseBiome(String id) throws LoadException {
private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException {
Identifier identifier = Identifier.tryParse(id);
if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier); // failure.
if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier, tracker); // failure.
return new ProtoPlatformBiome(identifier);
}
}