mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Add thead safety to terrain data (#1999)
Allow safely reading terrain data from other threads
This commit is contained in:
parent
d6220ff779
commit
aeca6a8f53
3 changed files with 101 additions and 25 deletions
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace MinecraftClient.Mapping
|
||||
{
|
||||
|
|
@ -15,6 +16,11 @@ namespace MinecraftClient.Mapping
|
|||
/// </summary>
|
||||
private Dictionary<int, Dictionary<int, ChunkColumn>> chunks = new Dictionary<int, Dictionary<int, ChunkColumn>>();
|
||||
|
||||
/// <summary>
|
||||
/// Lock for thread safety
|
||||
/// </summary>
|
||||
private readonly ReaderWriterLockSlim chunksLock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Read, set or unload the specified chunk column
|
||||
/// </summary>
|
||||
|
|
@ -25,34 +31,50 @@ namespace MinecraftClient.Mapping
|
|||
{
|
||||
get
|
||||
{
|
||||
//Read a chunk
|
||||
if (chunks.ContainsKey(chunkX))
|
||||
if (chunks[chunkX].ContainsKey(chunkZ))
|
||||
return chunks[chunkX][chunkZ];
|
||||
return null;
|
||||
chunksLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
//Read a chunk
|
||||
if (chunks.ContainsKey(chunkX))
|
||||
if (chunks[chunkX].ContainsKey(chunkZ))
|
||||
return chunks[chunkX][chunkZ];
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
chunksLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
chunksLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
//Update a chunk column
|
||||
if (!chunks.ContainsKey(chunkX))
|
||||
chunks[chunkX] = new Dictionary<int, ChunkColumn>();
|
||||
chunks[chunkX][chunkZ] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Unload a chunk column
|
||||
if (chunks.ContainsKey(chunkX))
|
||||
if (value != null)
|
||||
{
|
||||
if (chunks[chunkX].ContainsKey(chunkZ))
|
||||
//Update a chunk column
|
||||
if (!chunks.ContainsKey(chunkX))
|
||||
chunks[chunkX] = new Dictionary<int, ChunkColumn>();
|
||||
chunks[chunkX][chunkZ] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Unload a chunk column
|
||||
if (chunks.ContainsKey(chunkX))
|
||||
{
|
||||
chunks[chunkX].Remove(chunkZ);
|
||||
if (chunks[chunkX].Count == 0)
|
||||
chunks.Remove(chunkX);
|
||||
if (chunks[chunkX].ContainsKey(chunkZ))
|
||||
{
|
||||
chunks[chunkX].Remove(chunkZ);
|
||||
if (chunks[chunkX].Count == 0)
|
||||
chunks.Remove(chunkX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
chunksLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +139,7 @@ namespace MinecraftClient.Mapping
|
|||
{
|
||||
Location doneloc = new Location(x, y, z);
|
||||
Block doneblock = GetBlock(doneloc);
|
||||
Material blockType = GetBlock(doneloc).Type;
|
||||
Material blockType = doneblock.Type;
|
||||
if (blockType == block)
|
||||
{
|
||||
list.Add(doneloc);
|
||||
|
|
@ -150,7 +172,15 @@ namespace MinecraftClient.Mapping
|
|||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
chunks = new Dictionary<int, Dictionary<int, ChunkColumn>>();
|
||||
chunksLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
chunks = new Dictionary<int, Dictionary<int, ChunkColumn>>();
|
||||
}
|
||||
finally
|
||||
{
|
||||
chunksLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue