From 95ec45d55c70af957d01dcea841bdf8d9ef02b35 Mon Sep 17 00:00:00 2001 From: Roman Alexander Date: Wed, 25 Mar 2015 20:27:13 -0500 Subject: [PATCH] Configurable async light updates diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index b681a9f..f507134 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -18,6 +18,12 @@ import org.bukkit.generator.ChunkGenerator; import java.util.*; import java.util.concurrent.Callable; +// PaperSpigot start +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +// PaperSpigot end + // CraftBukkit start // CraftBukkit end @@ -714,22 +720,26 @@ public abstract class World implements IBlockAccess { blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); } + // PaperSpigot start - configurable async light updates if (!this.isValidLocation(blockposition)) { return enumskyblock.c; - } else if (!this.isLoaded(blockposition)) { + } + + Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk == null) { return enumskyblock.c; } else { - Chunk chunk = this.getChunkAtWorldCoords(blockposition); - + // PaperSpigot end return chunk.getBrightness(enumskyblock, blockposition); } } public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { if (this.isValidLocation(blockposition)) { - if (this.isLoaded(blockposition)) { - Chunk chunk = this.getChunkAtWorldCoords(blockposition); - + // PaperSpigot start - Configurable async light updates + Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk != null) { + // PaperSpigot end chunk.a(enumskyblock, blockposition, i); this.n(blockposition); } @@ -2316,10 +2326,13 @@ public abstract class World implements IBlockAccess { } private int a(BlockPosition blockposition, EnumSkyBlock enumskyblock) { - if (enumskyblock == EnumSkyBlock.SKY && this.i(blockposition)) { + // PaperSpigot start - Configurable async light updates + Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk == null || (enumskyblock == EnumSkyBlock.SKY && chunk.d(blockposition))) { + // PaperSpigot end return 15; } else { - Block block = this.getType(blockposition).getBlock(); + Block block = chunk.getType(blockposition); // PaperSpigot - Configurable async light updates int i = enumskyblock == EnumSkyBlock.SKY ? 0 : block.r(); int j = block.p(); @@ -2358,131 +2371,154 @@ public abstract class World implements IBlockAccess { } } - public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - // CraftBukkit start - Use neighbor cache instead of looking up - Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); - if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) { - // CraftBukkit end - return false; - } else { - int i = 0; - int j = 0; - - this.methodProfiler.a("getBrightness"); - int k = this.b(enumskyblock, blockposition); - int l = this.a(blockposition, enumskyblock); - int i1 = blockposition.getX(); - int j1 = blockposition.getY(); - int k1 = blockposition.getZ(); - int l1; - int i2; - int j2; - int k2; - int l2; - int i3; - int j3; - int k3; - - if (l > k) { - this.H[j++] = 133152; - } else if (l < k) { - this.H[j++] = 133152 | k << 18; - - while (i < j) { - l1 = this.H[i++]; - i2 = (l1 & 63) - 32 + i1; - j2 = (l1 >> 6 & 63) - 32 + j1; - k2 = (l1 >> 12 & 63) - 32 + k1; - int l3 = l1 >> 18 & 15; - BlockPosition blockposition1 = new BlockPosition(i2, j2, k2); - - l2 = this.b(enumskyblock, blockposition1); - if (l2 == l3) { - this.a(enumskyblock, blockposition1, 0); - if (l3 > 0) { - i3 = MathHelper.a(i2 - i1); - j3 = MathHelper.a(j2 - j1); - k3 = MathHelper.a(k2 - k1); - if (i3 + j3 + k3 < 17) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - EnumDirection[] aenumdirection = EnumDirection.values(); - int i4 = aenumdirection.length; - - for (int j4 = 0; j4 < i4; ++j4) { - EnumDirection enumdirection = aenumdirection[j4]; - int k4 = i2 + enumdirection.getAdjacentX(); - int l4 = j2 + enumdirection.getAdjacentY(); - int i5 = k2 + enumdirection.getAdjacentZ(); - - blockposition_mutableblockposition.c(k4, l4, i5); - int j5 = Math.max(1, this.getType(blockposition_mutableblockposition).getBlock().p()); - - l2 = this.b(enumskyblock, (BlockPosition) blockposition_mutableblockposition); - if (l2 == l3 - j5 && j < this.H.length) { - this.H[j++] = k4 - i1 + 32 | l4 - j1 + 32 << 6 | i5 - k1 + 32 << 12 | l3 - j5 << 18; + // PaperSpigot start - Configurable async light updates + private ExecutorService service = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); + public boolean c(final EnumSkyBlock enumskyblock, final BlockPosition blockposition) { + Callable callable = new Callable() { + @Override + public Boolean call() throws Exception { + // CraftBukkit start - Use neighbor cache instead of looking up + Chunk chunk = World.this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) { + // CraftBukkit end + return false; + } else { + int i = 0; + int j = 0; + + World.this.methodProfiler.a("getBrightness"); + int k = World.this.b(enumskyblock, blockposition); + int l = World.this.a(blockposition, enumskyblock); + int i1 = blockposition.getX(); + int j1 = blockposition.getY(); + int k1 = blockposition.getZ(); + int l1; + int i2; + int j2; + int k2; + int l2; + int i3; + int j3; + int k3; + + if (l > k) { + World.this.H[j++] = 133152; + } else if (l < k) { + World.this.H[j++] = 133152 | k << 18; + + while (i < j) { + l1 = World.this.H[i++]; + i2 = (l1 & 63) - 32 + i1; + j2 = (l1 >> 6 & 63) - 32 + j1; + k2 = (l1 >> 12 & 63) - 32 + k1; + int l3 = l1 >> 18 & 15; + BlockPosition blockposition1 = new BlockPosition(i2, j2, k2); + + l2 = World.this.b(enumskyblock, blockposition1); + if (l2 == l3) { + World.this.a(enumskyblock, blockposition1, 0); + if (l3 > 0) { + i3 = MathHelper.a(i2 - i1); + j3 = MathHelper.a(j2 - j1); + k3 = MathHelper.a(k2 - k1); + if (i3 + j3 + k3 < 17) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + EnumDirection[] aenumdirection = EnumDirection.values(); + int i4 = aenumdirection.length; + + for (int j4 = 0; j4 < i4; ++j4) { + EnumDirection enumdirection = aenumdirection[j4]; + int k4 = i2 + enumdirection.getAdjacentX(); + int l4 = j2 + enumdirection.getAdjacentY(); + int i5 = k2 + enumdirection.getAdjacentZ(); + + blockposition_mutableblockposition.c(k4, l4, i5); + Chunk lightChunk = World.this.getChunkIfLoaded(blockposition_mutableblockposition.getX() >> 4, blockposition_mutableblockposition.getZ() >> 4); + int j5; + if (lightChunk != null) { + j5 = Math.max(1, lightChunk.getType(blockposition_mutableblockposition).p()); + } else { + j5 = 255; + } + + l2 = World.this.b(enumskyblock, (BlockPosition) blockposition_mutableblockposition); + if (l2 == l3 - j5 && j < World.this.H.length) { + World.this.H[j++] = k4 - i1 + 32 | l4 - j1 + 32 << 6 | i5 - k1 + 32 << 12 | l3 - j5 << 18; + } + } } } } } - } - } - i = 0; - } + i = 0; + } - this.methodProfiler.b(); - this.methodProfiler.a("checkedPosition < toCheckCount"); - - while (i < j) { - l1 = this.H[i++]; - i2 = (l1 & 63) - 32 + i1; - j2 = (l1 >> 6 & 63) - 32 + j1; - k2 = (l1 >> 12 & 63) - 32 + k1; - BlockPosition blockposition2 = new BlockPosition(i2, j2, k2); - int k5 = this.b(enumskyblock, blockposition2); - - l2 = this.a(blockposition2, enumskyblock); - if (l2 != k5) { - this.a(enumskyblock, blockposition2, l2); - if (l2 > k5) { - i3 = Math.abs(i2 - i1); - j3 = Math.abs(j2 - j1); - k3 = Math.abs(k2 - k1); - boolean flag = j < this.H.length - 6; - - if (i3 + j3 + k3 < 17 && flag) { - if (this.b(enumskyblock, blockposition2.west()) < l2) { - this.H[j++] = i2 - 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } + World.this.methodProfiler.b(); + World.this.methodProfiler.a("checkedPosition < toCheckCount"); + + while (i < j) { + l1 = World.this.H[i++]; + i2 = (l1 & 63) - 32 + i1; + j2 = (l1 >> 6 & 63) - 32 + j1; + k2 = (l1 >> 12 & 63) - 32 + k1; + BlockPosition blockposition2 = new BlockPosition(i2, j2, k2); + int k5 = World.this.b(enumskyblock, blockposition2); + + l2 = World.this.a(blockposition2, enumskyblock); + if (l2 != k5) { + World.this.a(enumskyblock, blockposition2, l2); + if (l2 > k5) { + i3 = Math.abs(i2 - i1); + j3 = Math.abs(j2 - j1); + k3 = Math.abs(k2 - k1); + boolean flag = j < World.this.H.length - 6; + + if (i3 + j3 + k3 < 17 && flag) { + if (World.this.b(enumskyblock, blockposition2.west()) < l2) { + World.this.H[j++] = i2 - 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } - if (this.b(enumskyblock, blockposition2.east()) < l2) { - this.H[j++] = i2 + 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } + if (World.this.b(enumskyblock, blockposition2.east()) < l2) { + World.this.H[j++] = i2 + 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } - if (this.b(enumskyblock, blockposition2.down()) < l2) { - this.H[j++] = i2 - i1 + 32 + (j2 - 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } + if (World.this.b(enumskyblock, blockposition2.down()) < l2) { + World.this.H[j++] = i2 - i1 + 32 + (j2 - 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } - if (this.b(enumskyblock, blockposition2.up()) < l2) { - this.H[j++] = i2 - i1 + 32 + (j2 + 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } + if (World.this.b(enumskyblock, blockposition2.up()) < l2) { + World.this.H[j++] = i2 - i1 + 32 + (j2 + 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } - if (this.b(enumskyblock, blockposition2.north()) < l2) { - this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - 1 - k1 + 32 << 12); - } + if (World.this.b(enumskyblock, blockposition2.north()) < l2) { + World.this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - 1 - k1 + 32 << 12); + } - if (this.b(enumskyblock, blockposition2.south()) < l2) { - this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 + 1 - k1 + 32 << 12); + if (World.this.b(enumskyblock, blockposition2.south()) < l2) { + World.this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 + 1 - k1 + 32 << 12); + } + } } } } + + World.this.methodProfiler.b(); + return true; } } - - this.methodProfiler.b(); - return true; + }; + if (paperSpigotConfig.useAsyncLighting) { + service.submit(callable); + } else { + try { + return callable.call(); + } catch(Exception ignore) { + } } + return true; } + // PaperSpigot end public boolean a(boolean flag) { return false; diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java index bcd8b65..fa9ae6c 100644 --- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java +++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java @@ -244,4 +244,11 @@ public class PaperSpigotWorldConfig log( "WorldServer TickNextTick cap set at " + tickNextTickCap ); log( "WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone ); } + + public boolean useAsyncLighting; + private void useAsyncLighting() + { + useAsyncLighting = getBoolean( "use-async-lighting", false ); + log( "World async lighting: " + useAsyncLighting ); + } } -- 1.9.5.msysgit.1