//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.ChatServer;
using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
///
/// The Chat Room Manager manages the creation and destruction of chat rooms.
///
internal class ChatRoomManager
{
private readonly ILoggerFactory _loggerFactory;
///
/// All currently used chat rooms.
///
private readonly IDictionary _rooms = new ConcurrentDictionary();
private readonly ConcurrentBag _freeRoomIds = new();
///
/// Initializes a new instance of the class.
///
/// The logger factory.
public ChatRoomManager(ILoggerFactory loggerFactory)
{
this._loggerFactory = loggerFactory;
for (ushort i = 0; i < ushort.MaxValue; ++i)
{
this._freeRoomIds.Add(i);
}
}
///
/// Gets the opened rooms.
///
public ICollection OpenedRooms => this._rooms.Values;
///
/// Creates a new ChatRoom and returns its Room-ID.
///
/// The Room-ID of the new room. Returns ushort.MaxValue, if there is no free chat room available.
public ushort CreateChatRoom()
{
if (!this._freeRoomIds.TryTake(out ushort roomId))
{
throw new InvalidOperationException("There is no free room id, so the chat room couldn't be created.");
}
var room = new ChatRoom(roomId, this._loggerFactory.CreateLogger());
room.RoomClosed += this.OnChatRoomClosed;
this._rooms.Add(roomId, room);
return roomId;
}
///
/// Returns the chat room with the corresponding Room-ID.
/// Returns null, if ChatRoom wasn't found.
///
/// Room-ID.
/// ChatRoom or null.
internal ChatRoom? GetChatRoom(ushort roomId)
{
this._rooms.TryGetValue(roomId, out var room);
return room;
}
private void OnChatRoomClosed(object? sender, ChatRoomClosedEventArgs eventArgs)
{
var room = eventArgs.ChatRoom;
this._rooms.Remove(room.RoomId);
this._freeRoomIds.Add(room.RoomId);
room.Dispose();
}
}