implement namespaced registries

This commit is contained in:
dfsek
2021-12-25 01:01:32 -07:00
parent bb87bfa1de
commit 8467a19781
44 changed files with 427 additions and 235 deletions

View File

@@ -41,7 +41,7 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register("IMAGE", () -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
providerRegistry.register(addon.getKey("IMAGE"), () -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
})
.failThrough();
}

View File

@@ -60,22 +60,22 @@ public class BiomePipelineAddon implements AddonInitializer {
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register("PIPELINE", BiomePipelineTemplate::new);
providerRegistry.register(addon.getKey("PIPELINE"), BiomePipelineTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(
SOURCE_REGISTRY_KEY);
sourceRegistry.register("SAMPLER", SamplerSourceTemplate::new);
sourceRegistry.register(addon.getKey("SAMPLER"), SamplerSourceTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
STAGE_REGISTRY_KEY);
stageRegistry.register("FRACTAL_EXPAND", ExpanderStageTemplate::new);
stageRegistry.register("SMOOTH", SmoothMutatorTemplate::new);
stageRegistry.register("REPLACE", ReplaceMutatorTemplate::new);
stageRegistry.register("REPLACE_LIST", ReplaceListMutatorTemplate::new);
stageRegistry.register("BORDER", BorderMutatorTemplate::new);
stageRegistry.register("BORDER_LIST", BorderListMutatorTemplate::new);
stageRegistry.register(addon.getKey("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
stageRegistry.register(addon.getKey("SMOOTH"), SmoothMutatorTemplate::new);
stageRegistry.register(addon.getKey("REPLACE"), ReplaceMutatorTemplate::new);
stageRegistry.register(addon.getKey("REPLACE_LIST"), ReplaceListMutatorTemplate::new);
stageRegistry.register(addon.getKey("BORDER"), BorderMutatorTemplate::new);
stageRegistry.register(addon.getKey("BORDER_LIST"), BorderListMutatorTemplate::new);
})
.failThrough();
platform.getEventManager()

View File

@@ -3,6 +3,9 @@ package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.terra.api.registry.key.RegistryKey;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
@@ -23,7 +26,7 @@ public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> {
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
if(c.equals("SELF")) return BiomeDelegate.self();
return biomeRegistry
.get((String) c)
.tryGet((String) c)
.map(BiomeDelegate::from)
.orElseGet(() -> BiomeDelegate.ephemeral((String) c));
}

View File

@@ -40,7 +40,7 @@ public class SingleBiomeProviderAddon implements AddonInitializer {
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register("SINGLE", SingleBiomeProviderTemplate::new);
providerRegistry.register(addon.getKey("SINGLE"), SingleBiomeProviderTemplate::new);
})
.failThrough();
}

View File

@@ -40,7 +40,7 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
event.getPack()
.getOrCreateRegistry(ChunkGeneratorProvider.class)
.register("NOISE_3D",
.register(addon.getKey("NOISE_3D"),
pack -> new NoiseChunkGenerator3D(pack, platform, config.getElevationBlend(), config.getHorizontalRes(),
config.getVerticalRes()));
event.getPack()

View File

@@ -30,7 +30,7 @@ public class BiomeAddon implements AddonInitializer {
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5);
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), addon.getKey("BIOME"), 5);
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader());
})
.failThrough();

View File

@@ -47,12 +47,12 @@ public class DistributorAddon implements AddonInitializer {
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Distributor>>> distributorRegistry = event.getPack().getOrCreateRegistry(
DISTRIBUTOR_TOKEN);
distributorRegistry.register("SAMPLER", SamplerDistributorTemplate::new);
distributorRegistry.register("POINTS", PointSetDistributorTemplate::new);
distributorRegistry.register("AND", AndDistributorTemplate::new);
distributorRegistry.register("OR", OrDistributorTemplate::new);
distributorRegistry.register("YES", YesDistributorTemplate::new);
distributorRegistry.register("NO", NoDistributorTemplate::new);
distributorRegistry.register(addon.getKey("SAMPLER"), SamplerDistributorTemplate::new);
distributorRegistry.register(addon.getKey("POINTS"), PointSetDistributorTemplate::new);
distributorRegistry.register(addon.getKey("AND"), AndDistributorTemplate::new);
distributorRegistry.register(addon.getKey("OR"), OrDistributorTemplate::new);
distributorRegistry.register(addon.getKey("YES"), YesDistributorTemplate::new);
distributorRegistry.register(addon.getKey("NO"), NoDistributorTemplate::new);
event.getPack()
.applyLoader(Point.class, PointTemplate::new);

View File

@@ -27,7 +27,7 @@ public class FeatureAddon implements AddonInitializer {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack().registerConfigType(new FeatureConfigType(), "FEATURE", 3))
.then(event -> event.getPack().registerConfigType(new FeatureConfigType(), addon.getKey("FEATURE"), 3))
.failThrough();
}
}

View File

@@ -30,7 +30,7 @@ public class FloraAddon implements AddonInitializer {
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
event.getPack().registerConfigType(new FloraConfigType(), "FLORA", 2);
event.getPack().registerConfigType(new FloraConfigType(), addon.getKey("FLORA"), 2);
event.getPack().applyLoader(BlockLayer.class, BlockLayerTemplate::new);
})
.failThrough();

View File

@@ -57,29 +57,29 @@ public class LocatorAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Locator>>> locatorRegistry = event.getPack().getOrCreateRegistry(LOCATOR_TOKEN);
locatorRegistry.register("SURFACE", () -> new SurfaceLocatorTemplate(platform));
locatorRegistry.register(addon.getKey("SURFACE"), () -> new SurfaceLocatorTemplate(platform));
locatorRegistry.register("RANDOM", RandomLocatorTemplate::new);
locatorRegistry.register("GAUSSIAN_RANDOM", GaussianRandomLocatorTemplate::new);
locatorRegistry.register(addon.getKey("RANDOM"), RandomLocatorTemplate::new);
locatorRegistry.register(addon.getKey("GAUSSIAN_RANDOM"), GaussianRandomLocatorTemplate::new);
locatorRegistry.register("PATTERN", PatternLocatorTemplate::new);
locatorRegistry.register(addon.getKey("PATTERN"), PatternLocatorTemplate::new);
locatorRegistry.register("SAMPLER", SamplerLocatorTemplate::new);
locatorRegistry.register("SAMPLER_3D", Sampler3DLocatorTemplate::new);
locatorRegistry.register(addon.getKey("SAMPLER"), SamplerLocatorTemplate::new);
locatorRegistry.register(addon.getKey("SAMPLER_3D"), Sampler3DLocatorTemplate::new);
locatorRegistry.register("AND", AndLocatorTemplate::new);
locatorRegistry.register("OR", OrLocatorTemplate::new);
locatorRegistry.register(addon.getKey("AND"), AndLocatorTemplate::new);
locatorRegistry.register(addon.getKey("OR"), OrLocatorTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Pattern>>> patternRegistry = event.getPack().getOrCreateRegistry(PATTERN_TOKEN);
patternRegistry.register("MATCH_AIR", AirMatchPatternTemplate::new);
patternRegistry.register("MATCH_SOLID", SolidMatchPatternTemplate::new);
patternRegistry.register("MATCH", SingleBlockMatchPatternTemplate::new);
patternRegistry.register("MATCH_SET", BlockSetMatchPatternTemplate::new);
patternRegistry.register(addon.getKey("MATCH_AIR"), AirMatchPatternTemplate::new);
patternRegistry.register(addon.getKey("MATCH_SOLID"), SolidMatchPatternTemplate::new);
patternRegistry.register(addon.getKey("MATCH"), SingleBlockMatchPatternTemplate::new);
patternRegistry.register(addon.getKey("MATCH_SET"), BlockSetMatchPatternTemplate::new);
patternRegistry.register("AND", AndPatternTemplate::new);
patternRegistry.register("OR", OrPatternTemplate::new);
patternRegistry.register("NOT", NotPatternTemplate::new);
patternRegistry.register(addon.getKey("AND"), AndPatternTemplate::new);
patternRegistry.register(addon.getKey("OR"), OrPatternTemplate::new);
patternRegistry.register(addon.getKey("NOT"), NotPatternTemplate::new);
})
.failThrough();
}

View File

@@ -84,54 +84,54 @@ public class NoiseAddon implements AddonInitializer {
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
.applyLoader(FunctionTemplate.class, FunctionTemplate::new);
noiseRegistry.register("LINEAR", LinearNormalizerTemplate::new);
noiseRegistry.register("NORMAL", NormalNormalizerTemplate::new);
noiseRegistry.register("CLAMP", ClampNormalizerTemplate::new);
noiseRegistry.register("PROBABILITY", ProbabilityNormalizerTemplate::new);
noiseRegistry.register("SCALE", ScaleNormalizerTemplate::new);
noiseRegistry.register(addon.getKey("LINEAR"), LinearNormalizerTemplate::new);
noiseRegistry.register(addon.getKey("NORMAL"), NormalNormalizerTemplate::new);
noiseRegistry.register(addon.getKey("CLAMP"), ClampNormalizerTemplate::new);
noiseRegistry.register(addon.getKey("PROBABILITY"), ProbabilityNormalizerTemplate::new);
noiseRegistry.register(addon.getKey("SCALE"), ScaleNormalizerTemplate::new);
noiseRegistry.register("IMAGE", ImageSamplerTemplate::new);
noiseRegistry.register(addon.getKey("IMAGE"), ImageSamplerTemplate::new);
noiseRegistry.register("DOMAIN_WARP", DomainWarpTemplate::new);
noiseRegistry.register(addon.getKey("DOMAIN_WARP"), DomainWarpTemplate::new);
noiseRegistry.register("FBM", BrownianMotionTemplate::new);
noiseRegistry.register("PING_PONG", PingPongTemplate::new);
noiseRegistry.register("RIDGED", RidgedFractalTemplate::new);
noiseRegistry.register(addon.getKey("FBM"), BrownianMotionTemplate::new);
noiseRegistry.register(addon.getKey("PING_PONG"), PingPongTemplate::new);
noiseRegistry.register(addon.getKey("RIDGED"), RidgedFractalTemplate::new);
noiseRegistry.register("OPEN_SIMPLEX_2", () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new));
noiseRegistry.register("OPEN_SIMPLEX_2S", () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new));
noiseRegistry.register("PERLIN", () -> new SimpleNoiseTemplate(PerlinSampler::new));
noiseRegistry.register("SIMPLEX", () -> new SimpleNoiseTemplate(SimplexSampler::new));
noiseRegistry.register("GABOR", GaborNoiseTemplate::new);
noiseRegistry.register(addon.getKey("OPEN_SIMPLEX_2"), () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new));
noiseRegistry.register(addon.getKey("OPEN_SIMPLEX_2S"), () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new));
noiseRegistry.register(addon.getKey("PERLIN"), () -> new SimpleNoiseTemplate(PerlinSampler::new));
noiseRegistry.register(addon.getKey("SIMPLEX"), () -> new SimpleNoiseTemplate(SimplexSampler::new));
noiseRegistry.register(addon.getKey("GABOR"), GaborNoiseTemplate::new);
noiseRegistry.register("VALUE", () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register("VALUE_CUBIC", () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
noiseRegistry.register(addon.getKey("VALUE"), () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register(addon.getKey("VALUE_CUBIC"), () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
noiseRegistry.register("CELLULAR", CellularNoiseTemplate::new);
noiseRegistry.register(addon.getKey("CELLULAR"), CellularNoiseTemplate::new);
noiseRegistry.register("WHITE_NOISE", () -> new SimpleNoiseTemplate(WhiteNoiseSampler::new));
noiseRegistry.register("POSITIVE_WHITE_NOISE", () -> new SimpleNoiseTemplate(PositiveWhiteNoiseSampler::new));
noiseRegistry.register("GAUSSIAN", () -> new SimpleNoiseTemplate(GaussianNoiseSampler::new));
noiseRegistry.register(addon.getKey("WHITE_NOISE"), () -> new SimpleNoiseTemplate(WhiteNoiseSampler::new));
noiseRegistry.register(addon.getKey("POSITIVE_WHITE_NOISE"), () -> new SimpleNoiseTemplate(PositiveWhiteNoiseSampler::new));
noiseRegistry.register(addon.getKey("GAUSSIAN"), () -> new SimpleNoiseTemplate(GaussianNoiseSampler::new));
noiseRegistry.register("CONSTANT", ConstantNoiseTemplate::new);
noiseRegistry.register(addon.getKey("CONSTANT"), ConstantNoiseTemplate::new);
noiseRegistry.register("KERNEL", KernelTemplate::new);
noiseRegistry.register(addon.getKey("KERNEL"), KernelTemplate::new);
noiseRegistry.register("LINEAR_HEIGHTMAP", LinearHeightmapSamplerTemplate::new);
noiseRegistry.register(addon.getKey("LINEAR_HEIGHTMAP"), LinearHeightmapSamplerTemplate::new);
noiseRegistry.register("ADD", () -> new BinaryArithmeticTemplate<>(AdditionSampler::new));
noiseRegistry.register("SUB", () -> new BinaryArithmeticTemplate<>(SubtractionSampler::new));
noiseRegistry.register("MUL", () -> new BinaryArithmeticTemplate<>(MultiplicationSampler::new));
noiseRegistry.register("DIV", () -> new BinaryArithmeticTemplate<>(DivisionSampler::new));
noiseRegistry.register("MAX", () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
noiseRegistry.register("MIN", () -> new BinaryArithmeticTemplate<>(MinSampler::new));
noiseRegistry.register(addon.getKey("ADD"), () -> new BinaryArithmeticTemplate<>(AdditionSampler::new));
noiseRegistry.register(addon.getKey("SUB"), () -> new BinaryArithmeticTemplate<>(SubtractionSampler::new));
noiseRegistry.register(addon.getKey("MUL"), () -> new BinaryArithmeticTemplate<>(MultiplicationSampler::new));
noiseRegistry.register(addon.getKey("DIV"), () -> new BinaryArithmeticTemplate<>(DivisionSampler::new));
noiseRegistry.register(addon.getKey("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
noiseRegistry.register(addon.getKey("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register("EXPRESSION", () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
noiseRegistry.register(addon.getKey("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());

View File

@@ -27,7 +27,7 @@ public class OreAddon implements AddonInitializer {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack().registerConfigType(new OreConfigType(), "ORE", 1))
.then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.getKey("ORE"), 1))
.failThrough();
}
}

View File

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

View File

@@ -27,7 +27,7 @@ public class StructureAddon implements AddonInitializer {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack().registerConfigType(new StructureConfigType(), "STRUCTURE", 2))
.then(event -> event.getPack().registerConfigType(new StructureConfigType(), addon.getKey("STRUCTURE"), 2))
.failThrough();
}
}

View File

@@ -54,7 +54,7 @@ public class FeatureGenerationAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack()
.getOrCreateRegistry(STAGE_TYPE_KEY)
.register("FEATURE", () -> new FeatureStageTemplate(platform)))
.register(addon.getKey("FEATURE"), () -> new FeatureStageTemplate(platform)))
.failThrough();
platform.getEventManager()

View File

@@ -26,7 +26,7 @@ public class StructureGenerationAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack()
.getOrCreateRegistry(GenerationStageProvider.class)
.register("STRUCTURE", pack -> new StructureGenerationStage(platform)))
.register(addon.getKey("STRUCTURE"), pack -> new StructureGenerationStage(platform)))
.failThrough();
platform.getEventManager()

View File

@@ -60,7 +60,7 @@ public class SpongeSchematicAddon implements AddonInitializer {
event.getPack().getLoader().open("", ".schem").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) {
String id = StringUtil.fileName(entry.getKey());
structureRegistry.register(id, convert(entry.getValue(), id));
structureRegistry.register(addon.getKey(id), convert(entry.getValue(), id));
}
}).close();
})

View File

@@ -62,7 +62,7 @@ public class TerraScriptAddon implements AddonInitializer {
}
})
.toList()
.forEach(structureScript -> structureRegistry.register(structureScript.getID(),
.forEach(structureScript -> structureRegistry.register(addon.getKey(structureScript.getID()),
structureScript)))
.close();
})

View File

@@ -66,8 +66,9 @@ public class StructureScript implements Structure {
throw new RuntimeException(e);
}
this.id = id;
functionRegistry.forEach(parser::registerFunction); // Register registry functions.
//noinspection unchecked
functionRegistry.forEach((key, function) -> parser.registerFunction(key.getID(), function)); // Register registry functions.
parser
.registerFunction("block", new BlockFunctionBuilder(platform))

View File

@@ -11,6 +11,7 @@ import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.entity.Container;
import com.dfsek.terra.api.event.events.world.generation.LootPopulateEvent;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.util.vector.Vector3;
import net.jafama.FastMath;
@@ -66,7 +67,7 @@ public class LootFunction implements Function<Void> {
String id = data.apply(implementationArguments, variableMap);
registry.get(id)
registry.get(RegistryKey.parse(id))
.ifPresentOrElse(table -> {
Vector3 apply = Vector3.of(FastMath.roundToInt(xz.getX()),
y.apply(implementationArguments, variableMap)

View File

@@ -9,10 +9,13 @@ package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.script.StructureScript;
import com.dfsek.terra.api.registry.key.RegistryKey;
import net.jafama.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -68,7 +71,7 @@ public class StructureFunction implements Function<Boolean> {
String app = id.apply(implementationArguments, variableMap);
return registry.get(app).map(script -> {
return registry.tryGet(app).map(script -> {
Rotation rotation1;
String rotString = rotations.get(arguments.getRandom().nextInt(rotations.size())).apply(implementationArguments, variableMap);
try {

View File

@@ -23,7 +23,7 @@ public class TerraScriptCheckFunctionAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.priority(1)
.then(event -> {
event.getPack().getOrCreateRegistry(FunctionBuilder.class).register("check", new CheckFunctionBuilder(platform));
event.getPack().getOrCreateRegistry(FunctionBuilder.class).register(addon.getKey("check"), new CheckFunctionBuilder(platform));
})
.failThrough();
}

View File

@@ -10,6 +10,8 @@ import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.registry.exception.NoSuchEntryException;
import com.dfsek.terra.api.registry.key.RegistryKey;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -92,12 +94,12 @@ public class RegistryArgument<T, R> extends CommandArgument<T, R> {
public @NonNull ArgumentParseResult<@NonNull R> parse(@NonNull CommandContext<@NonNull T> commandContext,
@NonNull Queue<@NonNull String> inputQueue) {
String input = inputQueue.remove();
return registry.get(input).map(ArgumentParseResult::success).orElse(ArgumentParseResult.failure(new NoSuchEntryException("No such entry: " + input)));
return registry.get(RegistryKey.parse(input)).map(ArgumentParseResult::success).orElse(ArgumentParseResult.failure(new NoSuchEntryException("No such entry: " + input)));
}
@Override
public @NonNull List<@NonNull String> suggestions(@NonNull CommandContext<T> commandContext, @NonNull String input) {
return registry.keys().stream().sorted().collect(Collectors.toList());
return registry.keys().stream().map(RegistryKey::toString).sorted().collect(Collectors.toList());
}
}
}

View File

@@ -15,7 +15,9 @@ import java.util.Map;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.key.Keyed;
import com.dfsek.terra.api.registry.key.Namespaced;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.registry.meta.RegistryHolder;
import com.dfsek.terra.api.tectonic.ConfigLoadingDelegate;
import com.dfsek.terra.api.tectonic.LoaderRegistrar;
@@ -27,9 +29,9 @@ import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;
public interface ConfigPack extends LoaderRegistrar, ConfigLoadingDelegate, RegistryHolder, StringIdentifiable, Namespaced {
public interface ConfigPack extends LoaderRegistrar, ConfigLoadingDelegate, RegistryHolder, Keyed {
ConfigPack registerConfigType(ConfigType<?, ?> type, String id, int priority);
ConfigPack registerConfigType(ConfigType<?, ?> type, RegistryKey id, int priority);
Map<BaseAddon, VersionRange> addons();

View File

@@ -7,6 +7,8 @@
package com.dfsek.terra.api.registry;
import com.dfsek.terra.api.registry.key.RegistryKey;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
@@ -21,5 +23,5 @@ public interface CheckedRegistry<T> extends Registry<T> {
*
* @throws DuplicateEntryException If an entry with the same identifier is already present.
*/
void register(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException;
void register(@NotNull RegistryKey identifier, @NotNull T value) throws DuplicateEntryException;
}

View File

@@ -7,6 +7,8 @@
package com.dfsek.terra.api.registry;
import com.dfsek.terra.api.registry.key.RegistryKey;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
@@ -19,7 +21,7 @@ public interface OpenRegistry<T> extends Registry<T> {
* @param identifier Identifier to assign value.
* @param value Value to register.
*/
boolean register(@NotNull String identifier, @NotNull T value);
boolean register(@NotNull RegistryKey identifier, @NotNull T value);
/**
* Add a value to this registry, checking whether it is present first.
@@ -29,7 +31,7 @@ public interface OpenRegistry<T> extends Registry<T> {
*
* @throws DuplicateEntryException If an entry with the same identifier is already present.
*/
void registerChecked(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException;
void registerChecked(@NotNull RegistryKey identifier, @NotNull T value) throws DuplicateEntryException;
/**
* Clears all entries from the registry.

View File

@@ -9,39 +9,41 @@ package com.dfsek.terra.api.registry;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.google.common.reflect.TypeToken;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
public interface Registry<T> extends TypeLoader<T> {
/**
* Get a value from the registry.
*
* @param identifier Identifier of value.
* @param key Identifier of value.
*
* @return Value matching the identifier, {@code null} if no value is present.
*/
@Contract(pure = true)
Optional<T> get(@NotNull String identifier);
Optional<T> get(@NotNull RegistryKey key);
/**
* Check if the registry contains a value.
*
* @param identifier Identifier of value.
* @param key Identifier of value.
*
* @return Whether the registry contains the value.
*/
@Contract(pure = true)
boolean contains(@NotNull String identifier);
boolean contains(@NotNull RegistryKey key);
/**
* Perform the given action for every value in the registry.
@@ -55,7 +57,7 @@ public interface Registry<T> extends TypeLoader<T> {
*
* @param consumer Action to perform on pair.
*/
void forEach(@NotNull BiConsumer<String, T> consumer);
void forEach(@NotNull BiConsumer<RegistryKey, T> consumer);
/**
* Get the entries of this registry as a {@link Set}.
@@ -73,7 +75,30 @@ public interface Registry<T> extends TypeLoader<T> {
*/
@NotNull
@Contract(pure = true)
Set<String> keys();
Set<RegistryKey> keys();
TypeKey<T> getType();
default Optional<T> tryGet(String attempt) {
return get(attempt, map -> {
if(map.isEmpty()) return Optional.empty();
if(map.size() == 1) {
return map.values().stream().findFirst(); // only one value.
}
throw new IllegalArgumentException("ID \"" + attempt + "\" is ambiguous; matches: " + map
.keySet()
.stream()
.map(RegistryKey::toString)
.reduce("", (a, b) -> a + "\n - " + b));
});
}
Map<RegistryKey, T> get(String id);
default Optional<T> get(String attempt, Function<Map<RegistryKey, T>, Optional<T>> reduction) {
if(attempt.contains(":")) {
return get(RegistryKey.parse(attempt));
}
return reduction.apply(get(attempt));
}
}

View File

@@ -0,0 +1,15 @@
package com.dfsek.terra.api.registry.key;
public interface Keyed extends Namespaced, StringIdentifiable {
RegistryKey getRegistryKey();
@Override
default String getNamespace() {
return getRegistryKey().getNamespace();
}
@Override
default String getID() {
return getRegistryKey().getID();
}
}

View File

@@ -3,17 +3,7 @@ package com.dfsek.terra.api.registry.key;
public interface Namespaced {
String getNamespace();
default RegistryKey getKey(String key) {
return new RegistryKey() {
@Override
public String getNamespace() {
return Namespaced.this.getNamespace();
}
@Override
public String getID() {
return key;
}
};
default RegistryKey getKey(String id) {
return RegistryKey.of(getNamespace(), id);
}
}

View File

@@ -1,5 +1,70 @@
package com.dfsek.terra.api.registry.key;
public interface RegistryKey extends StringIdentifiable, Namespaced {
import java.util.Objects;
import java.util.regex.Pattern;
public final class RegistryKey implements StringIdentifiable, Namespaced {
private static final Pattern ID_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]*$");
private final String namespace;
private final String id;
private RegistryKey(String namespace, String id) {
if(!ID_PATTERN.matcher(namespace).matches()) {
throw new IllegalArgumentException(
"Namespace must only contain alphanumeric characters, hyphens, and underscores. \"" + namespace +
"\" is not a valid namespace.");
}
if(!ID_PATTERN.matcher(id).matches()) {
throw new IllegalArgumentException(
"ID must only contain alphanumeric characters, hyphens, and underscores. \"" + id +
"\" is not a valid ID.");
}
this.namespace = namespace;
this.id = id;
}
public static RegistryKey parse(String key) {
if(key.chars().filter(c -> c == ':').count() != 1) {
throw new IllegalArgumentException("Malformed RegistryKey: " + key);
}
String namespace = key.substring(0, key.indexOf(":"));
String id = key.substring(key.indexOf(":") + 1);
return new RegistryKey(namespace, id);
}
public static RegistryKey of(String namespace, String id) {
return new RegistryKey(namespace, id);
}
@Override
public String getNamespace() {
return namespace;
}
@Override
public String getID() {
return id;
}
@Override
public int hashCode() {
return Objects.hash(namespace, id);
}
@Override
public boolean equals(Object obj) {
if(obj instanceof RegistryKey that) {
return this.id.equals(that.id) && this.namespace.equals(that.namespace);
}
return false;
}
@Override
public String toString() {
return namespace + ":" + id;
}
}

View File

@@ -209,7 +209,7 @@ public abstract class AbstractPlatform implements Platform {
platformInjector.inject(addon);
addon.initialize();
if(!(addon instanceof EphemeralAddon)) { // ephemeral addons exist only for version checking
addonRegistry.register(addon.getID(), addon);
addonRegistry.register(addon.getKey(addon.getID()), addon);
}
});

View File

@@ -30,6 +30,8 @@ import java.util.function.Supplier;
import com.dfsek.terra.api.registry.Registry;
import org.jetbrains.annotations.NotNull;
public class GenericTemplateSupplierLoader<T> implements TypeLoader<T> {
private final Registry<Supplier<ObjectTemplate<T>>> registry;
@@ -40,12 +42,11 @@ public class GenericTemplateSupplierLoader<T> implements TypeLoader<T> {
@SuppressWarnings("unchecked")
@Override
public T load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
public T load(@NotNull AnnotatedType t, @NotNull Object c, ConfigLoader loader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) c;
try {
return loader
.load(registry
.get(((String) map.get("type")))
.load(registry.tryGet(((String) map.get("type")))
.orElseThrow(() -> new LoadException("No such entry: " + map.get("type")))
.get(), new MapConfiguration(map)).get();
} catch(ConfigException e) {

View File

@@ -27,6 +27,9 @@ import com.dfsek.tectonic.api.loader.AbstractConfigLoader;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import com.dfsek.tectonic.yaml.YamlConfiguration;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import org.jetbrains.annotations.NotNull;
@@ -115,10 +118,9 @@ public class ConfigPackImpl implements ConfigPack {
private final Map<Type, ShortcutHolder<?>> shortcuts = new HashMap<>();
private final OpenRegistry<ConfigType<?, ?>> configTypeRegistry;
private final TreeMap<Integer, List<Pair<String, ConfigType<?, ?>>>> configTypes = new TreeMap<>();
private final TreeMap<Integer, List<Pair<RegistryKey, ConfigType<?, ?>>>> configTypes = new TreeMap<>();
private final String namespace;
private final String id;
private final RegistryKey key;
public ConfigPackImpl(File folder, Platform platform) {
this(new FolderLoader(folder.toPath()), Construct.construct(() -> {
@@ -175,14 +177,18 @@ public class ConfigPackImpl implements ConfigPack {
selfLoader.load(template, packManifest);
String namespace;
String id;
if(template.getID().contains(":")) {
this.namespace = template.getID().substring(0, template.getID().indexOf(":"));
this.id = template.getID().substring(template.getID().indexOf(":") + 1);
namespace = template.getID().substring(0, template.getID().indexOf(":"));
id = template.getID().substring(template.getID().indexOf(":") + 1);
} else {
this.id = template.getID();
this.namespace = template.getID();
id = template.getID();
namespace = template.getID();
}
this.key = RegistryKey.of(namespace, id);
logger.info("Loading config pack \"{}:{}\"", id, namespace);
configTypes.values().forEach(list -> list.forEach(pair -> configTypeRegistry.register(pair.getLeft(), pair.getRight())));
@@ -214,7 +220,7 @@ public class ConfigPackImpl implements ConfigPack {
return Pair.of(configuration.getID(), loaded);
})
.toList()
.forEach(pair -> registry.register(pair.getLeft(), pair.getRight()));
.forEach(pair -> registry.register(getKey(pair.getLeft()), pair.getRight()));
platform.getEventManager().callEvent(new ConfigTypePostLoadEvent(configType, registry, this));
});
@@ -282,13 +288,13 @@ public class ConfigPackImpl implements ConfigPack {
}
@Override
public ConfigPack registerConfigType(ConfigType<?, ?> type, String id, int priority) {
Set<String> contained = new HashSet<>();
public ConfigPack registerConfigType(ConfigType<?, ?> type, RegistryKey key, int priority) {
Set<RegistryKey> contained = new HashSet<>();
configTypes.forEach((p, configs) -> configs.forEach(pair -> {
if(contained.contains(pair.getLeft())) throw new IllegalArgumentException("Duplicate config ID: " + id);
contained.add(id);
if(contained.contains(pair.getLeft())) throw new IllegalArgumentException("Duplicate config key: " + key);
contained.add(key);
}));
configTypes.computeIfAbsent(priority, p -> new ArrayList<>()).add(Pair.of(id, type));
configTypes.computeIfAbsent(priority, p -> new ArrayList<>()).add(Pair.of(key, type));
return this;
}
@@ -374,7 +380,7 @@ public class ConfigPackImpl implements ConfigPack {
private OpenRegistry<ConfigType<?, ?>> createConfigRegistry() {
return new OpenRegistryImpl<>(new LinkedHashMap<>(), CONFIG_TYPE_TYPE_KEY) {
@Override
public boolean register(@NotNull String identifier, @NotNull ConfigType<?, ?> value) {
public boolean register(@NotNull RegistryKey key, @NotNull ConfigType<?, ?> value) {
if(!registryMap
.containsKey(value.getTypeKey()
.getType())) {
@@ -383,7 +389,7 @@ public class ConfigPackImpl implements ConfigPack {
abstractConfigLoader.registerLoader(value.getTypeKey().getType(), openRegistry);
registryMap.put(value.getTypeKey().getType(), new CheckedRegistryImpl<>(openRegistry));
}
return super.register(identifier, value);
return super.register(key, value);
}
};
}
@@ -411,12 +417,7 @@ public class ConfigPackImpl implements ConfigPack {
}
@Override
public String getID() {
return id;
}
@Override
public String getNamespace() {
return namespace;
public RegistryKey getRegistryKey() {
return key;
}
}

View File

@@ -20,6 +20,7 @@ package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.util.reflection.TypeKey;
import org.jetbrains.annotations.ApiStatus.Internal;
@@ -27,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -55,18 +57,18 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
}
@Override
public void register(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException {
public void register(@NotNull RegistryKey identifier, @NotNull T value) throws DuplicateEntryException {
registry.registerChecked(identifier, value);
}
@Override
public Optional<T> get(@NotNull String identifier) {
return registry.get(identifier);
public Optional<T> get(@NotNull RegistryKey key) {
return registry.get(key);
}
@Override
public boolean contains(@NotNull String identifier) {
return registry.contains(identifier);
public boolean contains(@NotNull RegistryKey key) {
return registry.contains(key);
}
@Override
@@ -75,7 +77,7 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
}
@Override
public void forEach(@NotNull BiConsumer<String, T> consumer) {
public void forEach(@NotNull BiConsumer<RegistryKey, T> consumer) {
registry.forEach(consumer);
}
@@ -85,7 +87,7 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
}
@Override
public @NotNull Set<String> keys() {
public @NotNull Set<RegistryKey> keys() {
return registry.keys();
}
@@ -94,6 +96,11 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
return registry.getType();
}
@Override
public Map<RegistryKey, T> get(String id) {
return registry.get(id);
}
@Override
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
return registry.load(t, c, loader);

View File

@@ -20,12 +20,14 @@ package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.util.reflection.TypeKey;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -47,13 +49,13 @@ public class LockedRegistryImpl<T> implements Registry<T> {
}
@Override
public Optional<T> get(@NotNull String identifier) {
return registry.get(identifier);
public Optional<T> get(@NotNull RegistryKey key) {
return registry.get(key);
}
@Override
public boolean contains(@NotNull String identifier) {
return registry.contains(identifier);
public boolean contains(@NotNull RegistryKey key) {
return registry.contains(key);
}
@Override
@@ -62,7 +64,7 @@ public class LockedRegistryImpl<T> implements Registry<T> {
}
@Override
public void forEach(@NotNull BiConsumer<String, T> consumer) {
public void forEach(@NotNull BiConsumer<RegistryKey, T> consumer) {
registry.forEach(consumer);
}
@@ -72,7 +74,7 @@ public class LockedRegistryImpl<T> implements Registry<T> {
}
@Override
public @NotNull Set<String> keys() {
public @NotNull Set<RegistryKey> keys() {
return registry.keys();
}
@@ -81,6 +83,11 @@ public class LockedRegistryImpl<T> implements Registry<T> {
return registry.getType();
}
@Override
public Map<RegistryKey, T> get(String id) {
return registry.get(id);
}
@Override
public T load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader) throws LoadException {
return registry.load(t, c, loader);

View File

@@ -20,20 +20,25 @@ package com.dfsek.terra.registry;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.dfsek.terra.api.registry.OpenRegistry;
@@ -47,36 +52,45 @@ import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
*/
public class OpenRegistryImpl<T> implements OpenRegistry<T> {
private static final Entry<?> NULL = new Entry<>(null);
private static final Pattern ID_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]*$");
private final Map<String, Entry<T>> objects;
private final Map<RegistryKey, Entry<T>> objects;
private final ListMultimap<String, Pair<RegistryKey, Entry<T>>> objectIDs = Multimaps.newListMultimap(new HashMap<>(), ArrayList::new);
private final TypeKey<T> typeKey;
public OpenRegistryImpl(TypeKey<T> typeKey) {
this(new HashMap<>(), typeKey);
}
protected OpenRegistryImpl(Map<String, Entry<T>> init, TypeKey<T> typeKey) {
protected OpenRegistryImpl(Map<RegistryKey, Entry<T>> init, TypeKey<T> typeKey) {
this.objects = init;
this.typeKey = typeKey;
}
@Override
public T load(@NotNull AnnotatedType type, @NotNull Object o, @NotNull ConfigLoader configLoader) throws LoadException {
return get((String) o).orElseThrow(() -> {
String list = objects.keySet().stream().sorted().reduce("", (a, b) -> a + "\n - " + b);
if(objects.isEmpty()) list = "[ ]";
return new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o +
"\" was found in this registry. Registry contains items: " + list);
});
return tryGet((String) o).orElseThrow(() -> new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o +
"\" was found in this registry. Registry contains items: " +
getItemsFormatted()));
}
private String getItemsFormatted() {
if(objects.isEmpty()) {
return "[ ]";
}
return objects
.keySet()
.stream()
.map(RegistryKey::toString)
.sorted()
.reduce("", (a, b) -> a + "\n - " + b);
}
@Override
public boolean register(@NotNull String identifier, @NotNull T value) {
public boolean register(@NotNull RegistryKey identifier, @NotNull T value) {
return register(identifier, new Entry<>(value));
}
@Override
public void registerChecked(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException {
public void registerChecked(@NotNull RegistryKey identifier, @NotNull T value) throws DuplicateEntryException {
if(objects.containsKey(identifier))
throw new DuplicateEntryException("Value with identifier \"" + identifier + "\" is already defined in registry.");
register(identifier, value);
@@ -87,25 +101,22 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
objects.clear();
}
public boolean register(String identifier, Entry<T> value) {
if(!ID_PATTERN.matcher(identifier).matches())
throw new IllegalArgumentException(
"Registry ID must only contain alphanumeric characters, hyphens, and underscores. \"" + identifier +
"\" is not a valid ID.");
private boolean register(RegistryKey identifier, Entry<T> value) {
boolean exists = objects.containsKey(identifier);
objects.put(identifier, value);
objectIDs.put(identifier.getID(), Pair.of(identifier, value));
return exists;
}
@SuppressWarnings("unchecked")
@Override
public Optional<T> get(@NotNull String identifier) {
return Optional.ofNullable(objects.getOrDefault(identifier, (Entry<T>) NULL).getValue());
public Optional<T> get(@NotNull RegistryKey key) {
return Optional.ofNullable(objects.getOrDefault(key, (Entry<T>) NULL).getValue());
}
@Override
public boolean contains(@NotNull String identifier) {
return objects.containsKey(identifier);
public boolean contains(@NotNull RegistryKey key) {
return objects.containsKey(key);
}
@Override
@@ -114,7 +125,7 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
}
@Override
public void forEach(@NotNull BiConsumer<String, T> consumer) {
public void forEach(@NotNull BiConsumer<RegistryKey, T> consumer) {
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
}
@@ -124,7 +135,7 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
}
@Override
public @NotNull Set<String> keys() {
public @NotNull Set<RegistryKey> keys() {
return objects.keySet();
}
@@ -133,8 +144,16 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
return typeKey;
}
public Map<String, T> getDeadEntries() {
Map<String, T> dead = new HashMap<>();
@Override
public Map<RegistryKey, T> get(String id) {
return objectIDs
.get(id)
.stream()
.collect(HashMap::new, (map, pair) -> map.put(pair.getLeft(), pair.getRight().getValue()), Map::putAll);
}
public Map<RegistryKey, T> getDeadEntries() {
Map<RegistryKey, T> dead = new HashMap<>();
objects.forEach((id, entry) -> {
if(entry.dead()) dead.put(id, entry.value); // dont increment value here.
});
@@ -142,7 +161,7 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
}
protected static final class Entry<T> {
private static final class Entry<T> {
private final T value;
private final AtomicInteger access = new AtomicInteger(0);

View File

@@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.zip.ZipFile;
import com.dfsek.terra.api.Platform;
@@ -46,14 +47,14 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
public void load(File folder, Platform platform) throws ConfigException {
ConfigPack pack = new ConfigPackImpl(folder, platform);
register(pack.getID(), pack);
register(pack.getRegistryKey(), pack);
}
public boolean loadAll(Platform platform) {
boolean valid = true;
File packsFolder = new File(platform.getDataFolder(), "packs");
packsFolder.mkdirs();
for(File dir : packsFolder.listFiles(File::isDirectory)) {
for(File dir : Objects.requireNonNull(packsFolder.listFiles(File::isDirectory))) {
try {
load(dir, platform);
} catch(ConfigException e) {
@@ -61,7 +62,8 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
valid = false;
}
}
for(File zip : packsFolder.listFiles(file -> file.getName().endsWith(".zip") || file.getName().endsWith(".terra"))) {
for(File zip : Objects.requireNonNull(
packsFolder.listFiles(file -> file.getName().endsWith(".zip") || file.getName().endsWith(".terra")))) {
try {
logger.info("Loading ZIP archive: {}", zip.getName());
load(new ZipFile(zip), platform);
@@ -75,6 +77,6 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
public void load(ZipFile file, Platform platform) throws ConfigException {
ConfigPackImpl pack = new ConfigPackImpl(file, platform);
register(pack.getTemplate().getID(), pack);
register(pack.getRegistryKey(), pack);
}
}

View File

@@ -24,7 +24,7 @@ import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.api.util.generic.Construct;
import com.dfsek.terra.fabric.data.Codecs;
import net.fabricmc.api.ModInitializer;
import net.minecraft.server.command.ServerCommandSource;
@@ -33,9 +33,6 @@ import net.minecraft.util.registry.Registry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
public class FabricEntryPoint implements ModInitializer {
private static final Logger logger = LoggerFactory.getLogger(FabricEntryPoint.class);
@@ -51,8 +48,8 @@ public class FabricEntryPoint implements ModInitializer {
public void onInitialize() {
logger.info("Initializing Terra Fabric mod...");
// register the things
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC);
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), Codecs.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE);
FabricServerCommandManager<CommandSender> manager = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),

View File

@@ -74,7 +74,7 @@ public class PlatformImpl extends AbstractPlatform {
worlds.forEach(world -> {
FabricChunkGeneratorWrapper chunkGeneratorWrapper = ((FabricChunkGeneratorWrapper) world.getChunkManager().getChunkGenerator());
chunkGeneratorWrapper.setPack(getConfigRegistry().get(chunkGeneratorWrapper.getPack().getID()).orElseThrow());
chunkGeneratorWrapper.setPack(getConfigRegistry().get(chunkGeneratorWrapper.getPack().getRegistryKey()).orElseThrow());
});
return succeed;

View File

@@ -0,0 +1,58 @@
package com.dfsek.terra.fabric.data;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.registry.key.RegistryKey;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.dynamic.RegistryLookupCodec;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
public final class Codecs {
public static final Codec<RegistryKey> REGISTRY_KEY = RecordCodecBuilder
.create(registryKey -> registryKey.group(Codec.STRING.fieldOf("namespace")
.forGetter(RegistryKey::getNamespace),
Codec.STRING.fieldOf("id")
.forGetter(RegistryKey::getID))
.apply(registryKey, registryKey.stable(RegistryKey::of)));
public static final Codec<ConfigPack> CONFIG_PACK = RecordCodecBuilder
.create(config -> config.group(REGISTRY_KEY.fieldOf("pack")
.forGetter(ConfigPack::getRegistryKey))
.apply(config, config.stable(id -> FabricEntryPoint.getPlatform()
.getConfigRegistry()
.get(id)
.orElseThrow(() -> new IllegalArgumentException(
"No such config pack " +
id)))));
public static final Codec<TerraBiomeSource> TERRA_BIOME_SOURCE = RecordCodecBuilder
.create(instance -> instance.group(RegistryLookupCodec.of(Registry.BIOME_KEY)
.forGetter(TerraBiomeSource::getBiomeRegistry),
Codec.LONG.fieldOf("seed").stable()
.forGetter(TerraBiomeSource::getSeed),
CONFIG_PACK.fieldOf("pack").stable()
.forGetter(TerraBiomeSource::getPack))
.apply(instance, instance.stable(
TerraBiomeSource::new)));
public static final Codec<FabricChunkGeneratorWrapper> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
TERRA_BIOME_SOURCE.fieldOf("biome_source")
.forGetter(FabricChunkGeneratorWrapper::getBiomeSource),
Codec.LONG.fieldOf("seed").stable()
.forGetter(FabricChunkGeneratorWrapper::getSeed),
CONFIG_PACK.fieldOf("pack").stable()
.forGetter(FabricChunkGeneratorWrapper::getPack),
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
.forGetter(FabricChunkGeneratorWrapper::getSettingsSupplier)
).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new))
);
}

View File

@@ -18,19 +18,17 @@
package com.dfsek.terra.fabric.generation;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.ServerWorld;
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
import com.dfsek.terra.api.world.chunk.generation.stage.Chunkified;
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.data.Codecs;
import com.dfsek.terra.fabric.mixin.access.StructureAccessorAccessor;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.util.collection.Pool;
@@ -61,30 +59,7 @@ import java.util.function.Supplier;
public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.ChunkGenerator implements GeneratorWrapper {
public static final Codec<ConfigPack> PACK_CODEC = RecordCodecBuilder.create(
config -> config.group(
Codec.STRING.fieldOf("pack")
.forGetter(ConfigPack::getID)
).apply(config, config.stable(id -> FabricEntryPoint.getPlatform()
.getConfigRegistry()
.get(id)
.orElseThrow(
() -> new IllegalArgumentException(
"No such config pack " +
id)))));
private static final Logger logger = LoggerFactory.getLogger(FabricChunkGeneratorWrapper.class);
public static final Codec<FabricChunkGeneratorWrapper> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
TerraBiomeSource.CODEC.fieldOf("biome_source")
.forGetter(generator -> generator.biomeSource),
Codec.LONG.fieldOf("seed").stable()
.forGetter(generator -> generator.seed),
PACK_CODEC.fieldOf("pack").stable()
.forGetter(generator -> generator.pack),
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
.forGetter(generator -> generator.settingsSupplier)
).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new))
);
private final long seed;
private final TerraBiomeSource biomeSource;
@@ -107,7 +82,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
@Override
protected Codec<? extends net.minecraft.world.gen.chunk.ChunkGenerator> getCodec() {
return CODEC;
return Codecs.CODEC;
}
@Override
@@ -251,4 +226,17 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
public ChunkGenerator getHandle() {
return delegate;
}
public long getSeed() {
return seed;
}
public Supplier<ChunkGeneratorSettings> getSettingsSupplier() {
return settingsSupplier;
}
@Override
public TerraBiomeSource getBiomeSource() {
return biomeSource;
}
}

View File

@@ -17,47 +17,33 @@
package com.dfsek.terra.fabric.generation;
import com.dfsek.terra.fabric.data.Codecs;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.Identifier;
import net.minecraft.util.dynamic.RegistryLookupCodec;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.util.FabricUtil;
public class TerraBiomeSource extends BiomeSource {
public static final Codec<ConfigPack> PACK_CODEC = (RecordCodecBuilder.create(config -> config.group(
Codec.STRING.fieldOf("pack").forGetter(ConfigPack::getID)
)
.apply(config, config.stable(
id -> FabricEntryPoint.getPlatform()
.getConfigRegistry()
.get(id)
.orElseThrow(
() -> new IllegalArgumentException(
"No such config pack " +
id))))));
public static final Codec<TerraBiomeSource> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryLookupCodec.of(Registry.BIOME_KEY).forGetter(source -> source.biomeRegistry),
Codec.LONG.fieldOf("seed").stable().forGetter(source -> source.seed),
PACK_CODEC.fieldOf("pack").stable().forGetter(source -> source.pack))
.apply(instance, instance.stable(
TerraBiomeSource::new)));
private final Registry<net.minecraft.world.biome.Biome> biomeRegistry;
private final long seed;
private ConfigPack pack;
private final Map<Biome, net.minecraft.world.biome.Biome> terraToMinecraft = new HashMap<>();
public TerraBiomeSource(Registry<net.minecraft.world.biome.Biome> biomes, long seed, ConfigPack pack) {
super(biomes.stream()
.filter(biome -> Objects.requireNonNull(biomes.getId(biome))
@@ -75,7 +61,7 @@ public class TerraBiomeSource extends BiomeSource {
@Override
protected Codec<? extends BiomeSource> getCodec() {
return CODEC;
return Codecs.TERRA_BIOME_SOURCE;
}
@Override
@@ -86,10 +72,23 @@ public class TerraBiomeSource extends BiomeSource {
@Override
public net.minecraft.world.biome.Biome getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) {
Biome biome = pack.getBiomeProvider().getBiome(biomeX << 2, biomeZ << 2, seed);
return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID())));
return terraToMinecraft.computeIfAbsent(biome, b -> biomeRegistry
.get(new Identifier("terra", FabricUtil.createBiomeID(pack, pack.getKey(b.getID())))));
}
public BiomeProvider getProvider() {
return pack.getBiomeProvider();
}
public Registry<net.minecraft.world.biome.Biome> getBiomeRegistry() {
return biomeRegistry;
}
public ConfigPack getPack() {
return pack;
}
public long getSeed() {
return seed;
}
}

View File

@@ -85,7 +85,7 @@ public abstract class GeneratorOptionsMixin {
prop = prop.substring(prop.indexOf(":") + 1);
String finalProp = prop;
ConfigPack config = main.getConfigRegistry().get(prop).orElseThrow(() -> new IllegalArgumentException(
ConfigPack config = main.getConfigRegistry().tryGet(prop).orElseThrow(() -> new IllegalArgumentException(
"No such pack " + finalProp));
cir.setReturnValue(

View File

@@ -54,8 +54,9 @@ public final class FabricUtil {
private static final Map<RegistryKey<net.minecraft.world.biome.Biome>, List<RegistryKey<net.minecraft.world.biome.Biome>>>
terraVanillaBiomes = new HashMap<>();
public static String createBiomeID(ConfigPack pack, String biomeID) {
return pack.getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
return pack.getID()
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
}
/**
@@ -64,7 +65,8 @@ public final class FabricUtil {
* @param biome The Terra BiomeBuilder.
* @param pack The ConfigPack this biome belongs to.
*/
public static void registerBiome(Biome biome, ConfigPack pack, DynamicRegistryManager registryManager, String id) {
public static void registerBiome(Biome biome, ConfigPack pack, DynamicRegistryManager registryManager,
com.dfsek.terra.api.registry.key.RegistryKey id) {
// BiomeTemplate template = biome.getTemplate();
Map<String, Integer> colors = new HashMap<>(); // template.getColors();