mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-25 18:19:14 +00:00
Resolvers
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.volmit.iris.engine;
|
||||
|
||||
import art.arcane.amulet.format.Form;
|
||||
import art.arcane.amulet.metric.PrecisionStopwatch;
|
||||
import com.volmit.iris.engine.feature.features.FeatureTerrain;
|
||||
import com.volmit.iris.engine.pipeline.EnginePipeline;
|
||||
import com.volmit.iris.engine.pipeline.EnginePlumbing;
|
||||
@@ -30,17 +32,23 @@ public class Engine implements Closeable {
|
||||
private final EngineExecutor executor;
|
||||
private final EnginePlumbing plumbing;
|
||||
private final EngineSeedManager seedManager;
|
||||
private final EngineEditor editor;
|
||||
|
||||
public Engine(IrisPlatform platform, PlatformWorld world, EngineConfiguration configuration) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
this.configuration = configuration;
|
||||
this.platform = platform;
|
||||
this.world = world;
|
||||
i("Initializing Iris Engine for " + platform.getPlatformName() + " in " + world.getName()
|
||||
+ " with " + configuration.getThreads() + " priority " + configuration.getThreadPriority()
|
||||
+ " threads in " + (configuration.isMutable() ? "edit mode" : "production mode"));
|
||||
this.editor = configuration.isMutable() ? new EngineEditor(this) : null;
|
||||
this.seedManager = getSeedManager();
|
||||
this.registry = EngineRegistry.builder()
|
||||
.blockRegistry(new PlatformRegistry<>(platform.getBlocks()))
|
||||
.biomeRegistry(new PlatformRegistry<>(platform.getBiomes()))
|
||||
.build();
|
||||
this.blockCache = new EngineBlockCache(this);
|
||||
this.registry = EngineRegistry.builder()
|
||||
.blockRegistry(new PlatformRegistry<>("Block", platform.getBlocks()))
|
||||
.biomeRegistry(new PlatformRegistry<>("Biome", platform.getBiomes()))
|
||||
.build();
|
||||
this.executor = new EngineExecutor(this);
|
||||
this.plumbing = EnginePlumbing.builder().engine(this)
|
||||
.pipeline(EnginePipeline.builder()
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.volmit.iris.engine;
|
||||
|
||||
import art.arcane.amulet.concurrent.J;
|
||||
import art.arcane.amulet.io.JarLoader;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.volmit.iris.engine.dimension.IrisBiome;
|
||||
import com.volmit.iris.engine.dimension.IrisDimension;
|
||||
import com.volmit.iris.engine.dimension.IrisGenerator;
|
||||
import com.volmit.iris.engine.dimension.IrisSeedSet;
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.Data;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
public class EngineEditor {
|
||||
private final Engine engine;
|
||||
private final Gson gson;
|
||||
private List<Mutated> mutatedTypes;
|
||||
|
||||
public EngineEditor(Engine engine)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.mutatedTypes = J.attempt(() -> new JarLoader(getClass()).all().parallel()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(i -> !i.isInterface() && !i.isEnum())
|
||||
.filter(i -> i.isAssignableFrom(Mutated.class) || Mutated.class.isAssignableFrom(i))
|
||||
.map(i -> J.attempt(() -> (Mutated) i.getDeclaredConstructor().newInstance(), null)).toList(), List.of());
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
mutatedTypes.forEach(i -> i.apply(gsonBuilder));
|
||||
this.gson = gsonBuilder.setPrettyPrinting().create();
|
||||
i("Registered " + mutatedTypes.size() + " Mutators with " + mutatedTypes.stream().filter(i -> i instanceof TypeAdapterFactory).count() + " Type Adapter Factories");
|
||||
|
||||
i(gson.toJson(gson.fromJson("Noise.simplex(seed)", IrisGenerator.class)));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.volmit.iris.engine;
|
||||
|
||||
import art.arcane.amulet.concurrent.J;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Closeable;
|
||||
@@ -16,6 +17,7 @@ public class EngineExecutor implements ForkJoinPool.ForkJoinWorkerThreadFactory,
|
||||
{
|
||||
this.engine = engine;
|
||||
forks = new ForkJoinPool(engine.getConfiguration().getThreads(), this, this, true);
|
||||
i("Started Pool with " + engine.getConfiguration().getThreads() + " priority " + engine.getConfiguration().getThreadPriority() + " threads.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,6 +34,18 @@ public class EngineExecutor implements ForkJoinPool.ForkJoinWorkerThreadFactory,
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
forks.shutdownNow().forEach(Runnable::run);
|
||||
i("Shutting down generator pool");
|
||||
forks.shutdownNow().forEach((i) -> {
|
||||
try
|
||||
{
|
||||
i.run();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
i("Generator pool shutdown");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,13 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class EngineSeedManager {
|
||||
private final Engine engine;
|
||||
private final long worldSeed;
|
||||
|
||||
public EngineSeedManager(Engine engine)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.worldSeed = engine.getWorld().getSeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisBiome implements Mutated {
|
||||
private String name;
|
||||
}
|
||||
@@ -1,29 +1,24 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Singular;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class IrisDimension
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisDimension implements Mutated
|
||||
{
|
||||
private String name;
|
||||
|
||||
@Data
|
||||
public static class IrisDimensionMeta
|
||||
{
|
||||
private String name;
|
||||
private String description;
|
||||
private String version;
|
||||
private List<IrisDimensionAuthor> authors = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class IrisDimensionAuthor
|
||||
{
|
||||
private String name;
|
||||
private Map<String, String> social;
|
||||
}
|
||||
@Builder.Default
|
||||
private IrisDimensionMeta meta = new IrisDimensionMeta();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisDimensionAuthor implements Mutated
|
||||
{
|
||||
private String name;
|
||||
private Map<String, String> social;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Singular;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisDimensionMeta implements Mutated
|
||||
{
|
||||
private String name;
|
||||
private String description;
|
||||
private String version;
|
||||
@Singular
|
||||
private List<IrisDimensionAuthor> authors = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import art.arcane.source.api.NoisePlane;
|
||||
import art.arcane.source.api.script.NoisePlaneConstructor;
|
||||
import art.arcane.source.api.util.NoisePreset;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisGenerator implements Mutated, TypeAdapterFactory {
|
||||
@Builder.Default
|
||||
private String java = "art.arcane.source.api.util.NoisePreset.NATURAL.create(seed)";
|
||||
|
||||
@Builder.Default
|
||||
private IrisSeedSet seed = new IrisSeedSet();
|
||||
|
||||
public NoisePlane getNoisePlane(long seed)
|
||||
{
|
||||
try {
|
||||
return NoisePlaneConstructor.execute(seed, java);
|
||||
} catch(ScriptException e) {
|
||||
e.printStackTrace();
|
||||
return NoisePreset.NATURAL.create(seed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
|
||||
|
||||
if(!type.getRawType().equals(getClass())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new TypeAdapter<>() {
|
||||
public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
JsonToken token = in.peek();
|
||||
|
||||
if(token == JsonToken.STRING)
|
||||
{
|
||||
return (T) IrisGenerator.builder().java(in.nextString()).build();
|
||||
}
|
||||
|
||||
return delegate.read(in);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
import com.volmit.iris.engine.Engine;
|
||||
import com.volmit.iris.engine.editor.Mutated;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisSeedSet implements Mutated {
|
||||
private IrisSeedSetMode mode = IrisSeedSetMode.LOCAL_OFFSET;
|
||||
private long offset = 1337;
|
||||
|
||||
public double getSeed(Engine engine, long localSeed)
|
||||
{
|
||||
return switch(mode)
|
||||
{
|
||||
case WORLD -> engine.getSeedManager().getWorldSeed();
|
||||
case LOCAL -> localSeed;
|
||||
case LOCAL_OFFSET -> localSeed + offset;
|
||||
case RAW -> offset;
|
||||
case WORLD_OFFSET -> engine.getSeedManager().getWorldSeed() + offset;
|
||||
case RANDOM -> (Math.random() * Long.MAX_VALUE) + (Math.random() * Long.MAX_VALUE);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.volmit.iris.engine.dimension;
|
||||
|
||||
public enum IrisSeedSetMode
|
||||
{
|
||||
WORLD,
|
||||
RAW,
|
||||
WORLD_OFFSET,
|
||||
LOCAL,
|
||||
LOCAL_OFFSET,
|
||||
RANDOM
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.volmit.iris.engine.editor;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Mutated {
|
||||
default void apply(GsonBuilder builder) {
|
||||
if(this instanceof TypeAdapterFactory f) {
|
||||
builder.registerTypeAdapterFactory(f);
|
||||
}
|
||||
}
|
||||
|
||||
default <T> void writeSafeJson(TypeAdapter<T> delegate, JsonWriter out, T value) {
|
||||
try {
|
||||
delegate.write(out, value);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
delegate.write(out, null);
|
||||
} catch(IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.engine.editor;
|
||||
|
||||
import com.volmit.iris.platform.PlatformNamespaced;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MutatedFrozenResolver<T extends Mutated> implements MutatedResolver<T> {
|
||||
private final Map<PlatformNamespaced, T> registry;
|
||||
|
||||
public MutatedFrozenResolver(Map<PlatformNamespaced, T> registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public T resolve(PlatformNamespaced key) {
|
||||
return registry.get(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.engine.editor;
|
||||
|
||||
import com.volmit.iris.platform.PlatformNamespaced;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MutatedLoadingResolver<T extends Mutated> implements MutatedResolver<T> {
|
||||
private final Map<PlatformNamespaced, T> registry;
|
||||
|
||||
public MutatedLoadingResolver(Map<PlatformNamespaced, T> registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public T resolve(PlatformNamespaced key) {
|
||||
return registry.get(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.volmit.iris.engine.editor;
|
||||
|
||||
import com.volmit.iris.platform.PlatformNamespaced;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MutatedResolver<T extends Mutated> {
|
||||
T resolve(PlatformNamespaced key);
|
||||
}
|
||||
@@ -4,9 +4,9 @@ import art.arcane.amulet.range.IntegerRange;
|
||||
import art.arcane.source.api.NoisePlane;
|
||||
import art.arcane.source.api.fractal.FractalFBMProvider;
|
||||
import art.arcane.source.api.interpolator.StarcastInterpolator;
|
||||
import art.arcane.source.api.noise.Generator;
|
||||
import art.arcane.source.api.noise.provider.CellularProvider;
|
||||
import art.arcane.source.api.noise.provider.SimplexProvider;
|
||||
import art.arcane.source.api.util.NoisePreset;
|
||||
import com.volmit.iris.engine.Engine;
|
||||
import com.volmit.iris.engine.feature.IrisFeature;
|
||||
import com.volmit.iris.engine.feature.IrisFeatureSizedTarget;
|
||||
@@ -26,12 +26,7 @@ public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.Te
|
||||
{
|
||||
super("terrain", engine);
|
||||
stone = engine.block("stone");
|
||||
Generator g = new Generator(new FractalFBMProvider((s) -> new CellularProvider(s), 1234));
|
||||
g.scale(0.01);
|
||||
this.generator = new StarcastInterpolator(new Generator(new SimplexProvider(engine.getWorld().getSeed()))
|
||||
.maxOutput(64)
|
||||
.minOutput(0)
|
||||
.scale(0.01).warp(g), 8, 96);
|
||||
this.generator = NoisePreset.NATURAL.create(1234).fit(0, 64).scale(0.2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
package com.volmit.iris.platform;
|
||||
|
||||
import art.arcane.amulet.format.Form;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
@Data
|
||||
public class PlatformRegistry<T extends PlatformNamespaced> {
|
||||
private final Map<PlatformNamespaceKey, T> registry;
|
||||
private final String name;
|
||||
private final String namePlural;
|
||||
|
||||
public PlatformRegistry(Stream<T> stream) {
|
||||
public PlatformRegistry(String name, String namePlural, Stream<T> stream) {
|
||||
this.name = name;
|
||||
this.namePlural = namePlural;
|
||||
registry = Collections.unmodifiableMap(stream.collect(Collectors.toMap(PlatformNamespaced::getKey, (t) -> t)));
|
||||
i("Registered " + Form.f(registry.size()) + " " + namePlural);
|
||||
}
|
||||
|
||||
public PlatformRegistry(String name, Stream<T> stream) {
|
||||
this(name, name + "s", stream);
|
||||
}
|
||||
|
||||
|
||||
public T get(PlatformNamespaceKey key) {
|
||||
return registry.get(key);
|
||||
}
|
||||
|
||||
28
engine/src/main/java/com/volmit/iris/util/NSK.java
Normal file
28
engine/src/main/java/com/volmit/iris/util/NSK.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.platform.PlatformNamespaceKey;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class NSK implements PlatformNamespaceKey {
|
||||
private final String namespace;
|
||||
private final String key;
|
||||
|
||||
public NSK(String namespacedkey)
|
||||
{
|
||||
this(namespacedkey.contains(":") ? namespacedkey.split("\\Q:\\E")[0] : "minecraft",
|
||||
namespacedkey.contains(":") ? namespacedkey.split("\\Q:\\E")[1] : namespacedkey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user