//
// 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 _);
}
}