diff options
author | Travis Watkins <amaranth@ubuntu.com> | 2014-02-01 17:42:43 -0600 |
---|---|---|
committer | Travis Watkins <amaranth@ubuntu.com> | 2014-02-01 22:03:04 -0600 |
commit | d7d81fa68fb439c41547d347dd099261ff28af17 (patch) | |
tree | d757441b136df4ebd99c559f138ab958c075f388 /src/main/java/net/minecraft/server/ChunkProviderServer.java | |
parent | 4a6a81e72412d822f6047c0139524203081fad6f (diff) | |
download | craftbukkit-d7d81fa68fb439c41547d347dd099261ff28af17.tar craftbukkit-d7d81fa68fb439c41547d347dd099261ff28af17.tar.gz craftbukkit-d7d81fa68fb439c41547d347dd099261ff28af17.tar.lz craftbukkit-d7d81fa68fb439c41547d347dd099261ff28af17.tar.xz craftbukkit-d7d81fa68fb439c41547d347dd099261ff28af17.zip |
Load all already generated chunks via async chunk system
Currently we use the async chunk loading system only when players trigger
chunk loading. If a chunk is loaded for any other reason it goes through
a separate codepath. This means if a player has trigged a chunk load and
before the chunk loads something else wants the same chunk we will load it
twice and throw away the second result. With this change we instead use
the sync processing feature of the AsynchronousExecutor to load the chunk
which will pull it out of the queue if it was already queued to load. This
means we only ever load a chunk once. Because chunk generation is not
thread safe we still fallback to the vanilla chunk loading system if the
chunk does not currently exist.
Diffstat (limited to 'src/main/java/net/minecraft/server/ChunkProviderServer.java')
-rw-r--r-- | src/main/java/net/minecraft/server/ChunkProviderServer.java | 38 |
1 files changed, 25 insertions, 13 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; } |