This commit is contained in:
Daniel Mills 2021-01-05 18:48:55 -05:00
parent 73bfa9beb8
commit 4a30b6d264
12 changed files with 306 additions and 163 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.volmit</groupId>
<artifactId>Iris</artifactId>
<version>1.2.3</version>
<version>1.2.4-hotfix1</version>
<name>Iris</name>
<properties>
<skip.copy>false</skip.copy>

View File

@ -292,6 +292,7 @@ public class Iris extends VolmitPlugin
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
{
//TODO: Support ID
try
{
return INMS.get().createWorld(new IrisWorldCreator()

View File

@ -107,7 +107,7 @@ public class IrisEngine extends BlockPopulator implements Engine
Hunk<BlockData> blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t));
Hunk<BlockData> pblocks = structures ? postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)) : null;
Hunk<BlockData> fringe = structures ? Hunk.fringe(blocks, pblocks) : null;
getFramework().getEngineParallax().generateParallaxArea(x, z);
getFramework().getEngineParallax().generateParallaxArea(x>>4, z>>4);
getFramework().getBiomeActuator().actuate(x, z, vbiomes);
getFramework().getTerrainActuator().actuate(x, z, blocks);
getFramework().getCaveModifier().modify(x, z, blocks);

View File

@ -2,6 +2,7 @@ package com.volmit.iris.manager.command;
import com.volmit.iris.Iris;
import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.manager.link.MultiverseCoreLink;
import com.volmit.iris.nms.INMS;
import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.pregen.Pregenerator;
@ -58,6 +59,16 @@ public class CommandIrisCreate extends MortarCommand
if(multiverse)
{
dim = IrisDataManager.loadAnyDimension(type);
if(dim.getEnvironment() == null)
{
dim.setEnvironment(World.Environment.NORMAL);
}
if(Iris.linkMultiverseCore == null)
{
Iris.linkMultiverseCore = new MultiverseCoreLink();
}
String command = "mv create " + worldName + " " + Iris.linkMultiverseCore.envName(dim.getEnvironment());
command += " -s " + seed;
command += " -g Iris";

View File

@ -133,6 +133,11 @@ public class MultiverseCoreLink
}
public String envName(World.Environment environment) {
if(environment == null)
{
return "normal";
}
switch(environment)
{
case NORMAL:

View File

@ -1,6 +1,5 @@
package com.volmit.iris.pregen;
import com.sun.javafx.scene.control.skin.TableHeaderRow;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.scaffold.IrisWorlds;
@ -201,6 +200,11 @@ public class Pregenerator implements Listener
}
private boolean generateMCARegion(int x, int z, MultiBurst burst, IrisAccess access, Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration) {
if(!Iris.instance.isMCA())
{
return false;
}
File mca = new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca");
File mcg = directWriter.getMCAFile(x, z);
Path fileToMovePath = Paths.get(mcg.toURI());

View File

@ -160,40 +160,6 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
default void generateParallaxAreaFeatures(int x, int z) {
try {
PrecisionStopwatch p = PrecisionStopwatch.start();
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
for (i = -s; i <= s; i++) {
int ii = i;
for (j = -s; j <= s; j++) {
int jj = j;
int xxx = ((ii * 16) + (x));
int zzz = ((jj * 16) + (z));
int xx = xxx >> 4;
int zz = zzz >> 4;
if (!getParallaxAccess().isFeatureGenerated(xx, zz)){
RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed());
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
generateParallaxFeatures(rng, xx, zz, region, biome);
getParallaxAccess().setFeatureGenerated(xx, zz);
}
}
}
p.end();
getEngine().getMetrics().getParallax().put(p.getMilliseconds());
} catch (Throwable e) {
Iris.error("Failed to generate parallax in " + x + " " + z);
e.printStackTrace();
}
}
default void forEachFeature(double x, double z, Consumer<IrisFeaturePositional> f)
{
for(IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures())
@ -228,26 +194,50 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
default void generateParallaxAreaFeatures(int x, int z) {
try {
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
int xx = i +x;
int zz = j +z;
int xxx = xx << 4;
int zzz = zz << 4;
if (!getParallaxAccess().isFeatureGenerated(xx, zz)){
getParallaxAccess().setFeatureGenerated(xx, zz);
RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed());
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
generateParallaxFeatures(rng, xx, zz, region, biome);
}
}
}
} catch (Throwable e) {
Iris.error("Failed to generate parallax in " + x + " " + z);
e.printStackTrace();
}
}
default void generateParallaxArea(int x, int z)
{
try
{
PrecisionStopwatch p = PrecisionStopwatch.start();
generateParallaxAreaFeatures(x, z);
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i,j;
generateParallaxAreaFeatures(x, z);
for(i = -s; i <= s; i++)
{
int ii = i;
for(j = -s; j <= s; j++)
{
int jj = j;
generateParallaxLayer((ii*16)+x, (jj*16)+z);
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
generateParallaxLayer(i +x, j +z);
}
}
getParallaxAccess().setChunkGenerated(x>>4, z>>4);
getParallaxAccess().setChunkGenerated(x, z);
p.end();
getEngine().getMetrics().getParallax().put(p.getMilliseconds());
}
@ -261,18 +251,20 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
default void generateParallaxLayer(int x, int z, boolean force)
{
if(!force && getParallaxAccess().isParallaxGenerated(x >> 4, z >> 4))
if(!force && getParallaxAccess().isParallaxGenerated(x, z))
{
return;
}
getParallaxAccess().setParallaxGenerated(x>>4, z>>4);
int xx = x<<4;
int zz = z<<4;
getParallaxAccess().setParallaxGenerated(x, z);
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed());
IrisRegion region = getComplex().getRegionStream().get(x+8, z+8);
IrisBiome biome = getComplex().getTrueBiomeStream().get(x+8, z+8);
IrisRegion region = getComplex().getRegionStream().get(xx+8, zz+8);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xx+8, zz+8);
generateParallaxSurface(rng, x, z, biome);
generateParallaxMutations(rng, x, z);
generateStructures(rng, x>>4, z>>4, region, biome);
generateStructures(rng, x, z, region, biome);
}
default void generateParallaxFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome)
@ -372,7 +364,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
{
if(rng.chance(i.getChance()) && rng.chance(getComplex().getObjectChanceStream().get(x, z)))
{
place(rng, x, z, i);
place(rng, x<<4, z<<4, i);
}
}
}

View File

@ -3,11 +3,13 @@ package com.volmit.iris.scaffold.hunk.io;
import com.volmit.iris.Iris;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.scaffold.parallel.BurstExecutor;
import com.volmit.iris.scaffold.parallel.GridLock;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.*;
import org.bukkit.block.data.BlockData;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
public class HunkRegionSlice<T>
{
@ -15,6 +17,7 @@ public class HunkRegionSlice<T>
public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<String>> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new StringHunkIOAdapter(), c, t);
public static final Function3<Integer, CompoundTag, String, HunkRegionSlice<Boolean>> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new BooleanHunkIOAdapter(), c, t);
private final Function3<Integer, Integer, Integer, Hunk<T>> factory;
private final GridLock lock;
private final HunkIOAdapter<T> adapter;
private final CompoundTag compound;
private final String key;
@ -25,6 +28,7 @@ public class HunkRegionSlice<T>
public HunkRegionSlice(int height, Function3<Integer, Integer, Integer, Hunk<T>> factory, HunkIOAdapter<T> adapter, CompoundTag compound, String key)
{
this.lock = new GridLock(32, 32);
this.height = height;
this.loadedChunks = new KMap<>();
this.factory = factory;
@ -35,7 +39,7 @@ public class HunkRegionSlice<T>
this.lastUse = new KMap<>();
}
public int cleanup(long t)
public synchronized int cleanup(long t)
{
int v = 0;
if(loadedChunks.size() != lastUse.size())
@ -64,7 +68,7 @@ public class HunkRegionSlice<T>
return v;
}
public void clear()
public synchronized void clear()
{
for(String i : new KList<>(compound.getValue().keySet()))
{
@ -75,7 +79,7 @@ public class HunkRegionSlice<T>
}
}
public void save()
public synchronized void save()
{
BurstExecutor e = MultiBurst.burst.burst();
for(ChunkPosition i : save.copy())
@ -89,7 +93,7 @@ public class HunkRegionSlice<T>
try
{
save.remove(i);
lock.withNasty(i.getX(), i.getZ(), () -> save.remove(i));
}
catch(Throwable ef)
@ -101,35 +105,56 @@ public class HunkRegionSlice<T>
e.complete();
}
public boolean contains(int x, int z)
public boolean contains(int x, int z)
{
return compound.getValue().containsKey(key(x, z));
}
public void delete(int x, int z)
public void delete(int x, int z)
{
compound.getValue().remove(key(x, z));
lock.with(x, z, () -> compound.getValue().remove(key(x, z)));
}
public Hunk<T> read(int x, int z) throws IOException
public Hunk<T> read(int x, int z) throws IOException
{
Tag t = compound.getValue().get(key(x, z));
AtomicReference<IOException> e = new AtomicReference<>();
Hunk<T> xt = lock.withResult(x, z, () -> {
Tag t = compound.getValue().get(key(x, z));
if(!(t instanceof ByteArrayTag))
{
Iris.verbose("NOT BYTE ARRAY!");
return null;
}
try {
return adapter.read(factory, (ByteArrayTag) t);
} catch (IOException xe) {
e.set(xe);
}
if(!(t instanceof ByteArrayTag))
{
Iris.verbose("NOT BYTE ARRAY!");
return null;
});
if(xt != null)
{
return xt;
}
return adapter.read(factory, (ByteArrayTag) t);
if(e.get()!= null)
{
throw e.get();
}
return null;
}
public void write(Hunk<T> hunk, int x, int z) throws IOException
public void write(Hunk<T> hunk, int x, int z) throws IOException
{
compound.getValue().put(key(x, z), hunk.writeByteArrayTag(adapter, key(x, z)));
lock.withIO(x, z, () -> compound.getValue().put(key(x, z), hunk.writeByteArrayTag(adapter, key(x, z))));
}
public int unloadAll()
public synchronized int unloadAll()
{
int v = 0;
for(ChunkPosition i : loadedChunks.k())
@ -148,7 +173,7 @@ public class HunkRegionSlice<T>
{
try
{
write(region, x, z);
lock.withIO(x, z, () -> write(region, x, z));
}
catch(IOException e)
{
@ -156,92 +181,102 @@ public class HunkRegionSlice<T>
}
}
public boolean isLoaded(int x, int z)
public boolean isLoaded(int x, int z)
{
return loadedChunks.containsKey(new ChunkPosition(x, z));
return lock.withResult(x, z, () -> loadedChunks.containsKey(new ChunkPosition(x, z)));
}
public void save(int x, int z)
{
if(isLoaded(x, z))
{
save(get(x, z), x, z);
}
lock.with(x, z, () -> {
if(isLoaded(x, z))
{
save(get(x, z), x, z);
}
});
}
public void unload(int x, int z)
public void unload(int x, int z)
{
ChunkPosition key = new ChunkPosition(x, z);
if(isLoaded(x, z))
{
if(save.contains(key))
lock.with(x, z, () -> {
ChunkPosition key = new ChunkPosition(x, z);
if(isLoaded(x, z))
{
save(x, z);
save.remove(key);
}
if(save.contains(key))
{
save(x, z);
save.remove(key);
}
lastUse.remove(key);
loadedChunks.remove(key);
}
lastUse.remove(key);
loadedChunks.remove(key);
}
});
}
public Hunk<T> load(int x, int z)
{
if(isLoaded(x, z))
{
return loadedChunks.get(new ChunkPosition(x, z));
}
Hunk<T> v = null;
if(contains(x, z))
{
try
return lock.withResult(x, z, () -> {
if(isLoaded(x, z))
{
v = read(x, z);
return loadedChunks.get(new ChunkPosition(x, z));
}
catch(IOException e)
Hunk<T> v = null;
if(contains(x, z))
{
e.printStackTrace();
try
{
v = read(x, z);
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
if(v == null)
{
v = factory.apply(16, height, 16);
}
if(v == null)
{
v = factory.apply(16, height, 16);
}
loadedChunks.put(new ChunkPosition(x, z), v);
loadedChunks.put(new ChunkPosition(x, z), v);
return v;
return v;
});
}
public Hunk<T> get(int x, int z)
{
ChunkPosition key = new ChunkPosition(x, z);
return lock.withResult(x, z, () -> {
ChunkPosition key = new ChunkPosition(x, z);
Hunk<T> c = loadedChunks.get(key);
Hunk<T> c = loadedChunks.get(key);
if(c == null)
{
c = load(x, z);
}
if(c == null)
{
c = load(x, z);
}
lastUse.put(new ChunkPosition(x, z), M.ms());
lastUse.put(new ChunkPosition(x, z), M.ms());
return c;
return c;
});
}
public Hunk<T> getR(int x, int z)
{
return get(x, z).readOnly();
return lock.withResult(x, z, () -> get(x, z).readOnly());
}
public Hunk<T> getRW(int x, int z)
{
save.addIfMissing(new ChunkPosition(x, z));
return get(x, z);
return lock.withResult(x, z, () -> {
save.addIfMissing(new ChunkPosition(x, z));
return get(x, z);
});
}
private String key(int x, int z)
@ -254,7 +289,7 @@ public class HunkRegionSlice<T>
return key + "." + x + "." + z;
}
public int getLoadCount()
public int getLoadCount()
{
return loadedChunks.size();
}

View File

@ -4,6 +4,7 @@ import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.scaffold.hunk.io.HunkIOAdapter;
import com.volmit.iris.scaffold.hunk.io.HunkRegion;
import com.volmit.iris.scaffold.hunk.io.HunkRegionSlice;
import com.volmit.iris.scaffold.parallel.GridLock;
import com.volmit.iris.util.ByteArrayTag;
import com.volmit.iris.util.CompoundTag;
import com.volmit.iris.util.M;
@ -21,6 +22,7 @@ public class ParallaxRegion extends HunkRegion
private HunkRegionSlice<BlockData> blockSlice;
private HunkRegionSlice<String> objectSlice;
private HunkRegionSlice<Boolean> updateSlice;
private final GridLock lock;
private long lastUse;
private final int height;
@ -29,6 +31,7 @@ public class ParallaxRegion extends HunkRegion
super(folder, x, z, compound);
this.height = height;
setupSlices();
lock = new GridLock(32, 32);
}
public ParallaxRegion(int height, File folder, int x, int z)
@ -36,6 +39,7 @@ public class ParallaxRegion extends HunkRegion
super(folder, x, z);
this.height = height;
setupSlices();
lock = new GridLock(32, 32);
}
private void setupSlices()
@ -49,28 +53,30 @@ public class ParallaxRegion extends HunkRegion
lastUse = M.ms();
}
public boolean hasBeenIdleLongerThan(long time)
public boolean hasBeenIdleLongerThan(long time)
{
return M.ms() - lastUse > time;
}
public ParallaxChunkMeta getMetaR(int x, int z)
public ParallaxChunkMeta getMetaR(int x, int z)
{
return getMetaHunkR().getOr(x, 0, z, new ParallaxChunkMeta());
return lock.withResult(x, z, () -> getMetaHunkR().getOr(x, 0, z, new ParallaxChunkMeta()));
}
public ParallaxChunkMeta getMetaRW(int x, int z)
{
lastUse = M.ms();
dirtyMeta = true;
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
if(p == null)
{
p = new ParallaxChunkMeta();
getMetaHunkRW().set(x,0,z,p);
}
return lock.withResult(x, z, () -> {
lastUse = M.ms();
dirtyMeta = true;
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
if(p == null)
{
p = new ParallaxChunkMeta();
getMetaHunkRW().set(x,0,z,p);
}
return p;
return p;
});
}
private Hunk<ParallaxChunkMeta> getMetaHunkR()
@ -89,7 +95,7 @@ public class ParallaxRegion extends HunkRegion
return getMetaHunkR();
}
public Hunk<ParallaxChunkMeta> loadMetaHunk()
private Hunk<ParallaxChunkMeta> loadMetaHunk()
{
lastUse = M.ms();
if(meta == null)
@ -138,7 +144,7 @@ public class ParallaxRegion extends HunkRegion
}
}
public void save() throws IOException
public synchronized void save() throws IOException
{
blockSlice.save();
objectSlice.save();
@ -147,7 +153,7 @@ public class ParallaxRegion extends HunkRegion
super.save();
}
public int unload()
public int unload()
{
unloadMetaHunk();
return blockSlice.unloadAll()+
@ -155,7 +161,7 @@ public class ParallaxRegion extends HunkRegion
updateSlice.unloadAll();
}
public HunkRegionSlice<BlockData> getBlockSlice() {
public HunkRegionSlice<BlockData> getBlockSlice() {
lastUse = M.ms();
return blockSlice;
}
@ -165,18 +171,18 @@ public class ParallaxRegion extends HunkRegion
return objectSlice;
}
public HunkRegionSlice<Boolean> getUpdateSlice() {
public HunkRegionSlice<Boolean> getUpdateSlice() {
lastUse = M.ms();
return updateSlice;
}
public int cleanup(long c) {
public synchronized int cleanup(long c) {
return blockSlice.cleanup(c) +
objectSlice.cleanup(c) +
updateSlice.cleanup(c);
}
public int getChunkCount() {
public int getChunkCount() {
return blockSlice.getLoadCount() + objectSlice.getLoadCount() + updateSlice.getLoadCount();
}
}

View File

@ -26,12 +26,12 @@ public class ParallaxWorld implements ParallaxAccess
folder.mkdirs();
}
public int getRegionCount()
public int getRegionCount()
{
return loadedRegions.size();
}
public int getChunkCount()
public int getChunkCount()
{
int m = 0;
@ -43,7 +43,7 @@ public class ParallaxWorld implements ParallaxAccess
}
}
catch(Throwable e)
catch(Throwable ignored)
{
}
@ -51,7 +51,7 @@ public class ParallaxWorld implements ParallaxAccess
return m;
}
public void close()
public void close()
{
for(ParallaxRegion i : loadedRegions.v())
{
@ -62,7 +62,7 @@ public class ParallaxWorld implements ParallaxAccess
loadedRegions.clear();
}
public void save(ParallaxRegion region)
public void save(ParallaxRegion region)
{
try
{
@ -75,12 +75,12 @@ public class ParallaxWorld implements ParallaxAccess
}
}
public boolean isLoaded(int x, int z)
public boolean isLoaded(int x, int z)
{
return loadedRegions.containsKey(key(x, z));
}
public void save(int x, int z)
public void save(int x, int z)
{
if(isLoaded(x, z))
{
@ -88,7 +88,7 @@ public class ParallaxWorld implements ParallaxAccess
}
}
public int unload(int x, int z)
public int unload(int x, int z)
{
long key = key(x, z);
int v = 0;
@ -111,7 +111,7 @@ public class ParallaxWorld implements ParallaxAccess
return v;
}
public ParallaxRegion load(int x, int z)
public ParallaxRegion load(int x, int z)
{
if(isLoaded(x, z))
{
@ -124,7 +124,7 @@ public class ParallaxWorld implements ParallaxAccess
return v;
}
public ParallaxRegion getR(int x, int z)
public ParallaxRegion getR(int x, int z)
{
long key = key(x, z);
@ -138,7 +138,7 @@ public class ParallaxWorld implements ParallaxAccess
return region;
}
public ParallaxRegion getRW(int x, int z)
public ParallaxRegion getRW(int x, int z)
{
save.addIfMissing(key(x, z));
return getR(x, z);
@ -150,60 +150,60 @@ public class ParallaxWorld implements ParallaxAccess
}
@Override
public Hunk<BlockData> getBlocksR(int x, int z)
public Hunk<BlockData> getBlocksR(int x, int z)
{
return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<BlockData> getBlocksRW(int x, int z)
public Hunk<BlockData> getBlocksRW(int x, int z)
{
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<String> getObjectsR(int x, int z)
public Hunk<String> getObjectsR(int x, int z)
{
return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<String> getObjectsRW(int x, int z)
public Hunk<String> getObjectsRW(int x, int z)
{
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<Boolean> getUpdatesR(int x, int z)
public Hunk<Boolean> getUpdatesR(int x, int z)
{
return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<Boolean> getUpdatesRW(int x, int z)
public Hunk<Boolean> getUpdatesRW(int x, int z)
{
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
}
@Override
public ParallaxChunkMeta getMetaR(int x, int z)
public ParallaxChunkMeta getMetaR(int x, int z)
{
return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31);
}
@Override
public ParallaxChunkMeta getMetaRW(int x, int z)
public ParallaxChunkMeta getMetaRW(int x, int z)
{
return getRW(x >> 5, z >> 5).getMetaRW(x & 31, z & 31);
}
public void cleanup()
public void cleanup()
{
cleanup(IrisSettings.get().getParallaxRegionEvictionMS(), IrisSettings.get().getParallax().getParallaxChunkEvictionMS());
}
@Override
public void cleanup(long r, long c) {
public void cleanup(long r, long c) {
J.a(() -> {
try
{
@ -233,12 +233,12 @@ public class ParallaxWorld implements ParallaxAccess
}
@Override
public void saveAll() {
public void saveAll() {
J.a(this::saveAllNOW);
}
@Override
public void saveAllNOW() {
public void saveAllNOW() {
for(ParallaxRegion i : loadedRegions.v())
{
if(save.contains(key(i.getX(), i.getZ())))

View File

@ -1,2 +1,89 @@
package com.volmit.iris.scaffold.parallel;public class GridLock {
package com.volmit.iris.scaffold.parallel;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.util.IORunnable;
import com.volmit.iris.util.NastyRunnable;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
public class GridLock
{
private Hunk<ReentrantLock> locks;
public GridLock(int x, int z)
{
this.locks = Hunk.newAtomicHunk(x, 1, z);
locks.iterateSync((a,b,c) -> locks.set(a,b,c,new ReentrantLock()));
}
public void with(int x, int z, Runnable r)
{
lock(x, z);
r.run();
unlock(x, z);
}
public void withNasty(int x, int z, NastyRunnable r) throws Throwable {
lock(x, z);
r.run();
unlock(x, z);
}
public void withIO(int x, int z, IORunnable r) throws IOException {
lock(x, z);
r.run();
unlock(x, z);
}
public <T> T withResult(int x, int z, Supplier<T> r)
{
lock(x, z);
T t = r.get();
unlock(x, z);
return t;
}
public void withAll(Runnable r)
{
locks.iterateSync((a,b,c,d) -> d.lock());
r.run();
locks.iterateSync((a,b,c,d) -> d.unlock());
}
public <T> T withAllResult(Supplier<T> r)
{
locks.iterateSync((a,b,c,d) -> d.lock());
T t = r.get();
locks.iterateSync((a,b,c,d) -> d.unlock());
return t;
}
public boolean tryLock(int x, int z)
{
return locks.get(x,0,z).tryLock();
}
public boolean tryLock(int x, int z, long timeout)
{
try {
return locks.get(x,0,z).tryLock(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {
}
return false;
}
public void lock(int x, int z)
{
locks.get(x,0,z).lock();
}
public void unlock(int x, int z)
{
locks.get(x,0,z).unlock();
}
}

View File

@ -1,6 +1,8 @@
package com.volmit.iris.util;
public interface NastyRunnable
import java.io.IOException;
public interface IORunnable
{
public void run() throws Throwable;
public void run() throws IOException;
}