fixed code formatter.
minor bug fixes to a few systems as well.
This commit is contained in:
parent
657e19f48f
commit
01d2cbf4b3
@ -27,19 +27,19 @@ namespace AdvChkSys
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new WorldConstraints object.
|
/// Creates a new WorldConstraints object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static WorldConstraints CreateDefaultConstraints() => new WorldConstraints();
|
public static WorldConstraints CreateDefaultConstraints() => new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new 2D chunk manager with optional constraints.
|
/// Creates a new 2D chunk manager with optional constraints.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ChunkManager2D<byte> Create2DManager(WorldConstraints? constraints = null) =>
|
public static ChunkManager2D<byte> Create2DManager(WorldConstraints? constraints = null) =>
|
||||||
new ChunkManager2D<byte>(constraints);
|
new(constraints);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new 3D chunk manager with optional constraints.
|
/// Creates a new 3D chunk manager with optional constraints.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ChunkManager3D<byte> Create3DManager(WorldConstraints? constraints = null) =>
|
public static ChunkManager3D<byte> Create3DManager(WorldConstraints? constraints = null) =>
|
||||||
new ChunkManager3D<byte>(constraints);
|
new(constraints);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a detailed report of the current memory usage by the chunk system.
|
/// Gets a detailed report of the current memory usage by the chunk system.
|
||||||
@ -73,13 +73,13 @@ namespace AdvChkSys
|
|||||||
/// Creates a spatial index for 2D chunks.
|
/// Creates a spatial index for 2D chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static SpatialChunkIndex<Chunk2D<T>> CreateSpatialIndex2D<T>() =>
|
public static SpatialChunkIndex<Chunk2D<T>> CreateSpatialIndex2D<T>() =>
|
||||||
new SpatialChunkIndex<Chunk2D<T>>();
|
new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a spatial index for 3D chunks.
|
/// Creates a spatial index for 3D chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static SpatialChunkIndex<Chunk3D<T>> CreateSpatialIndex3D<T>() =>
|
public static SpatialChunkIndex<Chunk3D<T>> CreateSpatialIndex3D<T>() =>
|
||||||
new SpatialChunkIndex<Chunk3D<T>>();
|
new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configures the threading system for high throughput.
|
/// Configures the threading system for high throughput.
|
||||||
|
|||||||
@ -91,13 +91,13 @@ namespace AdvChkSys.Chunk
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (localX < 0 || localX >= Width || localY < 0 || localY >= Height)
|
if (localX < 0 || localX >= Width || localY < 0 || localY >= Height)
|
||||||
throw new ArgumentOutOfRangeException($"Coordinates ({localX}, {localY}) out of bounds [0-{Width-1}, 0-{Height-1}]");
|
throw new ArgumentOutOfRangeException($"Coordinates ({localX}, {localY}) out of bounds [0-{Width - 1}, 0-{Height - 1}]");
|
||||||
return _isAllAir ? default! : _data![localX, localY];
|
return _isAllAir ? default! : _data![localX, localY];
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (localX < 0 || localX >= Width || localY < 0 || localY >= Height)
|
if (localX < 0 || localX >= Width || localY < 0 || localY >= Height)
|
||||||
throw new ArgumentOutOfRangeException($"Coordinates ({localX}, {localY}) out of bounds [0-{Width-1}, 0-{Height-1}]");
|
throw new ArgumentOutOfRangeException($"Coordinates ({localX}, {localY}) out of bounds [0-{Width - 1}, 0-{Height - 1}]");
|
||||||
if (_isAllAir)
|
if (_isAllAir)
|
||||||
throw new InvalidOperationException("Cannot set cell in all-air chunk.");
|
throw new InvalidOperationException("Cannot set cell in all-air chunk.");
|
||||||
_data![localX, localY] = value;
|
_data![localX, localY] = value;
|
||||||
|
|||||||
@ -6,210 +6,210 @@ using AdvChkSys.Interfaces;
|
|||||||
|
|
||||||
namespace AdvChkSys.Chunk
|
namespace AdvChkSys.Chunk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 3D chunk of data in the world.
|
||||||
|
/// Perspective-agnostic and supports arbitrary data types and metadata.
|
||||||
|
/// </summary>
|
||||||
|
public class Chunk3D<T> : IChunk, IDisposable
|
||||||
|
{
|
||||||
|
// Array pool for chunk data arrays
|
||||||
|
private static readonly ConcurrentBag<T[,,]> _arrayPool = new();
|
||||||
|
|
||||||
|
// Flyweight: one all-air instance per size
|
||||||
|
private static readonly Dictionary<(int, int, int), Chunk3D<T>> _allAirChunks = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a 3D chunk of data in the world.
|
/// Returns a singleton all-air chunk for the given size and position.
|
||||||
/// Perspective-agnostic and supports arbitrary data types and metadata.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Chunk3D<T> : IChunk, IDisposable
|
public static Chunk3D<T> AllAir(int x, int y, int z, int width, int height, int depth)
|
||||||
{
|
{
|
||||||
// Array pool for chunk data arrays
|
var key = (width, height, depth);
|
||||||
private static readonly ConcurrentBag<T[,,]> _arrayPool = new();
|
if (!_allAirChunks.TryGetValue(key, out var chunk))
|
||||||
|
|
||||||
// Flyweight: one all-air instance per size
|
|
||||||
private static readonly Dictionary<(int, int, int), Chunk3D<T>> _allAirChunks = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a singleton all-air chunk for the given size and position.
|
|
||||||
/// </summary>
|
|
||||||
public static Chunk3D<T> AllAir(int x, int y, int z, int width, int height, int depth)
|
|
||||||
{
|
{
|
||||||
var key = (width, height, depth);
|
chunk = new Chunk3D<T>(x, y, z, width, height, depth, isAllAir: true);
|
||||||
if (!_allAirChunks.TryGetValue(key, out var chunk))
|
_allAirChunks[key] = chunk;
|
||||||
{
|
|
||||||
chunk = new Chunk3D<T>(x, y, z, width, height, depth, isAllAir: true);
|
|
||||||
_allAirChunks[key] = chunk;
|
|
||||||
}
|
|
||||||
chunk.SetPosition(x, y, z); // Use explicit method for position update
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
chunk.SetPosition(x, y, z); // Use explicit method for position update
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The chunk's X position in chunk coordinates.
|
/// The chunk's X position in chunk coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int X { get; private set; }
|
public int X { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The chunk's Y position in chunk coordinates.
|
/// The chunk's Y position in chunk coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Y { get; private set; }
|
public int Y { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The chunk's Z position in chunk coordinates.
|
/// The chunk's Z position in chunk coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Z { get; private set; }
|
public int Z { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The width of the chunk in cells.
|
/// The width of the chunk in cells.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Width { get; }
|
public int Width { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The height of the chunk in cells.
|
/// The height of the chunk in cells.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Height { get; }
|
public int Height { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The depth of the chunk in cells.
|
/// The depth of the chunk in cells.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Depth { get; }
|
public int Depth { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The chunk's data array.
|
/// The chunk's data array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly T[,,]? _data;
|
private readonly T[,,]? _data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Metadata dictionary for arbitrary chunk information (e.g., biome, tags).
|
/// Metadata dictionary for arbitrary chunk information (e.g., biome, tags).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, object> Metadata { get; }
|
public Dictionary<string, object> Metadata { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if this chunk is the all-air singleton.
|
/// Returns true if this chunk is the all-air singleton.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAllAir { get; private set; } = false;
|
public bool IsAllAir { get; private set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tracks whether the chunk has been disposed.
|
/// Tracks whether the chunk has been disposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new 3D chunk at the specified position with the given dimensions.
|
/// Creates a new 3D chunk at the specified position with the given dimensions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">X coordinate in chunk space</param>
|
/// <param name="x">X coordinate in chunk space</param>
|
||||||
/// <param name="y">Y coordinate in chunk space</param>
|
/// <param name="y">Y coordinate in chunk space</param>
|
||||||
/// <param name="z">Z coordinate in chunk space</param>
|
/// <param name="z">Z coordinate in chunk space</param>
|
||||||
/// <param name="width">Width of the chunk in cells</param>
|
/// <param name="width">Width of the chunk in cells</param>
|
||||||
/// <param name="height">Height of the chunk in cells</param>
|
/// <param name="height">Height of the chunk in cells</param>
|
||||||
/// <param name="depth">Depth of the chunk in cells</param>
|
/// <param name="depth">Depth of the chunk in cells</param>
|
||||||
public Chunk3D(int x, int y, int z, int width, int height, int depth)
|
public Chunk3D(int x, int y, int z, int width, int height, int depth)
|
||||||
: this(x, y, z, width, height, depth, false)
|
: this(x, y, z, width, height, depth, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new 3D chunk at the specified position with the given dimensions.
|
/// Creates a new 3D chunk at the specified position with the given dimensions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="x">X coordinate in chunk space</param>
|
/// <param name="x">X coordinate in chunk space</param>
|
||||||
/// <param name="y">Y coordinate in chunk space</param>
|
/// <param name="y">Y coordinate in chunk space</param>
|
||||||
/// <param name="z">Z coordinate in chunk space</param>
|
/// <param name="z">Z coordinate in chunk space</param>
|
||||||
/// <param name="width">Width of the chunk in cells</param>
|
/// <param name="width">Width of the chunk in cells</param>
|
||||||
/// <param name="height">Height of the chunk in cells</param>
|
/// <param name="height">Height of the chunk in cells</param>
|
||||||
/// <param name="depth">Depth of the chunk in cells</param>
|
/// <param name="depth">Depth of the chunk in cells</param>
|
||||||
/// <param name="isAllAir">Whether this is an all-air chunk</param>
|
/// <param name="isAllAir">Whether this is an all-air chunk</param>
|
||||||
public Chunk3D(int x, int y, int z, int width, int height, int depth, bool isAllAir = false)
|
public Chunk3D(int x, int y, int z, int width, int height, int depth, bool isAllAir = false)
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
Z = z;
|
Z = z;
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
Depth = depth;
|
Depth = depth;
|
||||||
IsAllAir = isAllAir;
|
IsAllAir = isAllAir;
|
||||||
_data = isAllAir ? null : RentArray(width, height, depth);
|
_data = isAllAir ? null : RentArray(width, height, depth);
|
||||||
Metadata = new Dictionary<string, object>();
|
Metadata = new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Explicitly sets the chunk's position. Used internally for all-air singleton.
|
/// Explicitly sets the chunk's position. Used internally for all-air singleton.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void SetPosition(int x, int y, int z)
|
internal void SetPosition(int x, int y, int z)
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
Z = z;
|
Z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the value at the given local chunk coordinates.
|
/// Gets or sets the value at the given local chunk coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public T this[int localX, int localY, int localZ]
|
public T this[int localX, int localY, int localZ]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
|
||||||
if (IsAllAir)
|
|
||||||
return default!;
|
|
||||||
return _data![localX, localY, localZ];
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (IsAllAir)
|
|
||||||
throw new InvalidOperationException("Cannot modify an all-air chunk.");
|
|
||||||
_data![localX, localY, localZ] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fills the chunk with a specified value.
|
|
||||||
/// </summary>
|
|
||||||
public void Fill(T value)
|
|
||||||
{
|
{
|
||||||
if (IsAllAir)
|
if (IsAllAir)
|
||||||
throw new InvalidOperationException("Cannot fill an all-air chunk.");
|
return default!;
|
||||||
|
return _data![localX, localY, localZ];
|
||||||
for (int x = 0; x < Width; x++)
|
|
||||||
for (int y = 0; y < Height; y++)
|
|
||||||
for (int z = 0; z < Depth; z++)
|
|
||||||
_data![x, y, z] = value;
|
|
||||||
}
|
}
|
||||||
|
set
|
||||||
/// <summary>
|
|
||||||
/// Rents an array from the pool or creates a new one.
|
|
||||||
/// </summary>
|
|
||||||
private static T[,,] RentArray(int width, int height, int depth)
|
|
||||||
{
|
{
|
||||||
if (_arrayPool.TryTake(out var arr) &&
|
if (IsAllAir)
|
||||||
arr.GetLength(0) == width &&
|
throw new InvalidOperationException("Cannot modify an all-air chunk.");
|
||||||
arr.GetLength(1) == height &&
|
_data![localX, localY, localZ] = value;
|
||||||
arr.GetLength(2) == depth)
|
|
||||||
return arr;
|
|
||||||
return new T[width, height, depth];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns an array to the pool.
|
|
||||||
/// </summary>
|
|
||||||
internal static void ReturnArray(T[,,] arr)
|
|
||||||
{
|
|
||||||
_arrayPool.Add(arr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the underlying data array (for pooling).
|
|
||||||
/// </summary>
|
|
||||||
internal T[,,]? GetDataArray() => _data;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Releases the data array back to the pool.
|
|
||||||
/// </summary>
|
|
||||||
internal void ReleaseDataArray()
|
|
||||||
{
|
|
||||||
if (_data != null && !IsAllAir)
|
|
||||||
{
|
|
||||||
ReturnArray(_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disposes the chunk and returns its resources to the pool.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (!_disposed)
|
|
||||||
{
|
|
||||||
ReleaseDataArray();
|
|
||||||
_disposed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fills the chunk with a specified value.
|
||||||
|
/// </summary>
|
||||||
|
public void Fill(T value)
|
||||||
|
{
|
||||||
|
if (IsAllAir)
|
||||||
|
throw new InvalidOperationException("Cannot fill an all-air chunk.");
|
||||||
|
|
||||||
|
for (int x = 0; x < Width; x++)
|
||||||
|
for (int y = 0; y < Height; y++)
|
||||||
|
for (int z = 0; z < Depth; z++)
|
||||||
|
_data![x, y, z] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents an array from the pool or creates a new one.
|
||||||
|
/// </summary>
|
||||||
|
private static T[,,] RentArray(int width, int height, int depth)
|
||||||
|
{
|
||||||
|
if (_arrayPool.TryTake(out var arr) &&
|
||||||
|
arr.GetLength(0) == width &&
|
||||||
|
arr.GetLength(1) == height &&
|
||||||
|
arr.GetLength(2) == depth)
|
||||||
|
return arr;
|
||||||
|
return new T[width, height, depth];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an array to the pool.
|
||||||
|
/// </summary>
|
||||||
|
internal static void ReturnArray(T[,,] arr)
|
||||||
|
{
|
||||||
|
_arrayPool.Add(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the underlying data array (for pooling).
|
||||||
|
/// </summary>
|
||||||
|
internal T[,,]? GetDataArray() => _data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases the data array back to the pool.
|
||||||
|
/// </summary>
|
||||||
|
internal void ReleaseDataArray()
|
||||||
|
{
|
||||||
|
if (_data != null && !IsAllAir)
|
||||||
|
{
|
||||||
|
ReturnArray(_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the chunk and returns its resources to the pool.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!_disposed)
|
||||||
|
{
|
||||||
|
ReleaseDataArray();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,67 +1,67 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace AdvChkSys.Constraints
|
namespace AdvChkSys.Constraints
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents constraints and limits for the chunk world.
|
|
||||||
/// Can be used to restrict world size, chunk counts, and other resource limits.
|
|
||||||
/// </summary>
|
|
||||||
public class WorldConstraints
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set, the minimum allowed chunk X coordinate (inclusive).
|
/// Represents constraints and limits for the chunk world.
|
||||||
|
/// Can be used to restrict world size, chunk counts, and other resource limits.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? MinChunkX { get; set; }
|
public class WorldConstraints
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the maximum allowed chunk X coordinate (inclusive).
|
|
||||||
/// </summary>
|
|
||||||
public int? MaxChunkX { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the minimum allowed chunk Y coordinate (inclusive).
|
|
||||||
/// </summary>
|
|
||||||
public int? MinChunkY { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the maximum allowed chunk Y coordinate (inclusive).
|
|
||||||
/// </summary>
|
|
||||||
public int? MaxChunkY { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the minimum allowed chunk Z coordinate (inclusive).
|
|
||||||
/// </summary>
|
|
||||||
public int? MinChunkZ { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the maximum allowed chunk Z coordinate (inclusive).
|
|
||||||
/// </summary>
|
|
||||||
public int? MaxChunkZ { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, the maximum number of chunks allowed to be loaded in memory at once.
|
|
||||||
/// </summary>
|
|
||||||
public int? MaxLoadedChunks { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the given chunk coordinates are within the allowed world bounds.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsWithinBounds(int chunkX, int chunkY)
|
|
||||||
{
|
{
|
||||||
if (MinChunkX.HasValue && chunkX < MinChunkX.Value) return false;
|
/// <summary>
|
||||||
if (MaxChunkX.HasValue && chunkX > MaxChunkX.Value) return false;
|
/// If set, the minimum allowed chunk X coordinate (inclusive).
|
||||||
if (MinChunkY.HasValue && chunkY < MinChunkY.Value) return false;
|
/// </summary>
|
||||||
if (MaxChunkY.HasValue && chunkY > MaxChunkY.Value) return false;
|
public int? MinChunkX { get; set; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the current number of loaded chunks is within the allowed limit.
|
/// If set, the maximum allowed chunk X coordinate (inclusive).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsWithinChunkLimit(int loadedChunkCount)
|
public int? MaxChunkX { get; set; }
|
||||||
{
|
|
||||||
if (MaxLoadedChunks.HasValue && loadedChunkCount > MaxLoadedChunks.Value) return false;
|
/// <summary>
|
||||||
return true;
|
/// If set, the minimum allowed chunk Y coordinate (inclusive).
|
||||||
|
/// </summary>
|
||||||
|
public int? MinChunkY { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set, the maximum allowed chunk Y coordinate (inclusive).
|
||||||
|
/// </summary>
|
||||||
|
public int? MaxChunkY { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set, the minimum allowed chunk Z coordinate (inclusive).
|
||||||
|
/// </summary>
|
||||||
|
public int? MinChunkZ { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set, the maximum allowed chunk Z coordinate (inclusive).
|
||||||
|
/// </summary>
|
||||||
|
public int? MaxChunkZ { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set, the maximum number of chunks allowed to be loaded in memory at once.
|
||||||
|
/// </summary>
|
||||||
|
public int? MaxLoadedChunks { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the given chunk coordinates are within the allowed world bounds.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsWithinBounds(int chunkX, int chunkY)
|
||||||
|
{
|
||||||
|
if (MinChunkX.HasValue && chunkX < MinChunkX.Value) return false;
|
||||||
|
if (MaxChunkX.HasValue && chunkX > MaxChunkX.Value) return false;
|
||||||
|
if (MinChunkY.HasValue && chunkY < MinChunkY.Value) return false;
|
||||||
|
if (MaxChunkY.HasValue && chunkY > MaxChunkY.Value) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the current number of loaded chunks is within the allowed limit.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsWithinChunkLimit(int loadedChunkCount)
|
||||||
|
{
|
||||||
|
if (MaxLoadedChunks.HasValue && loadedChunkCount > MaxLoadedChunks.Value) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@ -51,8 +51,10 @@ namespace AdvChkSys.Diagnostics
|
|||||||
{
|
{
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
var memStatus = new MemoryHelper.MEMORYSTATUSEX();
|
var memStatus = new MemoryHelper.MEMORYSTATUSEX
|
||||||
memStatus.dwLength = (uint)Marshal.SizeOf(typeof(MemoryHelper.MEMORYSTATUSEX));
|
{
|
||||||
|
dwLength = (uint)Marshal.SizeOf(typeof(MemoryHelper.MEMORYSTATUSEX))
|
||||||
|
};
|
||||||
if (MemoryHelper.GlobalMemoryStatusEx(ref memStatus))
|
if (MemoryHelper.GlobalMemoryStatusEx(ref memStatus))
|
||||||
{
|
{
|
||||||
return memStatus.ullTotalPhys;
|
return memStatus.ullTotalPhys;
|
||||||
|
|||||||
@ -4,123 +4,123 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace AdvChkSys.Events
|
namespace AdvChkSys.Events
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Provides events for chunk lifecycle operations such as loading, unloading, saving, and more.
|
|
||||||
/// Thread-safe event subscription and invocation.
|
|
||||||
/// </summary>
|
|
||||||
public static class ChunkEvents
|
|
||||||
{
|
|
||||||
// Backing fields for thread-safe event handling
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkLoaded;
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkUnloaded;
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkLoading;
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkUnloading;
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkSaving;
|
|
||||||
private static Action<Interfaces.IChunk>? _chunkSaved;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a chunk has been loaded into memory.
|
/// Provides events for chunk lifecycle operations such as loading, unloading, saving, and more.
|
||||||
|
/// Thread-safe event subscription and invocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event Action<Interfaces.IChunk> ChunkLoaded
|
public static class ChunkEvents
|
||||||
{
|
{
|
||||||
add => AddHandler(ref _chunkLoaded, value);
|
// Backing fields for thread-safe event handling
|
||||||
remove => RemoveHandler(ref _chunkLoaded, value);
|
private static Action<Interfaces.IChunk>? _chunkLoaded;
|
||||||
}
|
private static Action<Interfaces.IChunk>? _chunkUnloaded;
|
||||||
|
private static Action<Interfaces.IChunk>? _chunkLoading;
|
||||||
|
private static Action<Interfaces.IChunk>? _chunkUnloading;
|
||||||
|
private static Action<Interfaces.IChunk>? _chunkSaving;
|
||||||
|
private static Action<Interfaces.IChunk>? _chunkSaved;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a chunk is about to be loaded into memory.
|
/// Occurs when a chunk has been loaded into memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event Action<Interfaces.IChunk> ChunkLoading
|
public static event Action<Interfaces.IChunk> ChunkLoaded
|
||||||
{
|
|
||||||
add => AddHandler(ref _chunkLoading, value);
|
|
||||||
remove => RemoveHandler(ref _chunkLoading, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a chunk is about to be unloaded from memory.
|
|
||||||
/// </summary>
|
|
||||||
public static event Action<Interfaces.IChunk> ChunkUnloading
|
|
||||||
{
|
|
||||||
add => AddHandler(ref _chunkUnloading, value);
|
|
||||||
remove => RemoveHandler(ref _chunkUnloading, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a chunk has been unloaded from memory.
|
|
||||||
/// </summary>
|
|
||||||
public static event Action<Interfaces.IChunk> ChunkUnloaded
|
|
||||||
{
|
|
||||||
add => AddHandler(ref _chunkUnloaded, value);
|
|
||||||
remove => RemoveHandler(ref _chunkUnloaded, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a chunk is about to be saved.
|
|
||||||
/// </summary>
|
|
||||||
public static event Action<Interfaces.IChunk> ChunkSaving
|
|
||||||
{
|
|
||||||
add => AddHandler(ref _chunkSaving, value);
|
|
||||||
remove => RemoveHandler(ref _chunkSaving, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a chunk has been saved.
|
|
||||||
/// </summary>
|
|
||||||
public static event Action<Interfaces.IChunk> ChunkSaved
|
|
||||||
{
|
|
||||||
add => AddHandler(ref _chunkSaved, value);
|
|
||||||
remove => RemoveHandler(ref _chunkSaved, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkLoading event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkLoading(Interfaces.IChunk chunk) => _chunkLoading?.Invoke(chunk);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkLoaded event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkLoaded(Interfaces.IChunk chunk) => _chunkLoaded?.Invoke(chunk);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkUnloading event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkUnloading(Interfaces.IChunk chunk) => _chunkUnloading?.Invoke(chunk);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkUnloaded event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkUnloaded(Interfaces.IChunk chunk) => _chunkUnloaded?.Invoke(chunk);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkSaving event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkSaving(Interfaces.IChunk chunk) => _chunkSaving?.Invoke(chunk);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raises the ChunkSaved event.
|
|
||||||
/// </summary>
|
|
||||||
public static void OnChunkSaved(Interfaces.IChunk chunk) => _chunkSaved?.Invoke(chunk);
|
|
||||||
|
|
||||||
// Thread-safe add/remove for event handlers
|
|
||||||
private static void AddHandler(ref Action<Interfaces.IChunk>? field, Action<Interfaces.IChunk> handler)
|
|
||||||
{
|
|
||||||
Action<Interfaces.IChunk>? prevHandler, newHandler;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
prevHandler = field;
|
add => AddHandler(ref _chunkLoaded, value);
|
||||||
newHandler = (Action<Interfaces.IChunk>?)Delegate.Combine(prevHandler, handler);
|
remove => RemoveHandler(ref _chunkLoaded, value);
|
||||||
} while (Interlocked.CompareExchange(ref field, newHandler, prevHandler) != prevHandler);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemoveHandler(ref Action<Interfaces.IChunk>? field, Action<Interfaces.IChunk> handler)
|
/// <summary>
|
||||||
{
|
/// Occurs when a chunk is about to be loaded into memory.
|
||||||
Action<Interfaces.IChunk>? prevHandler, newHandler;
|
/// </summary>
|
||||||
do
|
public static event Action<Interfaces.IChunk> ChunkLoading
|
||||||
{
|
{
|
||||||
prevHandler = field;
|
add => AddHandler(ref _chunkLoading, value);
|
||||||
newHandler = (Action<Interfaces.IChunk>?)Delegate.Remove(prevHandler, handler);
|
remove => RemoveHandler(ref _chunkLoading, value);
|
||||||
} while (Interlocked.CompareExchange(ref field, newHandler, prevHandler) != prevHandler);
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a chunk is about to be unloaded from memory.
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Interfaces.IChunk> ChunkUnloading
|
||||||
|
{
|
||||||
|
add => AddHandler(ref _chunkUnloading, value);
|
||||||
|
remove => RemoveHandler(ref _chunkUnloading, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a chunk has been unloaded from memory.
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Interfaces.IChunk> ChunkUnloaded
|
||||||
|
{
|
||||||
|
add => AddHandler(ref _chunkUnloaded, value);
|
||||||
|
remove => RemoveHandler(ref _chunkUnloaded, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a chunk is about to be saved.
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Interfaces.IChunk> ChunkSaving
|
||||||
|
{
|
||||||
|
add => AddHandler(ref _chunkSaving, value);
|
||||||
|
remove => RemoveHandler(ref _chunkSaving, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a chunk has been saved.
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<Interfaces.IChunk> ChunkSaved
|
||||||
|
{
|
||||||
|
add => AddHandler(ref _chunkSaved, value);
|
||||||
|
remove => RemoveHandler(ref _chunkSaved, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkLoading event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkLoading(Interfaces.IChunk chunk) => _chunkLoading?.Invoke(chunk);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkLoaded event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkLoaded(Interfaces.IChunk chunk) => _chunkLoaded?.Invoke(chunk);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkUnloading event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkUnloading(Interfaces.IChunk chunk) => _chunkUnloading?.Invoke(chunk);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkUnloaded event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkUnloaded(Interfaces.IChunk chunk) => _chunkUnloaded?.Invoke(chunk);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkSaving event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkSaving(Interfaces.IChunk chunk) => _chunkSaving?.Invoke(chunk);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the ChunkSaved event.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnChunkSaved(Interfaces.IChunk chunk) => _chunkSaved?.Invoke(chunk);
|
||||||
|
|
||||||
|
// Thread-safe add/remove for event handlers
|
||||||
|
private static void AddHandler(ref Action<Interfaces.IChunk>? field, Action<Interfaces.IChunk> handler)
|
||||||
|
{
|
||||||
|
Action<Interfaces.IChunk>? prevHandler, newHandler;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
prevHandler = field;
|
||||||
|
newHandler = (Action<Interfaces.IChunk>?)Delegate.Combine(prevHandler, handler);
|
||||||
|
} while (Interlocked.CompareExchange(ref field, newHandler, prevHandler) != prevHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveHandler(ref Action<Interfaces.IChunk>? field, Action<Interfaces.IChunk> handler)
|
||||||
|
{
|
||||||
|
Action<Interfaces.IChunk>? prevHandler, newHandler;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
prevHandler = field;
|
||||||
|
newHandler = (Action<Interfaces.IChunk>?)Delegate.Remove(prevHandler, handler);
|
||||||
|
} while (Interlocked.CompareExchange(ref field, newHandler, prevHandler) != prevHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@ -2,37 +2,37 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace AdvChkSys.Interfaces
|
namespace AdvChkSys.Interfaces
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for managing chunks in memory.
|
|
||||||
/// Provides methods for loading, unloading, and accessing chunks.
|
|
||||||
/// </summary>
|
|
||||||
public interface IChunkManager
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the chunk at (x, y) is loaded.
|
/// Interface for managing chunks in memory.
|
||||||
|
/// Provides methods for loading, unloading, and accessing chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsChunkLoaded(int x, int y);
|
public interface IChunkManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the chunk at (x, y) is loaded.
|
||||||
|
/// </summary>
|
||||||
|
bool IsChunkLoaded(int x, int y);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the chunk at (x, y) if loaded, or null if not.
|
/// Gets the chunk at (x, y) if loaded, or null if not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IChunk? GetChunk(int x, int y);
|
IChunk? GetChunk(int x, int y);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads or creates a chunk at (x, y) with the given size.
|
/// Loads or creates a chunk at (x, y) with the given size.
|
||||||
/// Returns the loaded or newly created chunk.
|
/// Returns the loaded or newly created chunk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IChunk LoadOrCreateChunk(int x, int y, int width, int height);
|
IChunk LoadOrCreateChunk(int x, int y, int width, int height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads (removes) the chunk at (x, y) if loaded.
|
/// Unloads (removes) the chunk at (x, y) if loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool UnloadChunk(int x, int y);
|
bool UnloadChunk(int x, int y);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumerates all loaded chunks.
|
/// Enumerates all loaded chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerable<IChunk> GetAllChunks();
|
IEnumerable<IChunk> GetAllChunks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ namespace AdvChkSys.Manager
|
|||||||
private readonly WorldConstraints? _constraints;
|
private readonly WorldConstraints? _constraints;
|
||||||
private readonly int _capacity;
|
private readonly int _capacity;
|
||||||
private readonly Dictionary<(int, int), Task<Chunk2D<T>>> _loadingChunks = new();
|
private readonly Dictionary<(int, int), Task<Chunk2D<T>>> _loadingChunks = new();
|
||||||
private readonly object _lock = new object();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delegate for custom air check logic
|
/// Delegate for custom air check logic
|
||||||
|
|||||||
@ -6,67 +6,67 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace AdvChkSys.Resources
|
namespace AdvChkSys.Resources
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Manages allocation and release of chunk resources in memory.
|
|
||||||
/// Can be extended to track resource usage, pooling, or implement custom memory strategies.
|
|
||||||
/// </summary>
|
|
||||||
public static class ChunkResourceManager
|
|
||||||
{
|
|
||||||
// Example: Track allocated chunks (for diagnostics, pooling, or resource limits)
|
|
||||||
private static readonly ConcurrentDictionary<IChunk, DateTime> _allocatedChunks = new ConcurrentDictionary<IChunk, DateTime>();
|
|
||||||
private static int _allocatedChunkCount;
|
|
||||||
private static readonly object _lock = new object();
|
|
||||||
private static readonly HashSet<IChunk> _activeChunks = new();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a chunk is allocated/loaded into memory.
|
/// Manages allocation and release of chunk resources in memory.
|
||||||
/// Tracks the chunk and can be extended for pooling or resource limits.
|
/// Can be extended to track resource usage, pooling, or implement custom memory strategies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void AllocateChunk(IChunk chunk)
|
public static class ChunkResourceManager
|
||||||
{
|
{
|
||||||
lock (_lock)
|
// Example: Track allocated chunks (for diagnostics, pooling, or resource limits)
|
||||||
|
private static readonly ConcurrentDictionary<IChunk, DateTime> _allocatedChunks = new();
|
||||||
|
private static int _allocatedChunkCount;
|
||||||
|
private static readonly object _lock = new();
|
||||||
|
private static readonly HashSet<IChunk> _activeChunks = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a chunk is allocated/loaded into memory.
|
||||||
|
/// Tracks the chunk and can be extended for pooling or resource limits.
|
||||||
|
/// </summary>
|
||||||
|
public static void AllocateChunk(IChunk chunk)
|
||||||
{
|
{
|
||||||
_allocatedChunkCount++;
|
lock (_lock)
|
||||||
_activeChunks.Add(chunk);
|
{
|
||||||
|
_allocatedChunkCount++;
|
||||||
|
_activeChunks.Add(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a chunk is released/unloaded from memory.
|
/// Called when a chunk is released/unloaded from memory.
|
||||||
/// Removes the chunk from tracking and can be extended for pooling or cleanup.
|
/// Removes the chunk from tracking and can be extended for pooling or cleanup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ReleaseChunk(IChunk chunk)
|
public static void ReleaseChunk(IChunk chunk)
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
{
|
||||||
_allocatedChunkCount--;
|
lock (_lock)
|
||||||
_activeChunks.Remove(chunk);
|
{
|
||||||
|
_allocatedChunkCount--;
|
||||||
|
_activeChunks.Remove(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current number of allocated chunks.
|
/// Gets the current number of allocated chunks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static int AllocatedChunkCount => _allocatedChunks.Count;
|
public static int AllocatedChunkCount => _allocatedChunks.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears all tracked chunks (for diagnostics or shutdown).
|
/// Clears all tracked chunks (for diagnostics or shutdown).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Clear()
|
public static void Clear()
|
||||||
{
|
|
||||||
_allocatedChunks.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current count of active chunks being tracked by the resource manager.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The number of active chunks</returns>
|
|
||||||
public static int GetActiveChunkCount()
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
{
|
||||||
return _activeChunks.Count;
|
_allocatedChunks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current count of active chunks being tracked by the resource manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The number of active chunks</returns>
|
||||||
|
public static int GetActiveChunkCount()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _activeChunks.Count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@ -221,8 +221,8 @@ namespace AdvChkSys.Threading
|
|||||||
// Cancel all pending operations
|
// Cancel all pending operations
|
||||||
while (queue.Count > 0)
|
while (queue.Count > 0)
|
||||||
{
|
{
|
||||||
var operation = queue.Dequeue();
|
var (Operation, Completion) = queue.Dequeue();
|
||||||
operation.Completion.TrySetCanceled();
|
Completion.TrySetCanceled();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace AdvChkSys.Threading
|
|||||||
private static bool _currentThreadIsProcessingItems;
|
private static bool _currentThreadIsProcessingItems;
|
||||||
|
|
||||||
// The list of tasks to be executed
|
// The list of tasks to be executed
|
||||||
private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
|
private readonly LinkedList<Task> _tasks = new();
|
||||||
|
|
||||||
// The maximum concurrency level allowed by this scheduler.
|
// The maximum concurrency level allowed by this scheduler.
|
||||||
private int _maximumConcurrencyLevel;
|
private int _maximumConcurrencyLevel;
|
||||||
|
|||||||
@ -115,8 +115,8 @@ namespace AdvChkSys.Util
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
foreach (var node in _lruList)
|
foreach (var (key, value) in _lruList)
|
||||||
yield return node.value;
|
yield return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user