From bd62ccc04cc05df84e7346871b4e13ce6518c081 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Tue, 19 Apr 2011 07:50:17 +0000 Subject: [PATCH] Switched chunks to factory method, allowing them to be created with or without automatic validation (some ops, like copy, no longer perform unnecessary validation). Skylight recalculation optimization, cuts runtime of flatmap example by two thirds. --- Substrate/SubstrateCS/Source/BlockManager.cs | 2 +- Substrate/SubstrateCS/Source/Chunk.cs | 38 +++++++++++------ .../SubstrateCS/Source/ChunkFileManager.cs | 4 +- Substrate/SubstrateCS/Source/ChunkRef.cs | 41 +++++++++++++++---- Substrate/SubstrateCS/Source/Region.cs | 4 +- 5 files changed, 65 insertions(+), 24 deletions(-) diff --git a/Substrate/SubstrateCS/Source/BlockManager.cs b/Substrate/SubstrateCS/Source/BlockManager.cs index 360d128..45fa3c1 100644 --- a/Substrate/SubstrateCS/Source/BlockManager.cs +++ b/Substrate/SubstrateCS/Source/BlockManager.cs @@ -40,7 +40,7 @@ namespace Substrate { _chunkMan = cm; - Chunk c = new Chunk(0, 0); + Chunk c = Chunk.Create(0, 0); _chunkXDim = c.XDim; _chunkYDim = c.YDim; diff --git a/Substrate/SubstrateCS/Source/Chunk.cs b/Substrate/SubstrateCS/Source/Chunk.cs index 50345f0..2597516 100644 --- a/Substrate/SubstrateCS/Source/Chunk.cs +++ b/Substrate/SubstrateCS/Source/Chunk.cs @@ -64,21 +64,35 @@ namespace Substrate set { _tree.Root["Level"].ToTagCompound()["TerrainPopulated"].ToTagByte().Data = (byte)(value ? 1 : 0); } } - public Chunk (int x, int z) + private Chunk () { - _cx = x; - _cz = z; - - BuildNBTTree(); - - BuildTileEntityCache(); } - public Chunk (NBT_Tree tree) + public static Chunk Create (int x, int z) { - if (LoadTreeSafe(tree.Root) == null) { - throw new InvalidNBTObjectException(); - } + Chunk c = new Chunk(); + + c._cx = x; + c._cz = z; + + c.BuildNBTTree(); + c.BuildTileEntityCache(); + + return c; + } + + public static Chunk Create (NBT_Tree tree) + { + Chunk c = new Chunk(); + + return c.LoadTree(tree.Root); + } + + public static Chunk CreateVerified (NBT_Tree tree) + { + Chunk c = new Chunk(); + + return c.LoadTreeSafe(tree.Root); } private void BuildNBTTree () @@ -570,7 +584,7 @@ namespace Substrate public Chunk Copy () { - return new Chunk(_tree.Copy()); + return Chunk.Create(_tree.Copy()); } #endregion diff --git a/Substrate/SubstrateCS/Source/ChunkFileManager.cs b/Substrate/SubstrateCS/Source/ChunkFileManager.cs index ae24391..a6ceff6 100644 --- a/Substrate/SubstrateCS/Source/ChunkFileManager.cs +++ b/Substrate/SubstrateCS/Source/ChunkFileManager.cs @@ -92,7 +92,7 @@ namespace Substrate return null; } - return new Chunk(GetChunkTree(cx, cz)); + return Chunk.CreateVerified(GetChunkTree(cx, cz)); } public ChunkRef GetChunkRef (int cx, int cz) @@ -124,7 +124,7 @@ namespace Substrate public ChunkRef CreateChunk (int cx, int cz) { DeleteChunk(cx, cz); - Chunk c = new Chunk(cx, cz); + Chunk c = Chunk.Create(cx, cz); c.Save(GetChunkOutStream(cx, cz)); ChunkRef cr = ChunkRef.Create(this, this, cx, cz); diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs index b008b5d..bb7738b 100644 --- a/Substrate/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/SubstrateCS/Source/ChunkRef.cs @@ -52,12 +52,8 @@ namespace Substrate get { return _dirty; } } - private ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz) + private ChunkRef () { - _container = container; - _cache = cache; - _cx = cx; - _cz = cz; } public static ChunkRef Create (IChunkContainer container, IChunkCache cache, int cx, int cz) @@ -66,7 +62,14 @@ namespace Substrate return null; } - return new ChunkRef(container, cache, cx, cz); + ChunkRef c = new ChunkRef(); + + c._container = container; + c._cache = cache; + c._cx = cx; + c._cz = cz; + + return c; } public int BlockGlobalX (int x) @@ -480,9 +483,33 @@ namespace Substrate { GetChunk(); + // Optimization - only need to queue at level of highest neighbor's height for (int x = 0; x < XDim; x++) { for (int z = 0; z < ZDim; z++) { - QueueRelight(new BlockKey(x, YDim - 1, z)); + ChunkRef ce = LocalChunk(x, 0, z - 1); + ChunkRef cn = LocalChunk(x - 1, 0, z); + ChunkRef cs = LocalChunk(x + 1, 0, z); + ChunkRef cw = LocalChunk(x, 0, z + 1); + + int h = GetHeight(x, z); + if (ce != null) { + h = Math.Max(h, ce.GetHeight(x, ZDim - 1)); + } + if (cn != null) { + h = Math.Max(h, cn.GetHeight(XDim - 1, z)); + } + if (cs != null) { + h = Math.Max(h, cs.GetHeight(0, z)); + } + if (cw != null) { + h = Math.Max(h, cw.GetHeight(x, 0)); + } + + for (int y = h; y < YDim; y++) { + SetBlockSkyLight(x, y, z, BlockInfo.MAX_LUMINANCE); + } + + QueueRelight(new BlockKey(x, h, z)); } } diff --git a/Substrate/SubstrateCS/Source/Region.cs b/Substrate/SubstrateCS/Source/Region.cs index 8cde017..d854d46 100644 --- a/Substrate/SubstrateCS/Source/Region.cs +++ b/Substrate/SubstrateCS/Source/Region.cs @@ -257,7 +257,7 @@ namespace Substrate int cx = lcx + _rx * ChunkManager.REGION_XLEN; int cz = lcz + _rz * ChunkManager.REGION_ZLEN; - Chunk c = new Chunk(cx, cz); + Chunk c = Chunk.Create(cx, cz); c.Save(GetChunkOutStream(lcx, lcz)); ChunkRef cr = ChunkRef.Create(this, _cache, lcx, lcz); @@ -300,7 +300,7 @@ namespace Substrate return null; } - return new Chunk(GetChunkTree(lcx, lcz)); + return Chunk.CreateVerified(GetChunkTree(lcx, lcz)); } public bool ChunkExists (int lcx, int lcz)