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