// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.GameLogic; using System.Threading; using MUnique.OpenMU.GameLogic.Views.Duel; using Nito.AsyncEx; /// /// A class that manages several instances of . /// public class DuelRoomManager { private readonly DuelConfiguration _configuration; private readonly AsyncLock _lock = new AsyncLock(); private readonly DuelRoom?[] _duelRooms; /// /// Initializes a new instance of the class. /// /// The configuration. public DuelRoomManager(DuelConfiguration configuration) { this._configuration = configuration; this._duelRooms = new DuelRoom?[this.MaxRoomCount]; } /// /// Gets the maximum s count. /// public int MaxRoomCount => this._configuration?.DuelAreas.Count ?? 0; /// /// Gets a for the two duelist players. /// /// The first player. /// The second player. /// A cancellation token. /// A with a free . public async ValueTask GetFreeDuelRoomAsync(Player player1, Player player2, CancellationToken cancellationToken = default) { using var l = await this._lock.LockAsync(cancellationToken); for (int i = 0; i < this._duelRooms.Length; i++) { if (this._duelRooms[i] is null) { var area = this._configuration.DuelAreas.First(a => a.Index == i); return this._duelRooms[i] = new DuelRoom(area, player1, player2); } } return null; } /// /// Discards a . /// /// The . /// A . public async ValueTask GiveBackDuelRoomAsync(DuelRoom duelRoom) { using var l = await this._lock.LockAsync(); this._duelRooms[duelRoom.Index] = null; } /// /// Gets a by its index number. /// /// The index of the . /// A . public DuelRoom? GetRoomByIndex(byte requestedDuelIndex) { if (this.MaxRoomCount <= requestedDuelIndex) { return null; } return this._duelRooms[requestedDuelIndex]; } /// /// Shows the s to a player. /// /// The player. /// A . public async ValueTask ShowRoomsAsync(Player player) { await player.InvokeViewPlugInAsync(p => p.UpdateStatusAsync(this._duelRooms)).ConfigureAwait(false); } }