// // MapEntities.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Concurrent; using NosSmooth.Game.Data.Characters; using NosSmooth.Game.Data.Entities; using NosSmooth.Packets.Enums; namespace NosSmooth.Game.Data.Maps; /// /// Thread-safe store for the entities on the map. /// public class MapEntities { private readonly ConcurrentDictionary _entities; /// /// Initializes a new instance of the class. /// public MapEntities() { _entities = new ConcurrentDictionary(); } /// /// Gets the entities on the map. /// /// The list of the entities. public ICollection GetEntities() => _entities.Values; /// /// Gets the given entity by id. /// /// The id of the entity. /// The entity, or null, if not found. public IEntity? GetEntity(long id) => _entities.GetValueOrDefault(id); /// /// Get the given entity by id. /// /// The id of the entity. /// The type of the entity. /// The entity. /// If the entity is not of the specified type. public TEntity? GetEntity(long id) { var entity = GetEntity(id); if (entity is null) { return default; } if (entity is TEntity tentity) { return tentity; } throw new Exception($"Could not find the entity with the given type {typeof(TEntity)}, was {entity.GetType()}"); } /// /// Add the given entity to the entities list. /// /// The entity to add. internal void AddEntity(IEntity entity) { _entities.AddOrUpdate ( entity.Id, _ => entity, (_, e) => { if (entity is Player && e is Character) { // Do not replace Character with Player! return e; } return entity; } ); } /// /// . /// /// The id of the entity. /// The action to execute on create. /// The action to execute on update. /// The type of the entity. internal void AddOrUpdateEntity (long entityId, Func createAction, Func updateAction) where TEntity : IEntity { _entities.AddOrUpdate (entityId, (key) => createAction(key), (key, entity) => updateAction(key, (TEntity)entity)); } /// /// Remove the given entity. /// /// The entity to remove. internal void RemoveEntity(IEntity entity) { RemoveEntity(entity.Id); } /// /// Remove the given entity. /// /// The id of the entity to remove. internal void RemoveEntity(long entityId) { _entities.TryRemove(entityId, out _); } }