summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/net/minecraft/server/ChunkProviderServer.java38
-rw-r--r--src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java7
-rw-r--r--src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java20
-rw-r--r--src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java12
4 files changed, 40 insertions, 37 deletions
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 9c991774..bf60f4eb 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -14,6 +14,7 @@ import org.apache.logging.log4j.Logger;
import java.util.Random;
import org.bukkit.Server;
+import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
import org.bukkit.craftbukkit.util.LongHash;
import org.bukkit.craftbukkit.util.LongHashSet;
import org.bukkit.craftbukkit.util.LongObjectHashMap;
@@ -90,20 +91,37 @@ public class ChunkProviderServer implements IChunkProvider {
public Chunk getChunkAt(int i, int j, Runnable runnable) {
this.unloadQueue.remove(i, j);
- Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j));
- boolean newChunk = false;
+ Chunk chunk = this.chunks.get(LongHash.toLong(i, j));
ChunkRegionLoader loader = null;
if (this.f instanceof ChunkRegionLoader) {
loader = (ChunkRegionLoader) this.f;
}
- // If the chunk exists but isn't loaded do it async
- if (chunk == null && runnable != null && loader != null && loader.chunkExists(this.world, i, j)) {
- org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.queueChunkLoad(this.world, loader, this, i, j, runnable);
- return null;
+ // We can only use the queue for already generated chunks
+ if (chunk == null && loader != null && loader.chunkExists(this.world, i, j)) {
+ if (runnable != null) {
+ ChunkIOExecutor.queueChunkLoad(this.world, loader, this, i, j, runnable);
+ return null;
+ } else {
+ chunk = ChunkIOExecutor.syncChunkLoad(this.world, loader, this, i, j);
+ }
+ } else if (chunk == null) {
+ chunk = this.originalGetChunkAt(i, j);
}
- // CraftBukkit end
+
+ // If we didn't load the chunk async and have a callback run it now
+ if (runnable != null) {
+ runnable.run();
+ }
+
+ return chunk;
+ }
+
+ public Chunk originalGetChunkAt(int i, int j) {
+ this.unloadQueue.remove(i, j);
+ Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j));
+ boolean newChunk = false;
if (chunk == null) {
chunk = this.loadChunk(i, j);
@@ -143,12 +161,6 @@ public class ChunkProviderServer implements IChunkProvider {
chunk.a(this, this, i, j);
}
- // CraftBukkit start - If we didn't need to load the chunk run the callback now
- if (runnable != null) {
- runnable.run();
- }
- // CraftBukkit end
-
return chunk;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
index 92fbc4f9..afcf764b 100644
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
@@ -5,7 +5,6 @@ import net.minecraft.server.ChunkProviderServer;
import net.minecraft.server.ChunkRegionLoader;
import net.minecraft.server.World;
import org.bukkit.craftbukkit.util.AsynchronousExecutor;
-import org.bukkit.craftbukkit.util.LongHash;
public class ChunkIOExecutor {
static final int BASE_THREADS = 1;
@@ -13,12 +12,12 @@ public class ChunkIOExecutor {
private static final AsynchronousExecutor<QueuedChunk, Chunk, Runnable, RuntimeException> instance = new AsynchronousExecutor<QueuedChunk, Chunk, Runnable, RuntimeException>(new ChunkIOProvider(), BASE_THREADS);
- public static void waitForChunkLoad(World world, int x, int z) {
- instance.get(new QueuedChunk(LongHash.toLong(x, z), null, world, null));
+ public static Chunk syncChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z) {
+ return instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider));
}
public static void queueChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) {
- instance.add(new QueuedChunk(LongHash.toLong(x, z), loader, world, provider), runnable);
+ instance.add(new QueuedChunk(x, z, loader, world, provider), runnable);
}
public static void adjustPoolSize(int players) {
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
index b9de12d8..8feadd11 100644
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
@@ -16,7 +16,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
// async stuff
public Chunk callStage1(QueuedChunk queuedChunk) throws RuntimeException {
ChunkRegionLoader loader = queuedChunk.loader;
- Object[] data = loader.loadChunk(queuedChunk.world, LongHash.msw(queuedChunk.coords), LongHash.lsw(queuedChunk.coords));
+ Object[] data = loader.loadChunk(queuedChunk.world, queuedChunk.x, queuedChunk.z);
if (data != null) {
queuedChunk.compound = (NBTTagCompound) data[1];
@@ -30,27 +30,17 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
public void callStage2(QueuedChunk queuedChunk, Chunk chunk) throws RuntimeException {
if(chunk == null) {
// If the chunk loading failed just do it synchronously (may generate)
- queuedChunk.provider.getChunkAt(LongHash.msw(queuedChunk.coords), LongHash.lsw(queuedChunk.coords));
- return;
- }
-
- int x = LongHash.msw(queuedChunk.coords);
- int z = LongHash.lsw(queuedChunk.coords);
-
- // See if someone already loaded this chunk while we were working on it (API, etc)
- if (queuedChunk.provider.chunks.containsKey(queuedChunk.coords)) {
- // Make sure it isn't queued for unload, we need it
- queuedChunk.provider.unloadQueue.remove(queuedChunk.coords);
+ queuedChunk.provider.originalGetChunkAt(queuedChunk.x, queuedChunk.z);
return;
}
queuedChunk.loader.loadEntities(chunk, queuedChunk.compound.getCompound("Level"), queuedChunk.world);
chunk.p = queuedChunk.provider.world.getTime();
- queuedChunk.provider.chunks.put(queuedChunk.coords, chunk);
+ queuedChunk.provider.chunks.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk);
chunk.addEntities();
if (queuedChunk.provider.chunkProvider != null) {
- queuedChunk.provider.chunkProvider.recreateStructures(x, z);
+ queuedChunk.provider.chunkProvider.recreateStructures(queuedChunk.x, queuedChunk.z);
}
Server server = queuedChunk.provider.world.getServer();
@@ -58,7 +48,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false));
}
- chunk.a(queuedChunk.provider, queuedChunk.provider, x, z);
+ chunk.a(queuedChunk.provider, queuedChunk.provider, queuedChunk.x, queuedChunk.z);
}
public void callStage3(QueuedChunk queuedChunk, Chunk chunk, Runnable runnable) throws RuntimeException {
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java b/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java
index 77f56619..842d424f 100644
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java
@@ -6,14 +6,16 @@ import net.minecraft.server.NBTTagCompound;
import net.minecraft.server.World;
class QueuedChunk {
- final long coords;
+ final int x;
+ final int z;
final ChunkRegionLoader loader;
final World world;
final ChunkProviderServer provider;
NBTTagCompound compound;
- public QueuedChunk(long coords, ChunkRegionLoader loader, World world, ChunkProviderServer provider) {
- this.coords = coords;
+ public QueuedChunk(int x, int z, ChunkRegionLoader loader, World world, ChunkProviderServer provider) {
+ this.x = x;
+ this.z = z;
this.loader = loader;
this.world = world;
this.provider = provider;
@@ -21,14 +23,14 @@ class QueuedChunk {
@Override
public int hashCode() {
- return (int) coords ^ world.hashCode();
+ return (x * 31 + z * 29) ^ world.hashCode();
}
@Override
public boolean equals(Object object) {
if (object instanceof QueuedChunk) {
QueuedChunk other = (QueuedChunk) object;
- return coords == other.coords && world == other.world;
+ return x == other.x && z == other.z && world == other.world;
}
return false;