Optimize cold start speed and block loading speed

This commit is contained in:
BruceChen 2022-08-25 01:34:07 +08:00
parent 01ef9a89ca
commit 58eafdfd5c
8 changed files with 147 additions and 127 deletions

View file

@ -20,11 +20,6 @@ namespace MinecraftClient.Mapping
/// </summary>
private readonly Block[,,] blocks = new Block[SizeX, SizeY, SizeZ];
/// <summary>
/// Lock for thread safety
/// </summary>
private readonly ReaderWriterLockSlim blockLock = new ReaderWriterLockSlim();
/// <summary>
/// Read, or set the specified block
/// </summary>
@ -43,15 +38,7 @@ namespace MinecraftClient.Mapping
if (blockZ < 0 || blockZ >= SizeZ)
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
blockLock.EnterReadLock();
try
{
return blocks[blockX, blockY, blockZ];
}
finally
{
blockLock.ExitReadLock();
}
return blocks[blockX, blockY, blockZ];
}
set
{
@ -62,18 +49,22 @@ namespace MinecraftClient.Mapping
if (blockZ < 0 || blockZ >= SizeZ)
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
blockLock.EnterWriteLock();
try
{
blocks[blockX, blockY, blockZ] = value;
}
finally
{
blockLock.ExitWriteLock();
}
blocks[blockX, blockY, blockZ] = value;
}
}
/// <summary>
/// Used when parsing chunks
/// </summary>
/// <param name="blockX">Block X</param>
/// <param name="blockY">Block Y</param>
/// <param name="blockZ">Block Z</param>
/// <param name="block">Block</param>
public void SetWithoutCheck(int blockX, int blockY, int blockZ, Block block)
{
blocks[blockX, blockY, blockZ] = block;
}
/// <summary>
/// Get block at the specified location
/// </summary>

View file

@ -20,11 +20,6 @@ namespace MinecraftClient.Mapping
/// </summary>
private readonly Chunk[] chunks;
/// <summary>
/// Lock for thread safety
/// </summary>
private readonly ReaderWriterLockSlim chunkLock = new ReaderWriterLockSlim();
/// <summary>
/// Create a new ChunkColumn
/// </summary>
@ -44,27 +39,11 @@ namespace MinecraftClient.Mapping
{
get
{
chunkLock.EnterReadLock();
try
{
return chunks[chunkY];
}
finally
{
chunkLock.ExitReadLock();
}
return chunks[chunkY];
}
set
{
chunkLock.EnterWriteLock();
try
{
chunks[chunkY] = value;
}
finally
{
chunkLock.ExitWriteLock();
}
chunks[chunkY] = value;
}
}

View file

@ -14,17 +14,17 @@ namespace MinecraftClient.Mapping
/// <summary>
/// The chunks contained into the Minecraft world
/// </summary>
private Dictionary<int, Dictionary<int, ChunkColumn>> chunks = new Dictionary<int, Dictionary<int, ChunkColumn>>();
private Dictionary<int, Dictionary<int, ChunkColumn>> chunks = new();
/// <summary>
/// The dimension info of the world
/// </summary>
private static Dimension dimension = new Dimension();
private static Dimension dimension = new();
/// <summary>
/// Lock for thread safety
/// </summary>
private readonly ReaderWriterLockSlim chunksLock = new ReaderWriterLockSlim();
private readonly ReaderWriterLockSlim chunksLock = new();
/// <summary>
/// Chunk data parsing progress
@ -109,6 +109,54 @@ namespace MinecraftClient.Mapping
return dimension;
}
/// <summary>
/// Set chunk column at the specified location
/// </summary>
/// <param name="chunkX">ChunkColumn X</param>
/// <param name="chunkY">ChunkColumn Y</param>
/// <param name="chunkZ">ChunkColumn Z</param>
/// <param name="chunkColumnSize">ChunkColumn size</param>
/// <param name="chunk">Chunk data</param>
/// <param name="loadCompleted">Whether the ChunkColumn has been fully loaded</param>
public void StoreChunk(int chunkX, int chunkY, int chunkZ, int chunkColumnSize, Chunk chunk, bool loadCompleted)
{
ChunkColumn? chunkColumn = null;
chunksLock.EnterUpgradeableReadLock();
try
{
//Read a chunk
if (chunks.ContainsKey(chunkX))
if (chunks[chunkX].ContainsKey(chunkZ))
chunkColumn = chunks[chunkX][chunkZ];
if (chunkColumn == null)
{
chunkColumn = new ChunkColumn(chunkColumnSize);
chunksLock.EnterWriteLock();
try
{
//Update a chunk column
if (!chunks.ContainsKey(chunkX))
chunks[chunkX] = new Dictionary<int, ChunkColumn>();
chunks[chunkX][chunkZ] = chunkColumn;
}
finally
{
chunksLock.ExitWriteLock();
}
}
}
finally
{
chunksLock.ExitUpgradeableReadLock();
}
chunkColumn[chunkY] = chunk;
if (loadCompleted)
chunkColumn.FullyLoaded = true;
}
/// <summary>
/// Get chunk column at the specified location
/// </summary>