Files
Gen_Hack-and-Slash-Roguelit…/Client/Assets/Scripts/Managers/Buffer.cs
2025-07-16 13:05:04 +08:00

163 lines
4.8 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Threading;
namespace Managers
{
/// <summary>
/// 双缓冲静态类,用于逻辑计算线程与主线程之间的数据同步。
/// </summary>
/// <typeparam name="T">要同步的数据类型。</typeparam>
public static class DoubleBuffer<T>
{
/// <summary>
/// 当前用于写入的缓冲区。
/// </summary>
private static T _writeBuffer;
/// <summary>
/// 当前用于读取的缓冲区。
/// </summary>
private static T _readBuffer;
/// <summary>
/// 用于同步缓冲区交换的锁对象。
/// </summary>
private static readonly object _lock = new object();
/// <summary>
/// 初始化双缓冲类。
/// </summary>
/// <param name="initialValue">初始值,用于初始化两个缓冲区。</param>
public static void Initialize(T initialValue)
{
_writeBuffer = initialValue;
_readBuffer = initialValue;
}
/// <summary>
/// 写入数据到当前写缓冲区。
/// </summary>
/// <param name="data">要写入的数据。</param>
public static void Write(T data)
{
lock (_lock)
{
_writeBuffer = data; // 将数据写入写缓冲区
}
}
/// <summary>
/// 交换读写缓冲区,使主线程可以读取最新的数据。
/// </summary>
public static void SwapBuffers()
{
lock (_lock)
{
// 交换读写缓冲区
T temp = _readBuffer;
_readBuffer = _writeBuffer;
_writeBuffer = temp;
}
}
/// <summary>
/// 从当前读缓冲区读取数据。
/// </summary>
/// <returns>当前读缓冲区中的数据。</returns>
public static T Read()
{
lock (_lock)
{
return _readBuffer; // 返回读缓冲区中的数据
}
}
}
/// <summary>
/// 网络消息缓冲区类,用于在网络线程和主线程之间进行线程安全的消息传递。
/// </summary>
public static class NetworkMessageBuffer
{
/// <summary>
/// 缓冲区的最大消息数量。
/// </summary>
private static readonly int MaxMessageCount;
/// <summary>
/// 存储消息的线程安全队列。
/// </summary>
private static readonly ConcurrentQueue<string> MessageQueue;
/// <summary>
/// 用于控制缓冲区是否已满的信号量。
/// </summary>
private static readonly SemaphoreSlim BufferSemaphore;
/// <summary>
/// 初始化网络消息缓冲区类。
/// </summary>
static NetworkMessageBuffer()
{
MaxMessageCount = 100;
MessageQueue = new ConcurrentQueue<string>();
BufferSemaphore = new SemaphoreSlim(MaxMessageCount, MaxMessageCount);
}
/// <summary>
/// 向缓冲区添加一条消息。
/// 如果缓冲区已满,则等待直到有空间可用。
/// </summary>
/// <param name="message">要添加的消息内容。</param>
public static async void AddMessageAsync(string message)
{
// 等待缓冲区有可用空间
await BufferSemaphore.WaitAsync();
try
{
// 将消息添加到队列中
MessageQueue.Enqueue(message);
}
catch (Exception ex)
{
Console.WriteLine($"AddMessageAsync Error: {ex.Message}");
}
}
/// <summary>
/// 从缓冲区中读取一条消息。
/// 如果缓冲区为空,则返回 null。
/// </summary>
/// <returns>缓冲区中的第一条消息,如果缓冲区为空则返回 null。</returns>
public static string ReadMessage()
{
if (MessageQueue.TryDequeue(out string message))
{
// 释放一个缓冲区空间
BufferSemaphore.Release();
return message;
}
return null;
}
/// <summary>
/// 获取当前缓冲区中的消息数量。
/// </summary>
/// <returns>当前缓冲区中的消息数量。</returns>
public static int GetMessageCount()
{
return MessageQueue.Count;
}
/// <summary>
/// 清空缓冲区中的所有消息。
/// </summary>
public static void ClearBuffer()
{
while (MessageQueue.TryDequeue(out _)) { }
}
}
}