Merge remote-tracking branch 'upstream/master' into DecreeCommands

This commit is contained in:
CocoTheOwner 2021-08-19 09:54:55 +02:00
commit baf76c51f9
29 changed files with 438 additions and 185 deletions

View File

@ -32,7 +32,7 @@ plugins {
} }
group 'com.volmit.iris' group 'com.volmit.iris'
version '1.7.3' version '1.7.4'
def apiVersion = '1.17' def apiVersion = '1.17'
def name = getRootProject().getName() // See settings.gradle def name = getRootProject().getName() // See settings.gradle
def main = 'com.volmit.iris.Iris' def main = 'com.volmit.iris.Iris'

View File

@ -75,7 +75,6 @@ import java.util.Map;
@SuppressWarnings("CanBeFinal") @SuppressWarnings("CanBeFinal")
public class Iris extends VolmitPlugin implements Listener { public class Iris extends VolmitPlugin implements Listener {
private KMap<Class<? extends IrisService>, IrisService> services; private KMap<Class<? extends IrisService>, IrisService> services;
public static KList<GroupedExecutor> executors = new KList<>();
public static Iris instance; public static Iris instance;
public static BukkitAudiences audiences; public static BukkitAudiences audiences;
public static MultiverseCoreLink linkMultiverseCore; public static MultiverseCoreLink linkMultiverseCore;
@ -85,6 +84,7 @@ public class Iris extends VolmitPlugin implements Listener {
public static IrisCompat compat; public static IrisCompat compat;
public static FileWatcher configWatcher; public static FileWatcher configWatcher;
private static VolmitSender sender; private static VolmitSender sender;
private final KList<Runnable> postShutdown = new KList<>();
@Permission @Permission
public static PermissionIris perm; public static PermissionIris perm;
@ -126,6 +126,11 @@ public class Iris extends VolmitPlugin implements Listener {
services.values().forEach(this::registerListener); services.values().forEach(this::registerListener);
} }
public void postShutdown(Runnable r)
{
postShutdown.add(r);
}
private void postEnable() { private void postEnable() {
J.a(() -> PaperLib.suggestPaper(this)); J.a(() -> PaperLib.suggestPaper(this));
J.a(() -> IO.delete(getTemp())); J.a(() -> IO.delete(getTemp()));
@ -155,18 +160,10 @@ public class Iris extends VolmitPlugin implements Listener {
} }
public void onDisable() { public void onDisable() {
for (GroupedExecutor i : executors) { services.values().forEach(IrisService::onDisable);
Iris.debug("Closing Executor " + i.toString());
i.closeNow();
}
executors.clear();
Bukkit.getScheduler().cancelTasks(this); Bukkit.getScheduler().cancelTasks(this);
HandlerList.unregisterAll((Plugin) this); HandlerList.unregisterAll((Plugin) this);
MultiBurst.burst.shutdown(); postShutdown.forEach(Runnable::run);
services.values().forEach(IrisService::onDisable);
services.clear(); services.clear();
super.onDisable(); super.onDisable();
} }

View File

@ -104,6 +104,7 @@ public class IrisSettings {
public boolean verbose = false; public boolean verbose = false;
public boolean ignoreWorldEdit = false; public boolean ignoreWorldEdit = false;
public boolean disableNMS = false; public boolean disableNMS = false;
public boolean keepProductionOnReload = false;
public boolean pluginMetrics = true; public boolean pluginMetrics = true;
public boolean splashLogoStartup = true; public boolean splashLogoStartup = true;
public String forceMainWorld = ""; public String forceMainWorld = "";

View File

@ -37,7 +37,6 @@ public class EditSVC implements IrisService {
@Override @Override
public void onEnable() { public void onEnable() {
this.editors = new KMap<>(); this.editors = new KMap<>();
Iris.info("EDIT SVC ENABLED!");
Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::update, 1000, 1000); Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::update, 1000, 1000);
} }

View File

@ -74,7 +74,9 @@ public class PreservationSVC implements IrisService
@Override @Override
public void onDisable() { public void onDisable() {
dereferencer.interrupt(); dereferencer.interrupt();
dereference();
postShutdown(() -> {
for(Thread i : threads) for(Thread i : threads)
{ {
if(i.isAlive()) if(i.isAlive())
@ -87,7 +89,7 @@ public class PreservationSVC implements IrisService
catch(Throwable e) catch(Throwable e)
{ {
Iris.reportError(e);
} }
} }
} }
@ -102,7 +104,7 @@ public class PreservationSVC implements IrisService
catch(Throwable e) catch(Throwable e)
{ {
Iris.reportError(e);
} }
} }
@ -116,10 +118,9 @@ public class PreservationSVC implements IrisService
catch(Throwable e) catch(Throwable e)
{ {
Iris.reportError(e);
} }
} }
});
dereference();
} }
} }

View File

@ -73,15 +73,27 @@ public class StudioSVC implements IrisService {
@Override @Override
public void onDisable() { public void onDisable() {
if (IrisSettings.get().isStudio()) {
Iris.debug("Studio Mode Active: Closing Projects"); Iris.debug("Studio Mode Active: Closing Projects");
for (World i : Bukkit.getWorlds()) { for (World i : Bukkit.getWorlds()) {
if (IrisToolbelt.isIrisWorld(i)) { if (IrisToolbelt.isIrisWorld(i)) {
if(IrisToolbelt.isStudio(i))
{
IrisToolbelt.evacuate(i); IrisToolbelt.evacuate(i);
Iris.debug("Closing Platform Generator " + i.getName());
IrisToolbelt.access(i).close(); IrisToolbelt.access(i).close();
} }
else
{
if(!IrisSettings.get().getGeneral().isKeepProductionOnReload())
{
IrisToolbelt.evacuate(i);
IrisToolbelt.access(i).close();
Iris.error("You cannot reload Iris while production worlds are active!");
Iris.error("To prevent corrupted chunks, Iris is shutting the server down now!");
Bukkit.shutdown();
}
}
} }
} }
} }

View File

@ -189,4 +189,12 @@ public class IrisToolbelt {
return false; return false;
} }
public static boolean isStudio(World i) {
return isIrisWorld(i) && access(i).isStudio();
}
public static boolean isHeadless(World i) {
return isIrisWorld(i) && access(i).isHeadless();
}
} }

View File

@ -412,14 +412,14 @@ public class IrisEngine extends BlockPopulator implements Engine {
switch (getDimension().getTerrainMode()) { switch (getDimension().getTerrainMode()) {
case NORMAL -> { case NORMAL -> {
getMantle().generateMatter(x >> 4, z >> 4); getMantle().generateMatter(x >> 4, z >> 4, multicore);
getTerrainActuator().actuate(x, z, vblocks, multicore); getTerrainActuator().actuate(x, z, vblocks, multicore);
getBiomeActuator().actuate(x, z, vbiomes, multicore); getBiomeActuator().actuate(x, z, vbiomes, multicore);
getCaveModifier().modify(x, z, vblocks, multicore); getCaveModifier().modify(x, z, vblocks, multicore);
getRavineModifier().modify(x, z, vblocks, multicore); getRavineModifier().modify(x, z, vblocks, multicore);
getPostModifier().modify(x, z, vblocks, multicore); getPostModifier().modify(x, z, vblocks, multicore);
getDecorantActuator().actuate(x, z, blocks, multicore); getDecorantActuator().actuate(x, z, blocks, multicore);
getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks); getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore);
getDepositModifier().modify(x, z, blocks, multicore); getDepositModifier().modify(x, z, blocks, multicore);
} }
case ISLANDS -> { case ISLANDS -> {

View File

@ -26,9 +26,12 @@ import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom; import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.view.BiomeGridHunkView; import com.volmit.iris.util.hunk.view.BiomeGridHunkView;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
@ -65,13 +68,16 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
@Override @Override
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) { public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int zf, maxHeight; BurstExecutor burst = burst().burst();
IrisBiome ib; burst.setMulticore(multicore);
for (int xf = 0; xf < h.getWidth(); xf++) { for (int xf = 0; xf < h.getWidth(); xf++) {
for (zf = 0; zf < h.getDepth(); zf++) { int finalXf = xf;
ib = getComplex().getTrueBiomeStream().get(modX(xf + x), modZ(zf + z)); burst.queue(() -> {
maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); IrisBiome ib;
for (int zf = 0; zf < h.getDepth(); zf++) {
ib = getComplex().getTrueBiomeStream().get(modX(finalXf + x), modZ(zf + z));
int maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData()));
if (ib.isCustom()) { if (ib.isCustom()) {
try { try {
IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z);
@ -82,24 +88,26 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
} }
for (int i = 0; i < maxHeight; i++) { for (int i = 0; i < maxHeight; i++) {
injectBiome(h, xf, i, zf, biomeBase); injectBiome(h, finalXf, i, zf, biomeBase);
} }
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
Biome v = ib.getSkyBiome(rng, x, 0, z); Biome v = ib.getSkyBiome(rng, x, 0, z);
for (int i = 0; i < maxHeight; i++) { for (int i = 0; i < maxHeight; i++) {
h.set(xf, i, zf, v); h.set(finalXf, i, zf, v);
} }
} }
} else { } else {
Biome v = ib.getSkyBiome(rng, x, 0, z); Biome v = ib.getSkyBiome(rng, x, 0, z);
for (int i = 0; i < maxHeight; i++) { for (int i = 0; i < maxHeight; i++) {
h.set(xf, i, zf, v); h.set(finalXf, i, zf, v);
} }
} }
} }
});
} }
burst.complete();
getEngine().getMetrics().getBiome().put(p.getMilliseconds()); getEngine().getMetrics().getBiome().put(p.getMilliseconds());
} }
} }

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.actuator; package com.volmit.iris.engine.actuator;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.decorator.*; import com.volmit.iris.engine.decorator.*;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.framework.EngineAssignedActuator;
@ -25,13 +26,16 @@ import com.volmit.iris.engine.framework.EngineDecorator;
import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -86,18 +90,21 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
} }
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
BurstExecutor burst = burst().burst();
int j, realX, realZ, height; burst.setMulticore(multicore);
IrisBiome biome, cave;
for (int i = 0; i < output.getWidth(); i++) { for (int i = 0; i < output.getWidth(); i++) {
for (j = 0; j < output.getDepth(); j++) { int finalI = i;
burst.queue(() -> {
int height;
int realX = (int) Math.round(modX(x + finalI));
int realZ;
IrisBiome biome, cave;
for (int j=0; j < output.getDepth(); j++) {
boolean solid, liquid; boolean solid, liquid;
int emptyFor = 0; int emptyFor = 0;
int liquidFor = 0; int liquidFor = 0;
int lastSolid = 0; int lastSolid = 0;
realX = (int) Math.round(modX(x + i));
realZ = (int) Math.round(modZ(z + j)); realZ = (int) Math.round(modZ(z + j));
height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ));
biome = getComplex().getTrueBiomeStream().get(realX, realZ); biome = getComplex().getTrueBiomeStream().get(realX, realZ);
@ -107,36 +114,40 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
continue; continue;
} }
if (height == getDimension().getFluidHeight()) { if(height < getDimension().getFluidHeight())
getShoreLineDecorator().decorate(i, j, {
realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 1)), getSeaSurfaceDecorator().decorate(finalI, j,
realX, (int) Math.round(modX(x + finalI + 1)), (int) Math.round(modX(x + finalI - 1)),
realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)), realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)),
output, biome, height, getEngine().getHeight()); output, biome, getDimension().getFluidHeight(), getEngine().getHeight());
} else if (height == getDimension().getFluidHeight() + 1) { getSeaFloorDecorator().decorate(finalI, j,
getSeaSurfaceDecorator().decorate(i, j, realX, realZ, output, biome, height + 1,
realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 1)), getDimension().getFluidHeight() + 1);
realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)),
output, biome, height, getEngine().getHeight());
} else if (height < getDimension().getFluidHeight()) {
getSeaFloorDecorator().decorate(i, j, realX, realZ, output, biome, height + 1, getDimension().getFluidHeight() + 1);
} }
getSurfaceDecorator().decorate(i, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); if (height == getDimension().getFluidHeight()) {
getShoreLineDecorator().decorate(finalI, j,
realX, (int) Math.round(modX(x + finalI + 1)), (int) Math.round(modX(x + finalI - 1)),
realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)),
output, biome, height, getEngine().getHeight());
}
getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, biome, height, getEngine().getHeight() - height);
if (cave != null && cave.getDecorators().isNotEmpty()) { if (cave != null && cave.getDecorators().isNotEmpty()) {
for (int k = height; k > 0; k--) { for (int k = height; k > 0; k--) {
solid = PREDICATE_SOLID.test(output.get(i, k, j)); solid = PREDICATE_SOLID.test(output.get(finalI, k, j));
liquid = PREDICATE_CAVELIQUID.test(output.get(i, k + 1, j), k + 1); liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1);
if (solid) { if (solid) {
if (emptyFor > 0) { if (emptyFor > 0) {
if (liquid) { if (liquid) {
getSeaFloorDecorator().decorate(i, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1);
getSeaSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid);
} else { } else {
getSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k, lastSolid); getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid);
getCeilingDecorator().decorate(i, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor);
} }
emptyFor = 0; emptyFor = 0;
liquidFor = 0; liquidFor = 0;
@ -149,9 +160,12 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
} }
} }
} }
});
} }
burst.complete();
getEngine().getMetrics().getDecoration().put(p.getMilliseconds()); getEngine().getMetrics().getDecoration().put(p.getMilliseconds());
} }
private boolean shouldRayDecorate() { private boolean shouldRayDecorate() {

View File

@ -57,19 +57,14 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) { public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
if (multicore) {
BurstExecutor e = getEngine().burst().burst(h.getWidth()); BurstExecutor e = getEngine().burst().burst(h.getWidth());
e.setMulticore(multicore);
for (int xf = 0; xf < h.getWidth(); xf++) { for (int xf = 0; xf < h.getWidth(); xf++) {
int finalXf = xf; int finalXf = xf;
e.queue(() -> terrainSliver(x, z, finalXf, h)); e.queue(() -> terrainSliver(x, z, finalXf, h));
} }
e.complete(); e.complete();
} else {
for (int xf = 0; xf < h.getWidth(); xf++) {
terrainSliver(x, z, xf, h);
}
}
getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
} }

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.decorator; package com.volmit.iris.engine.decorator;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiome;

View File

@ -77,10 +77,6 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
} }
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData()); int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
if (decorator.isScaleStack()) {
int maxStack = max - height;
stack = (int) Math.ceil((double) maxStack * ((double) stack / 100));
} else stack = Math.min(height - max, stack);
if (stack == 1) { if (stack == 1) {
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())); data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));

View File

@ -23,6 +23,7 @@ import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.parallel.MultiBurst;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
public interface EngineComponent { public interface EngineComponent {
@ -32,6 +33,11 @@ public interface EngineComponent {
String getName(); String getName();
default MultiBurst burst()
{
return getEngine().burst();
}
default void close() { default void close() {
try { try {
if (this instanceof Listener) { if (this instanceof Listener) {

View File

@ -184,7 +184,7 @@ public interface EngineMantle extends IObjectPlacer {
@ChunkCoordinates @ChunkCoordinates
default void generateMatter(int x, int z) { default void generateMatter(int x, int z, boolean multicore) {
if (!getEngine().getDimension().isUseMantle()) { if (!getEngine().getDimension().isUseMantle()) {
return; return;
} }
@ -199,6 +199,7 @@ public interface EngineMantle extends IObjectPlacer {
}; };
int s = getRealRadius(); int s = getRealRadius();
BurstExecutor burst = burst().burst(); BurstExecutor burst = burst().burst();
burst.setMulticore(multicore);
for (int i = -s; i <= s; i++) { for (int i = -s; i <= s; i++) {
int xx = i + x; int xx = i + x;
@ -216,8 +217,17 @@ public interface EngineMantle extends IObjectPlacer {
{ {
KList<Runnable> px = post.copy(); KList<Runnable> px = post.copy();
post.clear(); post.clear();
if(multicore)
{
burst().burst(px); burst().burst(px);
} }
else
{
burst().sync(px);
}
}
} }
default void generateMantleComponent(int x, int z, MantleComponent c, Consumer<Runnable> post) { default void generateMantleComponent(int x, int z, MantleComponent c, Consumer<Runnable> post) {
@ -225,7 +235,7 @@ public interface EngineMantle extends IObjectPlacer {
} }
@ChunkCoordinates @ChunkCoordinates
default <T> void insertMatter(int x, int z, Class<T> t, Hunk<T> blocks) { default <T> void insertMatter(int x, int z, Class<T> t, Hunk<T> blocks, boolean multicore) {
if (!getEngine().getDimension().isUseMantle()) { if (!getEngine().getDimension().isUseMantle()) {
return; return;
} }

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.modifier; package com.volmit.iris.engine.modifier;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiome;
@ -25,8 +26,11 @@ import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.data.HeightMap; import com.volmit.iris.util.data.HeightMap;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.util.BlockVector; import org.bukkit.util.BlockVector;
@ -42,30 +46,32 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) { public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16)); generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16), multicore);
getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); getEngine().getMetrics().getDeposit().put(p.getMilliseconds());
} }
public void generateDeposits(RNG rx, Hunk<BlockData> terrain, int x, int z) { public void generateDeposits(RNG rx, Hunk<BlockData> terrain, int x, int z, boolean multicore) {
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z); RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7); IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7); IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
BurstExecutor burst = burst().burst();
burst.setMulticore(multicore);
for (IrisDepositGenerator k : getDimension().getDeposits()) { for (IrisDepositGenerator k : getDimension().getDeposits()) {
generate(k, terrain, ro, x, z, false); burst.queue(() -> generate(k, terrain, ro, x, z, false));
} }
for (IrisDepositGenerator k : region.getDeposits()) { for (IrisDepositGenerator k : region.getDeposits()) {
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
generate(k, terrain, ro, x, z, false); burst.queue(() -> generate(k, terrain, ro, x, z, false));
} }
} }
for (IrisDepositGenerator k : biome.getDeposits()) { for (IrisDepositGenerator k : biome.getDeposits()) {
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
generate(k, terrain, ro, x, z, false); burst.queue(() -> generate(k, terrain, ro, x, z, false));
} }
} }
burst.complete();
} }
public void generate(IrisDepositGenerator k, Hunk<BlockData> data, RNG rng, int cx, int cz, boolean safe) { public void generate(IrisDepositGenerator k, Hunk<BlockData> data, RNG rng, int cx, int cz, boolean safe) {

View File

@ -19,14 +19,26 @@
package com.volmit.iris.engine.modifier; package com.volmit.iris.engine.modifier;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.common.CaveResult; import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.B;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.*;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.storage.ArrayHunk;
import com.volmit.iris.util.math.Average;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.stream.ProceduralStream;
import com.volmit.iris.util.stream.interpolation.Interpolated;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Levelled; import org.bukkit.block.data.Levelled;
@ -34,9 +46,11 @@ import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Slab; import org.bukkit.block.data.type.Slab;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class IrisPostModifier extends EngineAssignedModifier<BlockData> { public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
private static final BlockData AIR = B.get("CAVE_AIR"); private static final BlockData AIR = B.get("AIR");
private static final BlockData WATER = B.get("WATER"); private static final BlockData WATER = B.get("WATER");
private final RNG rng; private final RNG rng;
@ -48,15 +62,22 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) { public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int i; AtomicInteger i = new AtomicInteger();
AtomicInteger j = new AtomicInteger(); AtomicInteger j = new AtomicInteger();
BurstExecutor burst = burst().burst();
for (i = 0; i < output.getWidth(); i++) { burst.setMulticore(multicore);
Hunk<BlockData> sync = output.synchronize();
for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) {
burst.queue(() -> {
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
post(i, j.get(), output, i + x, j.get() + z); int ii = i.get();
int jj = j.get();
post(ii, jj, sync, ii + x, jj + z);
} }
});
} }
burst.complete();
getEngine().getMetrics().getPost().put(p.getMilliseconds()); getEngine().getMetrics().getPost().put(p.getMilliseconds());
} }

View File

@ -44,4 +44,8 @@ public class IrisRange {
return rng.d(min, max); return rng.d(min, max);
} }
public boolean contains(int v) {
return v >= min && v <= max;
}
} }

View File

@ -107,7 +107,10 @@ public class IrisDecorator {
return stackMin; return stackMin;
} }
return getHeightGenerator(rng, data).fit(stackMin, stackMax, x / heightVariance.getZoom(), z / heightVariance.getZoom()) + 1; return getHeightGenerator(rng, data)
.fit(stackMin, stackMax,
x / heightVariance.getZoom(),
z / heightVariance.getZoom()) + 1;
} }
public CNG getHeightGenerator(RNG rng, IrisData data) { public CNG getHeightGenerator(RNG rng, IrisData data) {

View File

@ -105,12 +105,28 @@ public class IrisEntitySpawn implements IRare {
}; };
if (l != null) { if (l != null) {
if(referenceSpawner.getAllowedLightLevels().getMin() > 0 || referenceSpawner.getAllowedLightLevels().getMax() < 15)
{
if(referenceSpawner.getAllowedLightLevels().contains(l.getBlock().getLightLevel()))
{
if (spawn100(gen, l) != null) if (spawn100(gen, l) != null)
{
s++; s++;
} }
} }
} }
else
{
if (spawn100(gen, l) != null)
{
s++;
}
}
}
}
}
return s; return s;
} }

View File

@ -21,6 +21,7 @@ package com.volmit.iris.engine.object.spawners;
import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.basic.IrisRange;
import com.volmit.iris.engine.object.basic.IrisRate; import com.volmit.iris.engine.object.basic.IrisRate;
import com.volmit.iris.engine.object.basic.IrisTimeBlock; import com.volmit.iris.engine.object.basic.IrisTimeBlock;
import com.volmit.iris.engine.object.basic.IrisWeather; import com.volmit.iris.engine.object.basic.IrisWeather;
@ -32,6 +33,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -67,6 +69,9 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The maximum rate this spawner can fire on a specific chunk") @Desc("The maximum rate this spawner can fire on a specific chunk")
private IrisRate maximumRatePerChunk = new IrisRate(); private IrisRate maximumRatePerChunk = new IrisRate();
@Desc("The light levels this spawn is allowed to run in (0-15 inclusive)")
private IrisRange allowedLightLevels = new IrisRange(0, 15);
@Desc("Where should these spawns be placed") @Desc("Where should these spawns be placed")
private IrisSpawnGroup group = IrisSpawnGroup.NORMAL; private IrisSpawnGroup group = IrisSpawnGroup.NORMAL;

View File

@ -29,6 +29,7 @@ import com.volmit.iris.engine.framework.WrongEngineBroException;
import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.io.ReactiveFolder; import com.volmit.iris.util.io.ReactiveFolder;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
@ -47,6 +48,7 @@ import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.management.RuntimeErrorException; import javax.management.RuntimeErrorException;
import javax.swing.text.TableView;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -57,7 +59,7 @@ import java.util.concurrent.Semaphore;
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator { public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
private static final int LOAD_LOCKS = 1_000_000; private static final int LOAD_LOCKS = 1_000_000;
private final Semaphore loadLock; private final Semaphore loadLock;
private final Engine engine; private Engine engine;
private final IrisWorld world; private final IrisWorld world;
private final File dataLocation; private final File dataLocation;
private final String dimensionKey; private final String dimensionKey;
@ -66,9 +68,11 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
private final ChronoLatch hotloadChecker; private final ChronoLatch hotloadChecker;
private final Looper hotloader; private final Looper hotloader;
private final boolean studio; private final boolean studio;
private long lastSeed;
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
populators = new KList<>(); populators = new KList<>();
lastSeed = world.seed();
loadLock = new Semaphore(LOAD_LOCKS); loadLock = new Semaphore(LOAD_LOCKS);
this.world = world; this.world = world;
this.hotloadChecker = new ChronoLatch(1000, false); this.hotloadChecker = new ChronoLatch(1000, false);
@ -76,6 +80,23 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
this.dataLocation = dataLocation; this.dataLocation = dataLocation;
this.dimensionKey = dimensionKey; this.dimensionKey = dimensionKey;
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload()); this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
setupEngine();
this.hotloader = new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
};
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
}
private void setupEngine() {
IrisData data = IrisData.get(dataLocation); IrisData data = IrisData.get(dataLocation);
IrisDimension dimension = data.getDimensionLoader().load(dimensionKey); IrisDimension dimension = data.getDimensionLoader().load(dimensionKey);
@ -113,21 +134,9 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
} }
} }
this.engine = new IrisEngine(new EngineTarget(world, dimension, data), studio); engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
populators.clear();
populators.add((BlockPopulator) engine); populators.add((BlockPopulator) engine);
this.hotloader = new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
};
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
} }
@Override @Override
@ -161,7 +170,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
r.run(); r.run();
loadLock.release(LOAD_LOCKS); loadLock.release(LOAD_LOCKS);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); Iris.reportError(e);
} }
}); });
} }
@ -169,6 +178,15 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
@Override @Override
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
try { try {
if(lastSeed != world.getSeed())
{
Iris.warn("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed());
lastSeed = world.getSeed();
engine.getTarget().getWorld().seed(lastSeed);
engine.hotload();
Iris.success("Updated Engine seed to " + lastSeed);
}
loadLock.acquire(); loadLock.acquire();
PrecisionStopwatch ps = PrecisionStopwatch.start(); PrecisionStopwatch ps = PrecisionStopwatch.start();
TerrainChunk tc = TerrainChunk.create(world, biome); TerrainChunk tc = TerrainChunk.create(world, biome);
@ -182,6 +200,26 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
return c; return c;
} }
catch (WrongEngineBroException e)
{
Iris.warn("Trying to generate with a shut-down engine! Did you reload? Attempting to resolve this...");
try
{
setupEngine();
Iris.success("Resolved! Should generate now!");
}
catch(Throwable fe)
{
Iris.error("FATAL! Iris cannot generate in this world since it was reloaded! This will cause a crash, with missing chunks, so we're crashing right now!");
Bukkit.shutdown();
throw new RuntimeException();
}
return generateChunkData(world, ignored, x, z, biome);
}
catch (Throwable e) { catch (Throwable e) {
loadLock.release(); loadLock.release();
Iris.error("======================================"); Iris.error("======================================");

View File

@ -1449,4 +1449,9 @@ public interface Hunk<T> {
default boolean isEmpty() { default boolean isEmpty() {
return false; return false;
} }
default boolean contains(int x, int y, int z)
{
return x < getWidth() && x >= 0 && y < getHeight() && y >= 0 && z < getDepth() && z >= 0;
}
} }

View File

@ -111,6 +111,17 @@ public class Mantle {
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator); get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator);
} }
@ChunkCoordinates
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, BurstExecutor e, MantleFlag... requiredFlags) {
for (MantleFlag i : requiredFlags) {
if (!hasFlag(x, z, i)) {
return;
}
}
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e);
}
@ChunkCoordinates @ChunkCoordinates
public boolean hasFlag(int x, int z, MantleFlag flag) { public boolean hasFlag(int x, int z, MantleFlag flag) {
return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag);
@ -207,7 +218,16 @@ public class Mantle {
}); });
} }
try
{
b.complete(); b.complete();
}
catch(Throwable e)
{
Iris.reportError(e);
}
ioBurst.shutdownNow(); ioBurst.shutdownNow();
Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath());
} }

View File

@ -23,6 +23,8 @@ import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.matter.MatterSlice; import com.volmit.iris.util.matter.MatterSlice;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -184,6 +186,26 @@ public class MantleChunk {
} }
} }
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, BurstExecutor burst) {
for (int i = 0; i < sections.length(); i++) {
int finalI = i;
burst.queue(() -> {
int bs = (finalI << 4);
Matter matter = get(finalI);
if (matter != null) {
MatterSlice<T> t = matter.getSlice(type);
if (t != null) {
t.iterateSync((a, b, c, f) -> iterator.accept(a, b + bs, c, f));
}
}
});
}
burst.complete();
}
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator) { public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator) {
for (int i = 0; i < sections.length(); i++) { for (int i = 0; i < sections.length(); i++) {
int bs = (i << 4); int bs = (i << 4);

View File

@ -20,6 +20,7 @@ package com.volmit.iris.util.parallel;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import lombok.Setter;
import java.util.List; import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.*;
@ -28,6 +29,8 @@ import java.util.concurrent.*;
public class BurstExecutor { public class BurstExecutor {
private final ExecutorService executor; private final ExecutorService executor;
private final KList<CompletableFuture<Void>> futures; private final KList<CompletableFuture<Void>> futures;
@Setter
private boolean multicore = true;
public BurstExecutor(ExecutorService executor, int burstSizeEstimate) { public BurstExecutor(ExecutorService executor, int burstSizeEstimate) {
this.executor = executor; this.executor = executor;
@ -36,6 +39,12 @@ public class BurstExecutor {
@SuppressWarnings("UnusedReturnValue") @SuppressWarnings("UnusedReturnValue")
public CompletableFuture<Void> queue(Runnable r) { public CompletableFuture<Void> queue(Runnable r) {
if(!multicore)
{
r.run();
return null;
}
synchronized (futures) { synchronized (futures) {
CompletableFuture<Void> c = CompletableFuture.runAsync(r, executor); CompletableFuture<Void> c = CompletableFuture.runAsync(r, executor);
futures.add(c); futures.add(c);
@ -44,6 +53,16 @@ public class BurstExecutor {
} }
public BurstExecutor queue(List<Runnable> r) { public BurstExecutor queue(List<Runnable> r) {
if(!multicore)
{
for(Runnable i : r)
{
i.run();
}
return this;
}
synchronized (futures) { synchronized (futures) {
for (Runnable i : new KList<>(r)) { for (Runnable i : new KList<>(r)) {
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor); CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
@ -55,6 +74,16 @@ public class BurstExecutor {
} }
public BurstExecutor queue(Runnable[] r) { public BurstExecutor queue(Runnable[] r) {
if(!multicore)
{
for(Runnable i : r)
{
i.run();
}
return this;
}
synchronized (futures) { synchronized (futures) {
for (Runnable i : r) { for (Runnable i : r) {
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor); CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
@ -66,6 +95,11 @@ public class BurstExecutor {
} }
public void complete() { public void complete() {
if(!multicore)
{
return;
}
synchronized (futures) { synchronized (futures) {
if (futures.isEmpty()) { if (futures.isEmpty()) {
return; return;
@ -75,13 +109,17 @@ public class BurstExecutor {
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(); CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
futures.clear(); futures.clear();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
Iris.reportError(e); Iris.reportError(e);
} }
} }
} }
public boolean complete(long maxDur) { public boolean complete(long maxDur) {
if(!multicore)
{
return true;
}
synchronized (futures) { synchronized (futures) {
if (futures.isEmpty()) { if (futures.isEmpty()) {
return true; return true;

View File

@ -21,6 +21,7 @@ package com.volmit.iris.util.parallel;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.core.service.PreservationSVC;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.io.InstanceState;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
@ -111,6 +112,12 @@ public class MultiBurst {
} }
} }
public void sync(KList<Runnable> r) {
for (Runnable i : r) {
i.run();
}
}
public BurstExecutor burst(int estimate) { public BurstExecutor burst(int estimate) {
return new BurstExecutor(getService(), estimate); return new BurstExecutor(getService(), estimate);
} }
@ -159,6 +166,8 @@ public class MultiBurst {
public void shutdownLater() { public void shutdownLater() {
if (service != null) { if (service != null) {
try
{
service.submit(() -> { service.submit(() -> {
J.sleep(3000); J.sleep(3000);
Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
@ -170,6 +179,18 @@ public class MultiBurst {
heartbeat.interrupt(); heartbeat.interrupt();
} }
catch(Throwable e)
{
Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
if (service != null) {
service.shutdown();
}
heartbeat.interrupt();
}
}
} }
public void shutdownAndAwait() { public void shutdownAndAwait() {

View File

@ -18,10 +18,16 @@
package com.volmit.iris.util.plugin; package com.volmit.iris.util.plugin;
import com.volmit.iris.Iris;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
public interface IrisService extends Listener { public interface IrisService extends Listener {
void onEnable(); void onEnable();
void onDisable(); void onDisable();
default void postShutdown(Runnable r)
{
Iris.instance.postShutdown(r);
}
} }

View File

@ -226,7 +226,7 @@ public class VolmitSender implements CommandSender {
} }
public static String pulse(double speed) { public static String pulse(double speed) {
return Form.f(invertSpread((((getTick() * 15D * speed) % 1000D) / 1000D)), 3).replaceAll("\\Q,\\E", "."); return Form.f(invertSpread((((getTick() * 15D * speed) % 1000D) / 1000D)), 3).replaceAll("\\Q,\\E", ".").replaceAll("\\Q?\\E", "-");
} }
public static double invertSpread(double v) { public static double invertSpread(double v) {