9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-26 02:29:14 +00:00

It go fast

This commit is contained in:
cyberpwn
2022-06-26 20:01:47 -04:00
parent c209895389
commit cc70a30315
30 changed files with 815 additions and 56 deletions

View File

@@ -0,0 +1,23 @@
package com.volmit.iris.engine;
import com.volmit.iris.platform.PlatformBlock;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EngineBlockCache
{
private final IrisEngine engine;
private final Map<String, PlatformBlock> cache;
public EngineBlockCache(IrisEngine engine)
{
this.engine = engine;
this.cache = new ConcurrentHashMap<>();
}
public PlatformBlock get(String t)
{
return cache.computeIfAbsent(t, (key) -> engine.getPlatform().parseBlock(key));
}
}

View File

@@ -0,0 +1,22 @@
package com.volmit.iris.engine;
import com.volmit.iris.platform.PlatformWorld;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EngineConfiguration {
@Builder.Default
private boolean mutable = false;
@Builder.Default
private boolean timings = false;
@Builder.Default
private int threads = 4;
}

View File

@@ -0,0 +1,14 @@
package com.volmit.iris.engine;
import com.volmit.iris.platform.PlatformBiome;
import com.volmit.iris.platform.PlatformBlock;
import com.volmit.iris.platform.PlatformRegistry;
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class EngineRegistry {
private final PlatformRegistry<PlatformBlock> blockRegistry;
private final PlatformRegistry<PlatformBiome> biomeRegistry;
}

View File

@@ -0,0 +1,44 @@
package com.volmit.iris.engine;
import com.volmit.iris.engine.feature.IrisFeature;
import com.volmit.iris.engine.feature.standard.FeatureTerrain;
import com.volmit.iris.platform.IrisPlatform;
import com.volmit.iris.platform.PlatformBlock;
import com.volmit.iris.platform.PlatformNamespaceKey;
import com.volmit.iris.platform.PlatformRegistry;
import com.volmit.iris.platform.PlatformWorld;
import lombok.Data;
@Data
public class IrisEngine {
private final IrisPlatform platform;
private final EngineRegistry registry;
private final EngineConfiguration configuration;
private final PlatformWorld world;
private final EngineBlockCache blockCache;
private final FeatureTerrain terrainFeature;
public IrisEngine(IrisPlatform platform, PlatformWorld world, EngineConfiguration configuration) {
this.configuration = configuration;
this.platform = platform;
this.world = world;
this.blockCache = new EngineBlockCache(this);
this.registry = EngineRegistry.builder()
.blockRegistry(new PlatformRegistry<>(platform.getBlocks()))
.biomeRegistry(new PlatformRegistry<>(platform.getBiomes()))
.build();
terrainFeature = new FeatureTerrain(this);
}
public PlatformBlock block(String block)
{
return blockCache.get(block);
}
public PlatformNamespaceKey key(String nsk)
{
return getPlatform().key(nsk);
}
}

View File

@@ -0,0 +1,19 @@
package com.volmit.iris.engine.feature;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.Data;
@Data
public abstract class IrisFeature<T extends PlatformNamespaced, S extends IrisFeatureState> {
private final String name;
public IrisFeature(String name, IrisEngine engine)
{
this.name = name;
}
public abstract S prepare(IrisEngine engine, IrisFeatureSizedTarget target);
public abstract void generate(IrisEngine engine, S state, IrisFeatureTarget<T> target);
}

View File

@@ -0,0 +1,74 @@
package com.volmit.iris.engine.feature;
import art.arcane.amulet.collections.hunk.Hunk;
import art.arcane.amulet.geometry.Vec;
import art.arcane.amulet.range.IntegerRange;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class IrisFeatureSizedTarget {
@Builder.Default
private final int width = 16;
@Builder.Default
private final int height = 0;
@Builder.Default
private final int depth = 16;
@Builder.Default
private final int offsetX = 0;
@Builder.Default
private final int offsetY = 0;
@Builder.Default
private final int offsetZ = 0;
public int getAbsoluteMaxX()
{
return getOffsetX() + getWidth() - 1;
}
public int getAbsoluteMaxY()
{
return getOffsetY() + getHeight() - 1;
}
public int getAbsoluteMaxZ()
{
return getOffsetZ() + getDepth() - 1;
}
public IntegerRange x()
{
return new IntegerRange(getOffsetX(), getAbsoluteMaxX());
}
public IntegerRange y()
{
return new IntegerRange(getOffsetY(), getAbsoluteMaxY());
}
public IntegerRange z()
{
return new IntegerRange(getOffsetZ(), getAbsoluteMaxZ());
}
public IntegerRange localX()
{
return new IntegerRange(0, getWidth() - 1);
}
public IntegerRange localY()
{
return new IntegerRange(0, getHeight() - 1);
}
public IntegerRange localZ()
{
return new IntegerRange(0, getDepth() - 1);
}
}

View File

@@ -0,0 +1,5 @@
package com.volmit.iris.engine.feature;
public interface IrisFeatureState {
}

View File

@@ -0,0 +1,25 @@
package com.volmit.iris.engine.feature;
import art.arcane.amulet.collections.hunk.Hunk;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class IrisFeatureTarget<T extends PlatformNamespaced> extends IrisFeatureSizedTarget {
private final Hunk<T> hunk;
public IrisFeatureTarget(Hunk<T> hunk, int offsetX, int offsetY, int offsetZ)
{
super(hunk.getWidth(), hunk.getHeight(), hunk.getDepth(), offsetX, offsetY, offsetZ);
this.hunk = hunk;
}
public IrisFeatureTarget(Hunk<T> hunk, IrisFeatureSizedTarget target)
{
this(hunk, target.getOffsetX(), target.getOffsetY(), target.getOffsetZ());
}
}

View File

@@ -0,0 +1,68 @@
package com.volmit.iris.engine.feature.standard;
import art.arcane.amulet.range.IntegerRange;
import art.arcane.source.api.noise.Generator;
import art.arcane.source.api.noise.provider.SimplexProvider;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.engine.feature.IrisFeature;
import com.volmit.iris.engine.feature.IrisFeatureSizedTarget;
import com.volmit.iris.engine.feature.IrisFeatureState;
import com.volmit.iris.engine.feature.IrisFeatureTarget;
import com.volmit.iris.platform.PlatformBlock;
import com.volmit.iris.util.ShortNoiseCache;
import lombok.AllArgsConstructor;
import lombok.Data;
public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.TerrainFeatureState>
{
private final PlatformBlock stone;
private final Generator generator;
public FeatureTerrain(IrisEngine engine)
{
super("terrain", engine);
stone = engine.block("stone");
this.generator = new Generator(new SimplexProvider(engine.getWorld().getSeed()))
.maxOutput(64)
.minOutput(0)
.scale(0.01);
}
@Override
public TerrainFeatureState prepare(IrisEngine engine, IrisFeatureSizedTarget target) {
final ShortNoiseCache noise = new ShortNoiseCache(target.getWidth(), target.getDepth());
int cx,cz;
for(int x : target.x())
{
cx = x - target.getOffsetX();
for(int z : target.z())
{
cz = z - target.getOffsetZ();
noise.set(cx, cz, (short) generator.noise(x, z));
}
}
return new TerrainFeatureState(noise);
}
@Override
public void generate(IrisEngine engine, TerrainFeatureState state, IrisFeatureTarget<PlatformBlock> target) {
for(int x : target.localX()) {
for(int z : target.localZ()) {
int h = state.getNoise().get(x, z);
for(int y : new IntegerRange(target.y().getLeftEndpoint(), Math.min(target.y().getRightEndpoint(), h)))
{
target.getHunk().set(x, y, z, stone);
}
}
}
}
@Data
@AllArgsConstructor
public static class TerrainFeatureState implements IrisFeatureState {
private final ShortNoiseCache noise;
}
}

View File

@@ -0,0 +1,24 @@
package com.volmit.iris.platform;
import java.util.stream.Stream;
public interface IrisPlatform {
String getPlatformName();
Stream<PlatformBlock> getBlocks();
Stream<PlatformBiome> getBiomes();
boolean isWorldLoaded(String name);
PlatformWorld getWorld(String name);
PlatformBlock parseBlock(String raw);
PlatformNamespaceKey key(String namespace, String key);
default PlatformNamespaceKey key(String nsk)
{
return key("minecraft", nsk);
}
}

View File

@@ -0,0 +1,5 @@
package com.volmit.iris.platform;
public interface PlatformBiome extends PlatformNamespaced {
}

View File

@@ -0,0 +1,7 @@
package com.volmit.iris.platform;
import java.util.Map;
public interface PlatformBlock extends PlatformNamespaced {
Map<String, String> getProperties();
}

View File

@@ -0,0 +1,9 @@
package com.volmit.iris.platform;
public interface PlatformChunk {
int getX();
int getZ();
void unload(boolean save, boolean force);
}

View File

@@ -0,0 +1,9 @@
package com.volmit.iris.platform;
public interface PlatformNamespaceKey {
String getNamespace();
String getKey();
String toString();
}

View File

@@ -0,0 +1,5 @@
package com.volmit.iris.platform;
public interface PlatformNamespaced {
PlatformNamespaceKey getKey();
}

View File

@@ -0,0 +1,23 @@
package com.volmit.iris.platform;
import art.arcane.amulet.geometry.Vec;
import java.util.UUID;
public interface PlatformPlayer {
UUID getUUID();
String getName();
Vec getLocation();
PlatformWorld getWorld();
boolean canUseIris();
void sendMessage(String message);
void sendActionBar(String message);
void sendTitleMessage(String title, String subtitle, int in, int stay, int out);
}

View File

@@ -0,0 +1,24 @@
package com.volmit.iris.platform;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class PlatformRegistry<T extends PlatformNamespaced> {
private final Map<PlatformNamespaceKey, T> registry;
public PlatformRegistry(Stream<T> stream) {
registry = Collections.unmodifiableMap(stream.collect(Collectors.toMap(PlatformNamespaced::getKey, (t) -> t)));
}
public T get(PlatformNamespaceKey key) {
return registry.get(key);
}
public Set<PlatformNamespaceKey> getKeys() {
return Collections.unmodifiableSet(registry.keySet());
}
}

View File

@@ -0,0 +1,59 @@
package com.volmit.iris.platform;
import com.volmit.iris.util.WorldHeight;
import java.io.File;
public interface PlatformWorld {
WorldHeight getHeight();
String getName();
File getFolder();
Iterable<PlatformPlayer> getPlayers();
Iterable<PlatformChunk> getLoadedChunks();
PlatformChunk getOrLoadChunk(int x, int z);
PlatformBlock getBlock(int x, int y, int z);
PlatformBiome getBiome(int x, int y, int z);
long getSeed();
boolean isChunkLoaded(int x, int z);
void setBlock(int x, int y, int z, PlatformBlock block);
void setBiome(int x, int y, int z, PlatformBiome biome);
default File getWorldFolder(String subfolder) {
return new File(getFolder(), subfolder);
}
default File getRegionFolder() {
return getWorldFolder("region");
}
default File getIrisFolder() {
return getWorldFolder("iris");
}
default boolean isRegionLoaded(int x, int z) {
for(PlatformChunk i : getLoadedChunks()) {
if(i.getX() >> 5 == x && i.getZ() >> 5 == z) {
return true;
}
}
return false;
}
default void unloadChunks(boolean save, boolean force) {
for(PlatformChunk i : getLoadedChunks()) {
i.unload(save, force);
}
}
}

View File

@@ -0,0 +1,22 @@
package com.volmit.iris.util;
public class FloatNoiseCache {
private final int width;
private final int height;
private final float[] cache;
public FloatNoiseCache(int width, int height)
{
this.width = width;
this.height = height;
cache = new float[width * height];
}
public void set(int x, int y, float v) {
this.cache[y % this.height * this.width + x % this.width] = v;
}
public float get(int x, int y) {
return this.cache[y % this.height * this.width + x % this.width];
}
}

View File

@@ -0,0 +1,22 @@
package com.volmit.iris.util;
public class ShortNoiseCache {
private final int width;
private final int height;
private final short[] cache;
public ShortNoiseCache(int width, int height)
{
this.width = width;
this.height = height;
cache = new short[width * height];
}
public void set(int x, int y, short v) {
this.cache[y % this.height * this.width + x % this.width] = v;
}
public short get(int x, int y) {
return this.cache[y % this.height * this.width + x % this.width];
}
}

View File

@@ -0,0 +1,19 @@
package com.volmit.iris.util;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class WorldHeight {
private final int minHeight;
private final int maxHeight;
public WorldHeight(int maxHeight) {
this(0, maxHeight);
}
public int getTotalHeight() {
return maxHeight - minHeight;
}
}