mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Locking
This commit is contained in:
parent
73bfa9beb8
commit
4a30b6d264
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.volmit</groupId>
|
<groupId>com.volmit</groupId>
|
||||||
<artifactId>Iris</artifactId>
|
<artifactId>Iris</artifactId>
|
||||||
<version>1.2.3</version>
|
<version>1.2.4-hotfix1</version>
|
||||||
<name>Iris</name>
|
<name>Iris</name>
|
||||||
<properties>
|
<properties>
|
||||||
<skip.copy>false</skip.copy>
|
<skip.copy>false</skip.copy>
|
||||||
|
@ -292,6 +292,7 @@ public class Iris extends VolmitPlugin
|
|||||||
@Override
|
@Override
|
||||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
||||||
{
|
{
|
||||||
|
//TODO: Support ID
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return INMS.get().createWorld(new IrisWorldCreator()
|
return INMS.get().createWorld(new IrisWorldCreator()
|
||||||
|
@ -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> 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> 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;
|
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().getBiomeActuator().actuate(x, z, vbiomes);
|
||||||
getFramework().getTerrainActuator().actuate(x, z, blocks);
|
getFramework().getTerrainActuator().actuate(x, z, blocks);
|
||||||
getFramework().getCaveModifier().modify(x, z, blocks);
|
getFramework().getCaveModifier().modify(x, z, blocks);
|
||||||
|
@ -2,6 +2,7 @@ package com.volmit.iris.manager.command;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.manager.IrisDataManager;
|
import com.volmit.iris.manager.IrisDataManager;
|
||||||
|
import com.volmit.iris.manager.link.MultiverseCoreLink;
|
||||||
import com.volmit.iris.nms.INMS;
|
import com.volmit.iris.nms.INMS;
|
||||||
import com.volmit.iris.object.IrisDimension;
|
import com.volmit.iris.object.IrisDimension;
|
||||||
import com.volmit.iris.pregen.Pregenerator;
|
import com.volmit.iris.pregen.Pregenerator;
|
||||||
@ -58,6 +59,16 @@ public class CommandIrisCreate extends MortarCommand
|
|||||||
if(multiverse)
|
if(multiverse)
|
||||||
{
|
{
|
||||||
dim = IrisDataManager.loadAnyDimension(type);
|
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());
|
String command = "mv create " + worldName + " " + Iris.linkMultiverseCore.envName(dim.getEnvironment());
|
||||||
command += " -s " + seed;
|
command += " -s " + seed;
|
||||||
command += " -g Iris";
|
command += " -g Iris";
|
||||||
|
@ -133,6 +133,11 @@ public class MultiverseCoreLink
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String envName(World.Environment environment) {
|
public String envName(World.Environment environment) {
|
||||||
|
if(environment == null)
|
||||||
|
{
|
||||||
|
return "normal";
|
||||||
|
}
|
||||||
|
|
||||||
switch(environment)
|
switch(environment)
|
||||||
{
|
{
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.volmit.iris.pregen;
|
package com.volmit.iris.pregen;
|
||||||
|
|
||||||
import com.sun.javafx.scene.control.skin.TableHeaderRow;
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.IrisSettings;
|
import com.volmit.iris.IrisSettings;
|
||||||
import com.volmit.iris.scaffold.IrisWorlds;
|
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) {
|
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 mca = new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca");
|
||||||
File mcg = directWriter.getMCAFile(x, z);
|
File mcg = directWriter.getMCAFile(x, z);
|
||||||
Path fileToMovePath = Paths.get(mcg.toURI());
|
Path fileToMovePath = Paths.get(mcg.toURI());
|
||||||
|
@ -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)
|
default void forEachFeature(double x, double z, Consumer<IrisFeaturePositional> f)
|
||||||
{
|
{
|
||||||
for(IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures())
|
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)
|
default void generateParallaxArea(int x, int z)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
generateParallaxAreaFeatures(x, z);
|
||||||
int s = (int) Math.ceil(getParallaxSize() / 2D);
|
int s = (int) Math.ceil(getParallaxSize() / 2D);
|
||||||
int i,j;
|
int i,j;
|
||||||
generateParallaxAreaFeatures(x, z);
|
|
||||||
|
|
||||||
for(i = -s; i <= s; i++)
|
for (i = -s; i <= s; i++) {
|
||||||
{
|
for (j = -s; j <= s; j++) {
|
||||||
int ii = i;
|
generateParallaxLayer(i +x, j +z);
|
||||||
for(j = -s; j <= s; j++)
|
|
||||||
{
|
|
||||||
int jj = j;
|
|
||||||
generateParallaxLayer((ii*16)+x, (jj*16)+z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getParallaxAccess().setChunkGenerated(x>>4, z>>4);
|
getParallaxAccess().setChunkGenerated(x, z);
|
||||||
p.end();
|
p.end();
|
||||||
getEngine().getMetrics().getParallax().put(p.getMilliseconds());
|
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)
|
default void generateParallaxLayer(int x, int z, boolean force)
|
||||||
{
|
{
|
||||||
if(!force && getParallaxAccess().isParallaxGenerated(x >> 4, z >> 4))
|
if(!force && getParallaxAccess().isParallaxGenerated(x, z))
|
||||||
{
|
{
|
||||||
return;
|
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());
|
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed());
|
||||||
IrisRegion region = getComplex().getRegionStream().get(x+8, z+8);
|
IrisRegion region = getComplex().getRegionStream().get(xx+8, zz+8);
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStream().get(x+8, z+8);
|
IrisBiome biome = getComplex().getTrueBiomeStream().get(xx+8, zz+8);
|
||||||
generateParallaxSurface(rng, x, z, biome);
|
generateParallaxSurface(rng, x, z, biome);
|
||||||
generateParallaxMutations(rng, x, z);
|
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)
|
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)))
|
if(rng.chance(i.getChance()) && rng.chance(getComplex().getObjectChanceStream().get(x, z)))
|
||||||
{
|
{
|
||||||
place(rng, x, z, i);
|
place(rng, x<<4, z<<4, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,13 @@ package com.volmit.iris.scaffold.hunk.io;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||||
import com.volmit.iris.scaffold.parallel.BurstExecutor;
|
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.scaffold.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.*;
|
import com.volmit.iris.util.*;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class HunkRegionSlice<T>
|
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<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);
|
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 Function3<Integer, Integer, Integer, Hunk<T>> factory;
|
||||||
|
private final GridLock lock;
|
||||||
private final HunkIOAdapter<T> adapter;
|
private final HunkIOAdapter<T> adapter;
|
||||||
private final CompoundTag compound;
|
private final CompoundTag compound;
|
||||||
private final String key;
|
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)
|
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.height = height;
|
||||||
this.loadedChunks = new KMap<>();
|
this.loadedChunks = new KMap<>();
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
@ -35,7 +39,7 @@ public class HunkRegionSlice<T>
|
|||||||
this.lastUse = new KMap<>();
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int cleanup(long t)
|
public synchronized int cleanup(long t)
|
||||||
{
|
{
|
||||||
int v = 0;
|
int v = 0;
|
||||||
if(loadedChunks.size() != lastUse.size())
|
if(loadedChunks.size() != lastUse.size())
|
||||||
@ -64,7 +68,7 @@ public class HunkRegionSlice<T>
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear()
|
public synchronized void clear()
|
||||||
{
|
{
|
||||||
for(String i : new KList<>(compound.getValue().keySet()))
|
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();
|
BurstExecutor e = MultiBurst.burst.burst();
|
||||||
for(ChunkPosition i : save.copy())
|
for(ChunkPosition i : save.copy())
|
||||||
@ -89,7 +93,7 @@ public class HunkRegionSlice<T>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
save.remove(i);
|
lock.withNasty(i.getX(), i.getZ(), () -> save.remove(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
catch(Throwable ef)
|
catch(Throwable ef)
|
||||||
@ -101,35 +105,56 @@ public class HunkRegionSlice<T>
|
|||||||
e.complete();
|
e.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(int x, int z)
|
public boolean contains(int x, int z)
|
||||||
{
|
{
|
||||||
return compound.getValue().containsKey(key(x, 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;
|
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;
|
int v = 0;
|
||||||
for(ChunkPosition i : loadedChunks.k())
|
for(ChunkPosition i : loadedChunks.k())
|
||||||
@ -148,7 +173,7 @@ public class HunkRegionSlice<T>
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
write(region, x, z);
|
lock.withIO(x, z, () -> write(region, x, z));
|
||||||
}
|
}
|
||||||
catch(IOException e)
|
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)
|
public void save(int x, int z)
|
||||||
{
|
{
|
||||||
if(isLoaded(x, z))
|
lock.with(x, z, () -> {
|
||||||
{
|
if(isLoaded(x, z))
|
||||||
save(get(x, z), 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);
|
lock.with(x, z, () -> {
|
||||||
if(isLoaded(x, z))
|
ChunkPosition key = new ChunkPosition(x, z);
|
||||||
{
|
if(isLoaded(x, z))
|
||||||
if(save.contains(key))
|
|
||||||
{
|
{
|
||||||
save(x, z);
|
if(save.contains(key))
|
||||||
save.remove(key);
|
{
|
||||||
}
|
save(x, z);
|
||||||
|
save.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
lastUse.remove(key);
|
lastUse.remove(key);
|
||||||
loadedChunks.remove(key);
|
loadedChunks.remove(key);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hunk<T> load(int x, int z)
|
public Hunk<T> load(int x, int z)
|
||||||
{
|
{
|
||||||
if(isLoaded(x, z))
|
return lock.withResult(x, z, () -> {
|
||||||
{
|
if(isLoaded(x, z))
|
||||||
return loadedChunks.get(new ChunkPosition(x, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Hunk<T> v = null;
|
|
||||||
|
|
||||||
if(contains(x, z))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
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)
|
if(v == null)
|
||||||
{
|
{
|
||||||
v = factory.apply(16, height, 16);
|
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)
|
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)
|
if(c == null)
|
||||||
{
|
{
|
||||||
c = load(x, z);
|
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)
|
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)
|
public Hunk<T> getRW(int x, int z)
|
||||||
{
|
{
|
||||||
save.addIfMissing(new ChunkPosition(x, z));
|
return lock.withResult(x, z, () -> {
|
||||||
return get(x, z);
|
save.addIfMissing(new ChunkPosition(x, z));
|
||||||
|
return get(x, z);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String key(int x, int z)
|
private String key(int x, int z)
|
||||||
@ -254,7 +289,7 @@ public class HunkRegionSlice<T>
|
|||||||
return key + "." + x + "." + z;
|
return key + "." + x + "." + z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoadCount()
|
public int getLoadCount()
|
||||||
{
|
{
|
||||||
return loadedChunks.size();
|
return loadedChunks.size();
|
||||||
}
|
}
|
||||||
|
@ -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.HunkIOAdapter;
|
||||||
import com.volmit.iris.scaffold.hunk.io.HunkRegion;
|
import com.volmit.iris.scaffold.hunk.io.HunkRegion;
|
||||||
import com.volmit.iris.scaffold.hunk.io.HunkRegionSlice;
|
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.ByteArrayTag;
|
||||||
import com.volmit.iris.util.CompoundTag;
|
import com.volmit.iris.util.CompoundTag;
|
||||||
import com.volmit.iris.util.M;
|
import com.volmit.iris.util.M;
|
||||||
@ -21,6 +22,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
private HunkRegionSlice<BlockData> blockSlice;
|
private HunkRegionSlice<BlockData> blockSlice;
|
||||||
private HunkRegionSlice<String> objectSlice;
|
private HunkRegionSlice<String> objectSlice;
|
||||||
private HunkRegionSlice<Boolean> updateSlice;
|
private HunkRegionSlice<Boolean> updateSlice;
|
||||||
|
private final GridLock lock;
|
||||||
private long lastUse;
|
private long lastUse;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
@ -29,6 +31,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
super(folder, x, z, compound);
|
super(folder, x, z, compound);
|
||||||
this.height = height;
|
this.height = height;
|
||||||
setupSlices();
|
setupSlices();
|
||||||
|
lock = new GridLock(32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParallaxRegion(int height, File folder, int x, int z)
|
public ParallaxRegion(int height, File folder, int x, int z)
|
||||||
@ -36,6 +39,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
super(folder, x, z);
|
super(folder, x, z);
|
||||||
this.height = height;
|
this.height = height;
|
||||||
setupSlices();
|
setupSlices();
|
||||||
|
lock = new GridLock(32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSlices()
|
private void setupSlices()
|
||||||
@ -49,28 +53,30 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
lastUse = M.ms();
|
lastUse = M.ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasBeenIdleLongerThan(long time)
|
public boolean hasBeenIdleLongerThan(long time)
|
||||||
{
|
{
|
||||||
return M.ms() - lastUse > 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)
|
public ParallaxChunkMeta getMetaRW(int x, int z)
|
||||||
{
|
{
|
||||||
lastUse = M.ms();
|
return lock.withResult(x, z, () -> {
|
||||||
dirtyMeta = true;
|
lastUse = M.ms();
|
||||||
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
|
dirtyMeta = true;
|
||||||
if(p == null)
|
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
|
||||||
{
|
if(p == null)
|
||||||
p = new ParallaxChunkMeta();
|
{
|
||||||
getMetaHunkRW().set(x,0,z,p);
|
p = new ParallaxChunkMeta();
|
||||||
}
|
getMetaHunkRW().set(x,0,z,p);
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Hunk<ParallaxChunkMeta> getMetaHunkR()
|
private Hunk<ParallaxChunkMeta> getMetaHunkR()
|
||||||
@ -89,7 +95,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
return getMetaHunkR();
|
return getMetaHunkR();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hunk<ParallaxChunkMeta> loadMetaHunk()
|
private Hunk<ParallaxChunkMeta> loadMetaHunk()
|
||||||
{
|
{
|
||||||
lastUse = M.ms();
|
lastUse = M.ms();
|
||||||
if(meta == null)
|
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();
|
blockSlice.save();
|
||||||
objectSlice.save();
|
objectSlice.save();
|
||||||
@ -147,7 +153,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
super.save();
|
super.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int unload()
|
public int unload()
|
||||||
{
|
{
|
||||||
unloadMetaHunk();
|
unloadMetaHunk();
|
||||||
return blockSlice.unloadAll()+
|
return blockSlice.unloadAll()+
|
||||||
@ -155,7 +161,7 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
updateSlice.unloadAll();
|
updateSlice.unloadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HunkRegionSlice<BlockData> getBlockSlice() {
|
public HunkRegionSlice<BlockData> getBlockSlice() {
|
||||||
lastUse = M.ms();
|
lastUse = M.ms();
|
||||||
return blockSlice;
|
return blockSlice;
|
||||||
}
|
}
|
||||||
@ -165,18 +171,18 @@ public class ParallaxRegion extends HunkRegion
|
|||||||
return objectSlice;
|
return objectSlice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HunkRegionSlice<Boolean> getUpdateSlice() {
|
public HunkRegionSlice<Boolean> getUpdateSlice() {
|
||||||
lastUse = M.ms();
|
lastUse = M.ms();
|
||||||
return updateSlice;
|
return updateSlice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int cleanup(long c) {
|
public synchronized int cleanup(long c) {
|
||||||
return blockSlice.cleanup(c) +
|
return blockSlice.cleanup(c) +
|
||||||
objectSlice.cleanup(c) +
|
objectSlice.cleanup(c) +
|
||||||
updateSlice.cleanup(c);
|
updateSlice.cleanup(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChunkCount() {
|
public int getChunkCount() {
|
||||||
return blockSlice.getLoadCount() + objectSlice.getLoadCount() + updateSlice.getLoadCount();
|
return blockSlice.getLoadCount() + objectSlice.getLoadCount() + updateSlice.getLoadCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,12 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
folder.mkdirs();
|
folder.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionCount()
|
public int getRegionCount()
|
||||||
{
|
{
|
||||||
return loadedRegions.size();
|
return loadedRegions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChunkCount()
|
public int getChunkCount()
|
||||||
{
|
{
|
||||||
int m = 0;
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
for(ParallaxRegion i : loadedRegions.v())
|
for(ParallaxRegion i : loadedRegions.v())
|
||||||
{
|
{
|
||||||
@ -62,7 +62,7 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
loadedRegions.clear();
|
loadedRegions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(ParallaxRegion region)
|
public void save(ParallaxRegion region)
|
||||||
{
|
{
|
||||||
try
|
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));
|
return loadedRegions.containsKey(key(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(int x, int z)
|
public void save(int x, int z)
|
||||||
{
|
{
|
||||||
if(isLoaded(x, 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);
|
long key = key(x, z);
|
||||||
int v = 0;
|
int v = 0;
|
||||||
@ -111,7 +111,7 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParallaxRegion load(int x, int z)
|
public ParallaxRegion load(int x, int z)
|
||||||
{
|
{
|
||||||
if(isLoaded(x, z))
|
if(isLoaded(x, z))
|
||||||
{
|
{
|
||||||
@ -124,7 +124,7 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParallaxRegion getR(int x, int z)
|
public ParallaxRegion getR(int x, int z)
|
||||||
{
|
{
|
||||||
long key = key(x, z);
|
long key = key(x, z);
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParallaxRegion getRW(int x, int z)
|
public ParallaxRegion getRW(int x, int z)
|
||||||
{
|
{
|
||||||
save.addIfMissing(key(x, z));
|
save.addIfMissing(key(x, z));
|
||||||
return getR(x, z);
|
return getR(x, z);
|
||||||
@ -150,60 +150,60 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
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());
|
cleanup(IrisSettings.get().getParallaxRegionEvictionMS(), IrisSettings.get().getParallax().getParallaxChunkEvictionMS());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanup(long r, long c) {
|
public void cleanup(long r, long c) {
|
||||||
J.a(() -> {
|
J.a(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -233,12 +233,12 @@ public class ParallaxWorld implements ParallaxAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAll() {
|
public void saveAll() {
|
||||||
J.a(this::saveAllNOW);
|
J.a(this::saveAllNOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAllNOW() {
|
public void saveAllNOW() {
|
||||||
for(ParallaxRegion i : loadedRegions.v())
|
for(ParallaxRegion i : loadedRegions.v())
|
||||||
{
|
{
|
||||||
if(save.contains(key(i.getX(), i.getZ())))
|
if(save.contains(key(i.getX(), i.getZ())))
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.volmit.iris.util;
|
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user