~ruther/NosSmooth

ref: 6334c0f5e711b3d9567687ae3ebf72fa41691b43 NosSmooth/Core/NosSmooth.Game/Data/Maps/MapEntities.cs -rw-r--r-- 3.5 KiB
6334c0f5 — František Boháček tests: add ptctl deserialization test 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//
//  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;

namespace NosSmooth.Game.Data.Maps;

/// <summary>
/// Thread-safe store for the entities on the map.
/// </summary>
public class MapEntities
{
    private readonly ConcurrentDictionary<long, IEntity> _entities;

    /// <summary>
    /// Initializes a new instance of the <see cref="MapEntities"/> class.
    /// </summary>
    public MapEntities()
    {
        _entities = new ConcurrentDictionary<long, IEntity>();
    }

    /// <summary>
    /// Gets the entities on the map.
    /// </summary>
    /// <returns>The list of the entities.</returns>
    public ICollection<IEntity> GetEntities()
        => _entities.Values;

    /// <summary>
    /// Gets the given entity by id.
    /// </summary>
    /// <param name="id">The id of the entity.</param>
    /// <returns>The entity, or null, if not found.</returns>
    public IEntity? GetEntity(long id)
        => _entities.GetValueOrDefault(id);

    /// <summary>
    /// Get the given entity by id.
    /// </summary>
    /// <param name="id">The id of the entity.</param>
    /// <typeparam name="TEntity">The type of the entity.</typeparam>
    /// <returns>The entity.</returns>
    /// <exception cref="Exception">If the entity is not of the specified type.</exception>
    public TEntity? GetEntity<TEntity>(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()}");
    }

    /// <summary>
    /// Add the given entity to the entities list.
    /// </summary>
    /// <param name="entity">The entity to add.</param>
    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;
            }
        );
    }

    /// <summary>
    /// .
    /// </summary>
    /// <param name="entityId">The id of the entity.</param>
    /// <param name="createAction">The action to execute on create.</param>
    /// <param name="updateAction">The action to execute on update.</param>
    /// <typeparam name="TEntity">The type of the entity.</typeparam>
    internal void AddOrUpdateEntity<TEntity>
        (long entityId, Func<long, TEntity> createAction, Func<long, TEntity, TEntity> updateAction)
        where TEntity : IEntity
    {
        _entities.AddOrUpdate
            (entityId, (key) => createAction(key), (key, entity) => updateAction(key, (TEntity)entity));
    }

    /// <summary>
    /// Remove the given entity.
    /// </summary>
    /// <param name="entity">The entity to remove.</param>
    internal void RemoveEntity(IEntity entity)
    {
        RemoveEntity(entity.Id);
    }

    /// <summary>
    /// Remove the given entity.
    /// </summary>
    /// <param name="entityId">The id of the entity to remove.</param>
    internal void RemoveEntity(long entityId)
    {
        _entities.TryRemove(entityId, out _);
    }
}
Do not follow this link