mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Merge remote-tracking branch 'upstream/master' into DecreeCommands
This commit is contained in:
commit
baf76c51f9
@ -32,7 +32,7 @@ plugins {
|
||||
}
|
||||
|
||||
group 'com.volmit.iris'
|
||||
version '1.7.3'
|
||||
version '1.7.4'
|
||||
def apiVersion = '1.17'
|
||||
def name = getRootProject().getName() // See settings.gradle
|
||||
def main = 'com.volmit.iris.Iris'
|
||||
|
@ -75,7 +75,6 @@ import java.util.Map;
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
public class Iris extends VolmitPlugin implements Listener {
|
||||
private KMap<Class<? extends IrisService>, IrisService> services;
|
||||
public static KList<GroupedExecutor> executors = new KList<>();
|
||||
public static Iris instance;
|
||||
public static BukkitAudiences audiences;
|
||||
public static MultiverseCoreLink linkMultiverseCore;
|
||||
@ -85,6 +84,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
public static IrisCompat compat;
|
||||
public static FileWatcher configWatcher;
|
||||
private static VolmitSender sender;
|
||||
private final KList<Runnable> postShutdown = new KList<>();
|
||||
|
||||
@Permission
|
||||
public static PermissionIris perm;
|
||||
@ -126,6 +126,11 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
services.values().forEach(this::registerListener);
|
||||
}
|
||||
|
||||
public void postShutdown(Runnable r)
|
||||
{
|
||||
postShutdown.add(r);
|
||||
}
|
||||
|
||||
private void postEnable() {
|
||||
J.a(() -> PaperLib.suggestPaper(this));
|
||||
J.a(() -> IO.delete(getTemp()));
|
||||
@ -155,18 +160,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
for (GroupedExecutor i : executors) {
|
||||
Iris.debug("Closing Executor " + i.toString());
|
||||
i.closeNow();
|
||||
}
|
||||
|
||||
executors.clear();
|
||||
|
||||
services.values().forEach(IrisService::onDisable);
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll((Plugin) this);
|
||||
MultiBurst.burst.shutdown();
|
||||
|
||||
services.values().forEach(IrisService::onDisable);
|
||||
postShutdown.forEach(Runnable::run);
|
||||
services.clear();
|
||||
super.onDisable();
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ public class IrisSettings {
|
||||
public boolean verbose = false;
|
||||
public boolean ignoreWorldEdit = false;
|
||||
public boolean disableNMS = false;
|
||||
public boolean keepProductionOnReload = false;
|
||||
public boolean pluginMetrics = true;
|
||||
public boolean splashLogoStartup = true;
|
||||
public String forceMainWorld = "";
|
||||
|
@ -37,7 +37,6 @@ public class EditSVC implements IrisService {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
this.editors = new KMap<>();
|
||||
Iris.info("EDIT SVC ENABLED!");
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::update, 1000, 1000);
|
||||
}
|
||||
|
||||
|
@ -74,52 +74,53 @@ public class PreservationSVC implements IrisService
|
||||
@Override
|
||||
public void onDisable() {
|
||||
dereferencer.interrupt();
|
||||
dereference();
|
||||
|
||||
for(Thread i : threads)
|
||||
{
|
||||
if(i.isAlive())
|
||||
postShutdown(() -> {
|
||||
for(Thread i : threads)
|
||||
{
|
||||
if(i.isAlive())
|
||||
{
|
||||
try
|
||||
{
|
||||
i.interrupt();
|
||||
Iris.info("Shutdown Thread " + i.getName());
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(MultiBurst i : bursts)
|
||||
{
|
||||
try
|
||||
{
|
||||
i.interrupt();
|
||||
Iris.info("Shutdown Thread " + i.getName());
|
||||
i.shutdownNow();
|
||||
Iris.info("Shutdown Multiburst " + i);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(MultiBurst i : bursts)
|
||||
{
|
||||
try
|
||||
for(ExecutorService i : services)
|
||||
{
|
||||
i.shutdownNow();
|
||||
Iris.info("Shutdown Multiburst " + i);
|
||||
try
|
||||
{
|
||||
i.shutdownNow();
|
||||
Iris.info("Shutdown Executor Service " + i);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(ExecutorService i : services)
|
||||
{
|
||||
try
|
||||
{
|
||||
i.shutdownNow();
|
||||
Iris.info("Shutdown Executor Service " + i);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
dereference();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -73,15 +73,27 @@ public class StudioSVC implements IrisService {
|
||||
|
||||
@Override
|
||||
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()) {
|
||||
if (IrisToolbelt.isIrisWorld(i)) {
|
||||
for (World i : Bukkit.getWorlds()) {
|
||||
if (IrisToolbelt.isIrisWorld(i)) {
|
||||
if(IrisToolbelt.isStudio(i))
|
||||
{
|
||||
IrisToolbelt.evacuate(i);
|
||||
Iris.debug("Closing Platform Generator " + i.getName());
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,4 +189,12 @@ public class IrisToolbelt {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -412,14 +412,14 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
|
||||
switch (getDimension().getTerrainMode()) {
|
||||
case NORMAL -> {
|
||||
getMantle().generateMatter(x >> 4, z >> 4);
|
||||
getMantle().generateMatter(x >> 4, z >> 4, multicore);
|
||||
getTerrainActuator().actuate(x, z, vblocks, multicore);
|
||||
getBiomeActuator().actuate(x, z, vbiomes, multicore);
|
||||
getCaveModifier().modify(x, z, vblocks, multicore);
|
||||
getRavineModifier().modify(x, z, vblocks, multicore);
|
||||
getPostModifier().modify(x, z, vblocks, 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);
|
||||
}
|
||||
case ISLANDS -> {
|
||||
|
@ -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.IrisBiomeCustom;
|
||||
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.view.BiomeGridHunkView;
|
||||
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 org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
@ -65,41 +68,46 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
@Override
|
||||
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int zf, maxHeight;
|
||||
IrisBiome ib;
|
||||
BurstExecutor burst = burst().burst();
|
||||
burst.setMulticore(multicore);
|
||||
|
||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||
for (zf = 0; zf < h.getDepth(); zf++) {
|
||||
ib = getComplex().getTrueBiomeStream().get(modX(xf + x), modZ(zf + z));
|
||||
maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData()));
|
||||
if (ib.isCustom()) {
|
||||
try {
|
||||
IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z);
|
||||
Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId());
|
||||
int finalXf = xf;
|
||||
burst.queue(() -> {
|
||||
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()) {
|
||||
try {
|
||||
IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z);
|
||||
Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId());
|
||||
|
||||
if (biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) {
|
||||
throw new RuntimeException("Cant inject biome!");
|
||||
}
|
||||
if (biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) {
|
||||
throw new RuntimeException("Cant inject biome!");
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxHeight; i++) {
|
||||
injectBiome(h, xf, i, zf, biomeBase);
|
||||
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);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
} else {
|
||||
Biome v = ib.getSkyBiome(rng, x, 0, z);
|
||||
for (int i = 0; i < maxHeight; i++) {
|
||||
h.set(xf, i, zf, v);
|
||||
h.set(finalXf, i, zf, v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Biome v = ib.getSkyBiome(rng, x, 0, z);
|
||||
for (int i = 0; i < maxHeight; i++) {
|
||||
h.set(xf, i, zf, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
burst.complete();
|
||||
getEngine().getMetrics().getBiome().put(p.getMilliseconds());
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.volmit.iris.engine.actuator;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.decorator.*;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
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.carve.IrisCaveLayer;
|
||||
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.math.RNG;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -86,72 +90,82 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
|
||||
}
|
||||
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
|
||||
int j, realX, realZ, height;
|
||||
IrisBiome biome, cave;
|
||||
|
||||
BurstExecutor burst = burst().burst();
|
||||
burst.setMulticore(multicore);
|
||||
|
||||
for (int i = 0; i < output.getWidth(); i++) {
|
||||
for (j = 0; j < output.getDepth(); j++) {
|
||||
boolean solid, liquid;
|
||||
int emptyFor = 0;
|
||||
int liquidFor = 0;
|
||||
int lastSolid = 0;
|
||||
realX = (int) Math.round(modX(x + i));
|
||||
realZ = (int) Math.round(modZ(z + j));
|
||||
height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ));
|
||||
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
|
||||
cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : null;
|
||||
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;
|
||||
int emptyFor = 0;
|
||||
int liquidFor = 0;
|
||||
int lastSolid = 0;
|
||||
realZ = (int) Math.round(modZ(z + j));
|
||||
height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ));
|
||||
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
|
||||
cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : 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()) {
|
||||
getShoreLineDecorator().decorate(i, j,
|
||||
realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 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() + 1) {
|
||||
getSeaSurfaceDecorator().decorate(i, j,
|
||||
realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 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);
|
||||
}
|
||||
if(height < getDimension().getFluidHeight())
|
||||
{
|
||||
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)),
|
||||
output, biome, getDimension().getFluidHeight(), getEngine().getHeight());
|
||||
getSeaFloorDecorator().decorate(finalI, 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()) {
|
||||
for (int k = height; k > 0; k--) {
|
||||
solid = PREDICATE_SOLID.test(output.get(i, k, j));
|
||||
liquid = PREDICATE_CAVELIQUID.test(output.get(i, k + 1, j), k + 1);
|
||||
if (cave != null && cave.getDecorators().isNotEmpty()) {
|
||||
for (int k = height; k > 0; k--) {
|
||||
solid = PREDICATE_SOLID.test(output.get(finalI, k, j));
|
||||
liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1);
|
||||
|
||||
if (solid) {
|
||||
if (emptyFor > 0) {
|
||||
if (liquid) {
|
||||
getSeaFloorDecorator().decorate(i, 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);
|
||||
} else {
|
||||
getSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k, lastSolid);
|
||||
getCeilingDecorator().decorate(i, j, realX, realZ, output, cave, lastSolid - 1, emptyFor);
|
||||
if (solid) {
|
||||
if (emptyFor > 0) {
|
||||
if (liquid) {
|
||||
getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1);
|
||||
getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid);
|
||||
} else {
|
||||
getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid);
|
||||
getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor);
|
||||
}
|
||||
emptyFor = 0;
|
||||
liquidFor = 0;
|
||||
}
|
||||
emptyFor = 0;
|
||||
liquidFor = 0;
|
||||
lastSolid = k;
|
||||
} else {
|
||||
emptyFor++;
|
||||
if (liquid) liquidFor++;
|
||||
}
|
||||
lastSolid = k;
|
||||
} else {
|
||||
emptyFor++;
|
||||
if (liquid) liquidFor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
burst.complete();
|
||||
getEngine().getMetrics().getDecoration().put(p.getMilliseconds());
|
||||
|
||||
}
|
||||
|
||||
private boolean shouldRayDecorate() {
|
||||
|
@ -57,20 +57,15 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
||||
public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
|
||||
if (multicore) {
|
||||
BurstExecutor e = getEngine().burst().burst(h.getWidth());
|
||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||
int finalXf = xf;
|
||||
e.queue(() -> terrainSliver(x, z, finalXf, h));
|
||||
}
|
||||
|
||||
e.complete();
|
||||
} else {
|
||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||
terrainSliver(x, z, xf, h);
|
||||
}
|
||||
BurstExecutor e = getEngine().burst().burst(h.getWidth());
|
||||
e.setMulticore(multicore);
|
||||
for (int xf = 0; xf < h.getWidth(); xf++) {
|
||||
int finalXf = xf;
|
||||
e.queue(() -> terrainSliver(x, z, finalXf, h));
|
||||
}
|
||||
|
||||
e.complete();
|
||||
|
||||
getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.volmit.iris.engine.decorator;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||
|
@ -77,10 +77,6 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
|
||||
}
|
||||
|
||||
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) {
|
||||
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
||||
|
@ -23,6 +23,7 @@ import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.engine.IrisComplex;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public interface EngineComponent {
|
||||
@ -32,6 +33,11 @@ public interface EngineComponent {
|
||||
|
||||
String getName();
|
||||
|
||||
default MultiBurst burst()
|
||||
{
|
||||
return getEngine().burst();
|
||||
}
|
||||
|
||||
default void close() {
|
||||
try {
|
||||
if (this instanceof Listener) {
|
||||
|
@ -184,7 +184,7 @@ public interface EngineMantle extends IObjectPlacer {
|
||||
|
||||
|
||||
@ChunkCoordinates
|
||||
default void generateMatter(int x, int z) {
|
||||
default void generateMatter(int x, int z, boolean multicore) {
|
||||
if (!getEngine().getDimension().isUseMantle()) {
|
||||
return;
|
||||
}
|
||||
@ -199,6 +199,7 @@ public interface EngineMantle extends IObjectPlacer {
|
||||
};
|
||||
int s = getRealRadius();
|
||||
BurstExecutor burst = burst().burst();
|
||||
burst.setMulticore(multicore);
|
||||
|
||||
for (int i = -s; i <= s; i++) {
|
||||
int xx = i + x;
|
||||
@ -216,7 +217,16 @@ public interface EngineMantle extends IObjectPlacer {
|
||||
{
|
||||
KList<Runnable> px = post.copy();
|
||||
post.clear();
|
||||
burst().burst(px);
|
||||
|
||||
if(multicore)
|
||||
{
|
||||
burst().burst(px);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
burst().sync(px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +235,7 @@ public interface EngineMantle extends IObjectPlacer {
|
||||
}
|
||||
|
||||
@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()) {
|
||||
return;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||
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.regional.IrisRegion;
|
||||
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.math.RNG;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.BlockVector;
|
||||
@ -42,30 +46,32 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
|
||||
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());
|
||||
}
|
||||
|
||||
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);
|
||||
IrisRegion region = getComplex().getRegionStream().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()) {
|
||||
generate(k, terrain, ro, x, z, false);
|
||||
burst.queue(() -> generate(k, terrain, ro, x, z, false));
|
||||
}
|
||||
|
||||
for (IrisDepositGenerator k : region.getDeposits()) {
|
||||
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 (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) {
|
||||
|
@ -19,14 +19,26 @@
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
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.EngineAssignedModifier;
|
||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||
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.format.Form;
|
||||
import com.volmit.iris.util.function.*;
|
||||
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.RollingSequence;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
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.block.data.BlockData;
|
||||
import org.bukkit.block.data.Levelled;
|
||||
@ -34,9 +46,11 @@ import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Slab;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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 final RNG rng;
|
||||
|
||||
@ -48,15 +62,22 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
int i;
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
AtomicInteger j = new AtomicInteger();
|
||||
|
||||
for (i = 0; i < output.getWidth(); i++) {
|
||||
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
|
||||
post(i, j.get(), output, i + x, j.get() + z);
|
||||
}
|
||||
BurstExecutor burst = burst().burst();
|
||||
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()) {
|
||||
int ii = i.get();
|
||||
int jj = j.get();
|
||||
post(ii, jj, sync, ii + x, jj + z);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
burst.complete();
|
||||
getEngine().getMetrics().getPost().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
|
@ -44,4 +44,8 @@ public class IrisRange {
|
||||
|
||||
return rng.d(min, max);
|
||||
}
|
||||
|
||||
public boolean contains(int v) {
|
||||
return v >= min && v <= max;
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,10 @@ public class IrisDecorator {
|
||||
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) {
|
||||
|
@ -105,8 +105,24 @@ public class IrisEntitySpawn implements IRare {
|
||||
};
|
||||
|
||||
if (l != null) {
|
||||
if (spawn100(gen, l) != null)
|
||||
s++;
|
||||
if(referenceSpawner.getAllowedLightLevels().getMin() > 0 || referenceSpawner.getAllowedLightLevels().getMax() < 15)
|
||||
{
|
||||
if(referenceSpawner.getAllowedLightLevels().contains(l.getBlock().getLightLevel()))
|
||||
{
|
||||
if (spawn100(gen, l) != null)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (spawn100(gen, l) != null)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package com.volmit.iris.engine.object.spawners;
|
||||
import com.volmit.iris.core.project.loader.IrisRegistrant;
|
||||
import com.volmit.iris.engine.object.annotations.ArrayType;
|
||||
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.IrisTimeBlock;
|
||||
import com.volmit.iris.engine.object.basic.IrisWeather;
|
||||
@ -32,6 +33,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -67,6 +69,9 @@ public class IrisSpawner extends IrisRegistrant {
|
||||
@Desc("The maximum rate this spawner can fire on a specific chunk")
|
||||
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")
|
||||
private IrisSpawnGroup group = IrisSpawnGroup.NORMAL;
|
||||
|
||||
|
@ -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.dimensional.IrisDimension;
|
||||
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.io.ReactiveFolder;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
@ -47,6 +48,7 @@ import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.management.RuntimeErrorException;
|
||||
import javax.swing.text.TableView;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@ -57,7 +59,7 @@ import java.util.concurrent.Semaphore;
|
||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
||||
private static final int LOAD_LOCKS = 1_000_000;
|
||||
private final Semaphore loadLock;
|
||||
private final Engine engine;
|
||||
private Engine engine;
|
||||
private final IrisWorld world;
|
||||
private final File dataLocation;
|
||||
private final String dimensionKey;
|
||||
@ -66,9 +68,11 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
private final ChronoLatch hotloadChecker;
|
||||
private final Looper hotloader;
|
||||
private final boolean studio;
|
||||
private long lastSeed;
|
||||
|
||||
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
|
||||
populators = new KList<>();
|
||||
lastSeed = world.seed();
|
||||
loadLock = new Semaphore(LOAD_LOCKS);
|
||||
this.world = world;
|
||||
this.hotloadChecker = new ChronoLatch(1000, false);
|
||||
@ -76,6 +80,23 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
this.dataLocation = dataLocation;
|
||||
this.dimensionKey = dimensionKey;
|
||||
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);
|
||||
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);
|
||||
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
|
||||
@ -161,7 +170,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
r.run();
|
||||
loadLock.release(LOAD_LOCKS);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -169,6 +178,15 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
@Override
|
||||
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
|
||||
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();
|
||||
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
||||
TerrainChunk tc = TerrainChunk.create(world, biome);
|
||||
@ -182,6 +200,26 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
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) {
|
||||
loadLock.release();
|
||||
Iris.error("======================================");
|
||||
|
@ -1449,4 +1449,9 @@ public interface Hunk<T> {
|
||||
default boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean contains(int x, int y, int z)
|
||||
{
|
||||
return x < getWidth() && x >= 0 && y < getHeight() && y >= 0 && z < getDepth() && z >= 0;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,17 @@ public class Mantle {
|
||||
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
|
||||
public boolean hasFlag(int x, int z, MantleFlag flag) {
|
||||
return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag);
|
||||
@ -207,7 +218,16 @@ public class Mantle {
|
||||
});
|
||||
}
|
||||
|
||||
b.complete();
|
||||
try
|
||||
{
|
||||
b.complete();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
ioBurst.shutdownNow();
|
||||
Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath());
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.matter.IrisMatter;
|
||||
import com.volmit.iris.util.matter.Matter;
|
||||
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.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) {
|
||||
for (int i = 0; i < sections.length(); i++) {
|
||||
int bs = (i << 4);
|
||||
|
@ -20,6 +20,7 @@ package com.volmit.iris.util.parallel;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
@ -28,6 +29,8 @@ import java.util.concurrent.*;
|
||||
public class BurstExecutor {
|
||||
private final ExecutorService executor;
|
||||
private final KList<CompletableFuture<Void>> futures;
|
||||
@Setter
|
||||
private boolean multicore = true;
|
||||
|
||||
public BurstExecutor(ExecutorService executor, int burstSizeEstimate) {
|
||||
this.executor = executor;
|
||||
@ -36,6 +39,12 @@ public class BurstExecutor {
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public CompletableFuture<Void> queue(Runnable r) {
|
||||
if(!multicore)
|
||||
{
|
||||
r.run();
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized (futures) {
|
||||
CompletableFuture<Void> c = CompletableFuture.runAsync(r, executor);
|
||||
futures.add(c);
|
||||
@ -44,6 +53,16 @@ public class BurstExecutor {
|
||||
}
|
||||
|
||||
public BurstExecutor queue(List<Runnable> r) {
|
||||
if(!multicore)
|
||||
{
|
||||
for(Runnable i : r)
|
||||
{
|
||||
i.run();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
synchronized (futures) {
|
||||
for (Runnable i : new KList<>(r)) {
|
||||
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
||||
@ -55,6 +74,16 @@ public class BurstExecutor {
|
||||
}
|
||||
|
||||
public BurstExecutor queue(Runnable[] r) {
|
||||
if(!multicore)
|
||||
{
|
||||
for(Runnable i : r)
|
||||
{
|
||||
i.run();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
synchronized (futures) {
|
||||
for (Runnable i : r) {
|
||||
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
||||
@ -66,6 +95,11 @@ public class BurstExecutor {
|
||||
}
|
||||
|
||||
public void complete() {
|
||||
if(!multicore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (futures) {
|
||||
if (futures.isEmpty()) {
|
||||
return;
|
||||
@ -75,13 +109,17 @@ public class BurstExecutor {
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
|
||||
futures.clear();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean complete(long maxDur) {
|
||||
if(!multicore)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
synchronized (futures) {
|
||||
if (futures.isEmpty()) {
|
||||
return true;
|
||||
|
@ -21,6 +21,7 @@ package com.volmit.iris.util.parallel;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
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.math.M;
|
||||
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) {
|
||||
return new BurstExecutor(getService(), estimate);
|
||||
}
|
||||
@ -159,16 +166,30 @@ public class MultiBurst {
|
||||
|
||||
public void shutdownLater() {
|
||||
if (service != null) {
|
||||
service.submit(() -> {
|
||||
J.sleep(3000);
|
||||
try
|
||||
{
|
||||
service.submit(() -> {
|
||||
J.sleep(3000);
|
||||
Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
|
||||
|
||||
if (service != null) {
|
||||
service.shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
heartbeat.interrupt();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
|
||||
|
||||
if (service != null) {
|
||||
service.shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
heartbeat.interrupt();
|
||||
heartbeat.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,16 @@
|
||||
|
||||
package com.volmit.iris.util.plugin;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public interface IrisService extends Listener {
|
||||
void onEnable();
|
||||
|
||||
void onDisable();
|
||||
|
||||
default void postShutdown(Runnable r)
|
||||
{
|
||||
Iris.instance.postShutdown(r);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ public class VolmitSender implements CommandSender {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user