From 7528bd343b5084191c900ab2c8b9d5bf8b895bb2 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Mon, 12 Sep 2022 07:06:45 -0400 Subject: [PATCH] 3x --- .../com/volmit/iris/engine/IrisComplex.java | 61 +++++++------ .../engine/actuator/IrisBiomeActuator.java | 63 ++++++------- .../engine/actuator/IrisDecorantActuator.java | 91 +++++++++---------- .../actuator/IrisTerrainNormalActuator.java | 7 +- .../iris/engine/mode/ModeOverworld.java | 33 +++++-- .../volmit/iris/util/cache/ChunkCache2D.java | 27 ++++++ .../volmit/iris/util/cache/WorldCache2D.java | 34 +++++++ .../com/volmit/iris/util/data/KCache.java | 5 +- .../util/hunk/view/ChunkDataHunkHolder.java | 3 +- .../util/hunk/view/ChunkDataHunkView.java | 33 ++++++- .../util/stream/utility/CachedStream2D.java | 11 ++- .../utility/ContextInjectingStream.java | 6 +- 12 files changed, 238 insertions(+), 136 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/cache/ChunkCache2D.java create mode 100644 src/main/java/com/volmit/iris/util/cache/WorldCache2D.java diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index ba89bbe8b..2ad1c02cd 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -33,6 +33,7 @@ import com.volmit.iris.engine.object.IrisRegion; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; @@ -118,9 +119,9 @@ public class IrisComplex implements DataProvider { overlayStream = ProceduralStream.ofDouble((x, z) -> 0.0D).waste("Overlay Stream"); engine.getDimension().getOverlayNoise().forEach(i -> overlayStream = overlayStream.add((x, z) -> i.get(rng, getData(), x, z))); rockStream = engine.getDimension().getRockPalette().getLayerGenerator(rng.nextParallelRNG(45), data).stream() - .select(engine.getDimension().getRockPalette().getBlockData(data)).waste("Rock Stream").contextInjecting((c,x,z)->c.getRock().get(x, z)); + .select(engine.getDimension().getRockPalette().getBlockData(data)).waste("Rock Stream"); fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream() - .select(engine.getDimension().getFluidPalette().getBlockData(data)).waste("Fluid Stream").contextInjecting((c,x,z)->c.getFluid().get(x, z)); + .select(engine.getDimension().getFluidPalette().getBlockData(data)).waste("Fluid Stream"); regionStyleStream = engine.getDimension().getRegionStyle().create(rng.nextParallelRNG(883), getData()).stream() .zoom(engine.getDimension().getRegionZoom()).waste("Region Style"); regionIdentityStream = regionStyleStream.fit(Integer.MIN_VALUE, Integer.MAX_VALUE).waste("Region Identity Stream"); @@ -129,33 +130,35 @@ public class IrisComplex implements DataProvider { Interpolated.of(a -> 0D, a -> focusRegion)) : regionStyleStream .selectRarity(data.getRegionLoader().loadAll(engine.getDimension().getRegions())) - .cache2D("regionStream", engine, cacheSize).waste("Region Stream") - .contextInjecting((c,x,z)->c.getRegion().get(x, z)); + .cache2D("regionStream", engine, cacheSize).waste("Region Stream"); regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L)).waste("Region ID Stream"); - caveBiomeStream = regionStream.convert((r) + caveBiomeStream = regionStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z)) + .convert((r) -> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream() .zoom(r.getCaveBiomeZoom()) .selectRarity(data.getBiomeLoader().loadAll(r.getCaveBiomes())) .onNull(emptyBiome) - ).convertAware2D(ProceduralStream::get).cache2D("caveBiomeStream", engine, cacheSize).waste("Cave Biome Stream") - .contextInjecting((c,x,z)->c.getCave().get(x, z)); + ).convertAware2D(ProceduralStream::get).cache2D("caveBiomeStream", engine, cacheSize).waste("Cave Biome Stream"); inferredStreams.put(InferredType.CAVE, caveBiomeStream); - landBiomeStream = regionStream.convert((r) + landBiomeStream = regionStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z)) + .convert((r) -> engine.getDimension().getLandBiomeStyle().create(rng.nextParallelRNG(InferredType.LAND.ordinal()), getData()).stream() .zoom(r.getLandBiomeZoom()) .selectRarity(data.getBiomeLoader().loadAll(r.getLandBiomes(), (t) -> t.setInferredType(InferredType.LAND))) ).convertAware2D(ProceduralStream::get) .cache2D("landBiomeStream", engine, cacheSize).waste("Land Biome Stream"); inferredStreams.put(InferredType.LAND, landBiomeStream); - seaBiomeStream = regionStream.convert((r) + seaBiomeStream = regionStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z)) + .convert((r) -> engine.getDimension().getSeaBiomeStyle().create(rng.nextParallelRNG(InferredType.SEA.ordinal()), getData()).stream() .zoom(r.getSeaBiomeZoom()) .selectRarity(data.getBiomeLoader().loadAll(r.getSeaBiomes(), (t) -> t.setInferredType(InferredType.SEA))) ).convertAware2D(ProceduralStream::get) .cache2D("seaBiomeStream", engine, cacheSize).waste("Sea Biome Stream"); inferredStreams.put(InferredType.SEA, seaBiomeStream); - shoreBiomeStream = regionStream.convert((r) + shoreBiomeStream = regionStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z)) + .convert((r) -> engine.getDimension().getShoreBiomeStyle().create(rng.nextParallelRNG(InferredType.SHORE.ordinal()), getData()).stream() .zoom(r.getShoreBiomeZoom()) .selectRarity(data.getBiomeLoader().loadAll(r.getShoreBiomes(), (t) -> t.setInferredType(InferredType.SHORE))) @@ -175,37 +178,39 @@ public class IrisComplex implements DataProvider { heightStream = ProceduralStream.of((x, z) -> { IrisBiome b = focusBiome != null ? focusBiome : baseBiomeStream.get(x, z); return getHeight(engine, b, x, z, engine.getSeedManager().getHeight()); - }, Interpolated.DOUBLE).cache2D("heightStream", engine, cacheSize).waste("Height Stream") - .contextInjecting((c,x,z)->c.getHeight().get(x, z)); - roundedHeighteightStream = heightStream.round().waste("Rounded Height Stream") - .contextInjecting((c,x,z)->(int)Math.round(c.getHeight().get(x, z))); - slopeStream = heightStream.slope(3).cache2D("slopeStream", engine, cacheSize).waste("Slope Stream"); + }, Interpolated.DOUBLE).cache2D("heightStream", engine, cacheSize).waste("Height Stream"); + roundedHeighteightStream = heightStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z)) + .round().waste("Rounded Height Stream"); + slopeStream = heightStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z)) + .slope(3).cache2D("slopeStream", engine, cacheSize).waste("Slope Stream"); trueBiomeStream = focusBiome != null ? ProceduralStream.of((x, y) -> focusBiome, Interpolated.of(a -> 0D, b -> focusBiome)) .cache2D("trueBiomeStream-focus", engine, cacheSize) : heightStream .convertAware2D((h, x, z) -> fixBiomeType(h, baseBiomeStream.get(x, z), - regionStream.get(x, z), x, z, fluidHeight)) - .cache2D("trueBiomeStream", engine, cacheSize).waste("True Biome Stream") - .contextInjecting((c,x,z)->c.getBiome().get(x, z)); - trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D("trueBiomeDerivativeStream", engine, cacheSize).waste("True Biome Derivative Stream"); - heightFluidStream = heightStream.max(fluidHeight).cache2D("heightFluidStream", engine, cacheSize).waste("Height Fluid Stream"); + regionStream.contextInjecting((c,xx,zz)-> IrisContext.getOr(engine).getChunkContext().getRegion().get(xx, zz)).get(x, z), x, z, fluidHeight)) + .cache2D("trueBiomeStream", engine, cacheSize).waste("True Biome Stream"); + trueBiomeDerivativeStream = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) + .convert(IrisBiome::getDerivative).cache2D("trueBiomeDerivativeStream", engine, cacheSize).waste("True Biome Derivative Stream"); + heightFluidStream = heightStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z)) + .max(fluidHeight).cache2D("heightFluidStream", engine, cacheSize).waste("Height Fluid Stream"); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height).waste("Max Height Stream"); - terrainSurfaceDecoration = trueBiomeStream + terrainSurfaceDecoration = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D("terrainSurfaceDecoration", engine, cacheSize).waste("Surface Decoration Stream"); - terrainCeilingDecoration = trueBiomeStream + terrainCeilingDecoration = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D("terrainCeilingDecoration", engine, cacheSize).waste("Ceiling Decoration Stream"); - terrainCaveSurfaceDecoration = caveBiomeStream + terrainCaveSurfaceDecoration = caveBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getCave().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D("terrainCaveSurfaceDecoration", engine, cacheSize).waste("Cave Surface Stream"); - terrainCaveCeilingDecoration = caveBiomeStream + terrainCaveCeilingDecoration = caveBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getCave().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D("terrainCaveCeilingDecoration", engine, cacheSize).waste("Cave Ceiling Stream"); - shoreSurfaceDecoration = trueBiomeStream + shoreSurfaceDecoration = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.SHORE_LINE)).cache2D("shoreSurfaceDecoration", engine, cacheSize).waste("Shore Surface Stream"); - seaSurfaceDecoration = trueBiomeStream + seaSurfaceDecoration = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.SEA_SURFACE)).cache2D("seaSurfaceDecoration", engine, cacheSize).waste("Sea Surface Stream"); - seaFloorDecoration = trueBiomeStream + seaFloorDecoration = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.SEA_FLOOR)).cache2D("seaFloorDecoration", engine, cacheSize).waste("Sea Floor Stream"); - baseBiomeIDStream = trueBiomeStream.convertAware2D((b, x, z) -> { + baseBiomeIDStream = trueBiomeStream.contextInjecting((c,x,z)-> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) + .convertAware2D((b, x, z) -> { UUID d = regionIDStream.get(x, z); return new UUID(b.getLoadKey().hashCode() * 818223L, d.hashCode()); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index ff1b5a14f..71d0ffb43 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -78,50 +78,45 @@ public class IrisBiomeActuator extends EngineAssignedActuator { @Override public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor burst = burst().burst(PaperLib.isPaper() && multicore); for(int xf = 0; xf < h.getWidth(); xf++) { - int finalXf = xf; - burst.queue(() -> { - IrisBiome ib; - for(int zf = 0; zf < h.getDepth(); zf++) { - ib = context.getBiome().get(finalXf, zf); - int maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); - if(ib.isCustom()) { - try { - IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); - Object biomeBase = INMS.get().getCustomBiomeBaseHolderFor(getDimension().getLoadKey() + ":" + custom.getId()); + IrisBiome ib; + for(int zf = 0; zf < h.getDepth(); zf++) { + ib = context.getBiome().get(xf, zf); + int maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); + if(ib.isCustom()) { + try { + IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); + Object biomeBase = INMS.get().getCustomBiomeBaseHolderFor(getDimension().getLoadKey() + ":" + custom.getId()); - if(biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) { - throw new RuntimeException("Cant inject biome!"); - } - - for(int i = 0; i < maxHeight; i++) { - injectBiome(h, finalXf, i, zf, biomeBase); - } - } catch(Throwable e) { - Iris.reportError(e); - Biome v = ib.getSkyBiome(rng, x, 0, z); - for(int i = 0; i < maxHeight; i++) { - h.set(finalXf, i, zf, v); - } + if(biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) { + throw new RuntimeException("Cant inject biome!"); } - } else { - Biome v = ib.getSkyBiome(rng, x, 0, z); - if(v != null) { - for(int i = 0; i < maxHeight; i++) { - h.set(finalXf, i, zf, v); - } - } else if(cl.flip()) { - Iris.error("No biome provided for " + ib.getLoadKey()); + for(int i = 0; i < maxHeight; i++) { + injectBiome(h, xf, i, zf, biomeBase); + } + } catch(Throwable e) { + Iris.reportError(e); + Biome v = ib.getSkyBiome(rng, x, 0, z); + for(int i = 0; i < maxHeight; i++) { + h.set(xf, i, zf, v); } } + } else { + Biome v = ib.getSkyBiome(rng, x, 0, z); + + if(v != null) { + for(int i = 0; i < maxHeight; i++) { + h.set(xf, i, zf, v); + } + } else if(cl.flip()) { + Iris.error("No biome provided for " + ib.getLoadKey()); + } } - }); + } } - burst.complete(); getEngine().getMetrics().getBiome().put(p.getMilliseconds()); } } diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 801861312..9002ea03e 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -73,69 +73,64 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor burst = burst().burst(multicore); for(int i = 0; i < output.getWidth(); i++) { - int finalI = i; - burst.queue(() -> { - int height; - int realX = Math.round(x + finalI); - int realZ; - IrisBiome biome, cave; - for(int j = 0; j < output.getDepth(); j++) { - boolean solid; - int emptyFor = 0; - int lastSolid = 0; - realZ = Math.round(z + j); - height = (int) Math.round(context.getHeight().get(finalI, j)); - biome = context.getBiome().get(finalI, j); - cave = shouldRay ? context.getCave().get(finalI, j) : null; + int height; + int realX = Math.round(x + i); + int realZ; + IrisBiome biome, cave; + for(int j = 0; j < output.getDepth(); j++) { + boolean solid; + int emptyFor = 0; + int lastSolid = 0; + realZ = Math.round(z + j); + height = (int) Math.round(context.getHeight().get(i, j)); + biome = context.getBiome().get(i, j); + cave = shouldRay ? context.getCave().get(i, j) : null; - if(biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { - continue; - } + if(biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { + continue; + } - if(height < getDimension().getFluidHeight()) { - getSeaSurfaceDecorator().decorate(finalI, j, - realX, Math.round(finalI + 1), Math.round(x + finalI - 1), - realZ, Math.round(z + j + 1), Math.round(z + j - 1), - output, biome, getDimension().getFluidHeight(), getEngine().getHeight()); - getSeaFloorDecorator().decorate(finalI, j, - realX, realZ, output, biome, height + 1, - getDimension().getFluidHeight() + 1); - } + if(height < getDimension().getFluidHeight()) { + getSeaSurfaceDecorator().decorate(i, j, + realX, Math.round(i + 1), Math.round(x + i - 1), + realZ, Math.round(z + j + 1), Math.round(z + j - 1), + output, biome, getDimension().getFluidHeight(), getEngine().getHeight()); + getSeaFloorDecorator().decorate(i, j, + realX, realZ, output, biome, height + 1, + getDimension().getFluidHeight() + 1); + } - if(height == getDimension().getFluidHeight()) { - getShoreLineDecorator().decorate(finalI, j, - realX, Math.round(x + finalI + 1), Math.round(x + finalI - 1), - realZ, Math.round(z + j + 1), Math.round(z + j - 1), - output, biome, height, getEngine().getHeight()); - } + if(height == getDimension().getFluidHeight()) { + getShoreLineDecorator().decorate(i, j, + realX, Math.round(x + i + 1), Math.round(x + i - 1), + realZ, Math.round(z + j + 1), Math.round(z + j - 1), + output, biome, height, getEngine().getHeight()); + } - getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); + getSurfaceDecorator().decorate(i, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); - if(cave != null && cave.getDecorators().isNotEmpty()) { - for(int k = height; k > 0; k--) { - solid = PREDICATE_SOLID.test(output.get(finalI, k, j)); + if(cave != null && cave.getDecorators().isNotEmpty()) { + for(int k = height; k > 0; k--) { + solid = PREDICATE_SOLID.test(output.get(i, k, j)); - if(solid) { - if(emptyFor > 0) { - getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); - getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); - emptyFor = 0; - } - lastSolid = k; - } else { - emptyFor++; + if(solid) { + if(emptyFor > 0) { + getSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k, lastSolid); + getCeilingDecorator().decorate(i, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); + emptyFor = 0; } + lastSolid = k; + } else { + emptyFor++; } } } - }); + } } - burst.complete(); getEngine().getMetrics().getDecoration().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index f6f257f90..ac15fc913 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -27,7 +27,6 @@ import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; import org.bukkit.Material; @@ -54,14 +53,10 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor e = burst().burst(multicore); for(int xf = 0; xf < h.getWidth(); xf++) { - int finalXf = xf; - e.queue(() -> terrainSliver(x, z, finalXf, h, context)); + terrainSliver(x, z, xf, h, context); } - e.complete(); - getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/engine/mode/ModeOverworld.java b/src/main/java/com/volmit/iris/engine/mode/ModeOverworld.java index 4c4a64e91..bd19cf06a 100644 --- a/src/main/java/com/volmit/iris/engine/mode/ModeOverworld.java +++ b/src/main/java/com/volmit/iris/engine/mode/ModeOverworld.java @@ -23,6 +23,7 @@ import com.volmit.iris.engine.actuator.IrisDecorantActuator; import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineMode; +import com.volmit.iris.engine.framework.EngineStage; import com.volmit.iris.engine.framework.IrisEngineMode; import com.volmit.iris.engine.modifier.IrisCarveModifier; import com.volmit.iris.engine.modifier.IrisDepositModifier; @@ -40,17 +41,31 @@ public class ModeOverworld extends IrisEngineMode implements EngineMode { var post = new IrisPostModifier(getEngine()); var deposit = new IrisDepositModifier(getEngine()); var perfection = new IrisPerfectionModifier(getEngine()); + EngineStage sBiome = (x, z, k, p, m, c) -> biome.actuate(x, z, p, m, c); + EngineStage sGenMatter = (x, z, k, p, m, c) -> generateMatter(x >> 4, z >> 4, m, c); + EngineStage sTerrain = (x, z, k, p, m, c) -> terrain.actuate(x, z, k, m, c); + EngineStage sDecorant = (x, z, k, p, m, c) -> decorant.actuate(x, z, k, m, c); + EngineStage sCave = (x, z, k, p, m, c) -> cave.modify(x >> 4, z >> 4, k, m, c); + EngineStage sDeposit = (x, z, k, p, m, c) -> deposit.modify(x, z, k, m,c); + EngineStage sPost = (x, z, k, p, m, c) -> post.modify(x, z, k, m, c); + EngineStage sInsertMatter = (x, z, K, p, m, c) -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, K, m); + EngineStage sPerfection = (x, z, k, p, m, c) -> perfection.modify(x, z, k, m, c); - registerStage((x, z, k, p, m, c) -> biome.actuate(x, z, p, m, c)); registerStage(burst( - (x, z, k, p, m, c) -> generateMatter(x >> 4, z >> 4, m, c), - (x, z, k, p, m, c) -> terrain.actuate(x, z, k, m, c) + sBiome, + sGenMatter, + sTerrain )); - registerStage((x, z, k, p, m, c) -> cave.modify(x >> 4, z >> 4, k, m, c)); - registerStage((x, z, k, p, m, c) -> deposit.modify(x, z, k, m,c)); - registerStage((x, z, k, p, m, c) -> decorant.actuate(x, z, k, m, c)); - registerStage((x, z, k, p, m, c) -> post.modify(x, z, k, m, c)); - registerStage((x, z, K, p, m, c) -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, K, m)); - registerStage((x, z, k, p, m, c) -> perfection.modify(x, z, k, m, c)); + registerStage(burst( + sCave, + sPost + )); + registerStage(burst( + sDeposit, + sInsertMatter, + sDecorant + )); + registerStage(sPerfection); + } } diff --git a/src/main/java/com/volmit/iris/util/cache/ChunkCache2D.java b/src/main/java/com/volmit/iris/util/cache/ChunkCache2D.java new file mode 100644 index 000000000..a0fa5261a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/cache/ChunkCache2D.java @@ -0,0 +1,27 @@ +package com.volmit.iris.util.cache; + +import com.volmit.iris.util.data.ChunkCache; +import com.volmit.iris.util.function.Function2; + +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.function.Function; + +public class ChunkCache2D { + private final AtomicReferenceArray cache; + + public ChunkCache2D() { + this.cache = new AtomicReferenceArray<>(256); + } + + public T get(int x, int z, Function2 resolver) { + int key = ((z & 15) * 16) + (x & 15); + T t = cache.get(key); + + if(t == null) { + t = resolver.apply(x, z); + cache.set(key, t); + } + + return t; + } +} diff --git a/src/main/java/com/volmit/iris/util/cache/WorldCache2D.java b/src/main/java/com/volmit/iris/util/cache/WorldCache2D.java new file mode 100644 index 000000000..2ccfbe77d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/cache/WorldCache2D.java @@ -0,0 +1,34 @@ +package com.volmit.iris.util.cache; + +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.context.ChunkedDataCache; +import com.volmit.iris.util.data.KCache; +import com.volmit.iris.util.function.Function2; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.scheduling.ChronoLatch; +import it.unimi.dsi.fastutil.longs.Long2LongMaps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +public class WorldCache2D { + private final KCache> chunks; + private final Function2 resolver; + + public WorldCache2D(Function2 resolver) { + this.resolver = resolver; + chunks = new KCache<>((x) -> new ChunkCache2D<>(), 1024); + } + + public T get(int x, int z) { + ChunkCache2D chunk = chunks.get(Cache.key(x >> 4, z >> 4)); + return chunk.get(x, z, resolver); + } + + public long getSize() { + return chunks.getSize() * 256L; + } +} diff --git a/src/main/java/com/volmit/iris/util/data/KCache.java b/src/main/java/com/volmit/iris/util/data/KCache.java index eaa504571..c596e8844 100644 --- a/src/main/java/com/volmit/iris/util/data/KCache.java +++ b/src/main/java/com/volmit/iris/util/data/KCache.java @@ -24,6 +24,10 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import com.volmit.iris.engine.framework.MeteredCache; import com.volmit.iris.util.math.RollingSequence; +import java.time.Duration; +import java.time.temporal.TemporalUnit; +import java.util.concurrent.TimeUnit; + public class KCache implements MeteredCache { private final long max; private CacheLoader loader; @@ -46,7 +50,6 @@ public class KCache implements MeteredCache { return Caffeine .newBuilder() .maximumSize(max) - .softValues() .initialCapacity((int) (max)) .build((k) -> loader == null ? null : loader.load(k)); } diff --git a/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkHolder.java b/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkHolder.java index cec67eb41..e110ad4dc 100644 --- a/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkHolder.java +++ b/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkHolder.java @@ -65,8 +65,7 @@ public class ChunkDataHunkHolder extends AtomicHunk { for(int k = 0; k < getDepth(); k++) { BlockData b = super.getRaw(j, i, k); - if(b != null) - { + if(b != null) { chunk.setBlock(j, i + chunk.getMinHeight(), k, b); } } diff --git a/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java b/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java index aa7fb9569..c8e7ca177 100644 --- a/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java +++ b/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java @@ -18,12 +18,14 @@ package com.volmit.iris.util.hunk.view; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.hunk.Hunk; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; @SuppressWarnings("ClassCanBeRecord") public class ChunkDataHunkView implements Hunk { + private static final BlockData AIR = B.getAir(); private final ChunkData chunk; public ChunkDataHunkView(ChunkData chunk) { @@ -54,17 +56,44 @@ public class ChunkDataHunkView implements Hunk { chunk.setRegion(x1, y1 + chunk.getMinHeight(), z1, x2, y2 + chunk.getMinHeight(), z2, t); } + + public BlockData get(int x, int y, int z) { + return getRaw(x, y, z); + } + + public void set(int x, int y, int z, BlockData t) { + setRaw(x, y, z, t); + } + @Override public void setRaw(int x, int y, int z, BlockData t) { if(t == null) { return; } - chunk.setBlock(x, y + chunk.getMinHeight(), z, t); + try { + + chunk.setBlock(x, y + chunk.getMinHeight(), z, t); + } + + catch(Throwable ignored) + { + + } } @Override public BlockData getRaw(int x, int y, int z) { - return chunk.getBlockData(x, y + chunk.getMinHeight(), z); + try { + + return chunk.getBlockData(x, y + chunk.getMinHeight(), z); + } + + catch(Throwable e) + { + + } + + return AIR; } } diff --git a/src/main/java/com/volmit/iris/util/stream/utility/CachedStream2D.java b/src/main/java/com/volmit/iris/util/stream/utility/CachedStream2D.java index 605a6587e..fb834874e 100644 --- a/src/main/java/com/volmit/iris/util/stream/utility/CachedStream2D.java +++ b/src/main/java/com/volmit/iris/util/stream/utility/CachedStream2D.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.MeteredCache; +import com.volmit.iris.util.cache.WorldCache2D; import com.volmit.iris.util.data.KCache; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.storage.ArrayHunk; @@ -31,7 +32,7 @@ import com.volmit.iris.util.stream.ProceduralStream; public class CachedStream2D extends BasicStream implements ProceduralStream, MeteredCache { private final ProceduralStream stream; - private final KCache cache; + private final WorldCache2D cache; private final Engine engine; private boolean chunked = true; @@ -39,7 +40,7 @@ public class CachedStream2D extends BasicStream implements ProceduralStrea super(); this.stream = stream; this.engine = engine; - cache = new KCache<>(k -> stream.get(Cache.keyX(k), Cache.keyZ(k)), size); + cache = new WorldCache2D<>(stream::get); Iris.service(PreservationSVC.class).registerCache(this); } @@ -56,7 +57,7 @@ public class CachedStream2D extends BasicStream implements ProceduralStrea @Override public T get(double x, double z) { //return stream.get(x, z); - return cache.get(Cache.key((int) x, (int) z)); + return cache.get((int) x, (int) z); } @Override @@ -71,12 +72,12 @@ public class CachedStream2D extends BasicStream implements ProceduralStrea @Override public KCache getRawCache() { - return cache; + return null; } @Override public long getMaxSize() { - return cache.getMaxSize(); + return 256 * 32; } @Override diff --git a/src/main/java/com/volmit/iris/util/stream/utility/ContextInjectingStream.java b/src/main/java/com/volmit/iris/util/stream/utility/ContextInjectingStream.java index cc31692e6..bb887855e 100644 --- a/src/main/java/com/volmit/iris/util/stream/utility/ContextInjectingStream.java +++ b/src/main/java/com/volmit/iris/util/stream/utility/ContextInjectingStream.java @@ -25,7 +25,11 @@ public class ContextInjectingStream extends BasicStream { ChunkContext chunkContext = context.getChunkContext(); if(chunkContext != null && (int)x >> 4 == chunkContext.getX() >> 4 && (int)z >> 4 == chunkContext.getZ() >> 4) { - return contextAccessor.apply(chunkContext, (int)x&15, (int)z&15); + T t = contextAccessor.apply(chunkContext, (int)x&15, (int)z&15); + + if(t != null) { + return t; + } } }