Add support for automatically networking component dictionary fields with entity keys and values (#4932)

* Add support for automatically networking component dictionary fields with entity keys and values

* Fix using

* Fix order

* Add support for both key and value being entity uid
This commit is contained in:
DrSmugleaf
2024-03-02 16:51:23 -08:00
committed by GitHub
parent a7db5634df
commit 179c6790b6
4 changed files with 449 additions and 12 deletions

View File

@@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Diagnostics;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
using static Microsoft.CodeAnalysis.SymbolDisplayFormat;
using static Microsoft.CodeAnalysis.SymbolDisplayMiscellaneousOptions;
namespace Robust.Shared.CompNetworkGenerator
{
@@ -19,19 +17,25 @@ namespace Robust.Shared.CompNetworkGenerator
private const string GlobalEntityUidName = "global::Robust.Shared.GameObjects.EntityUid";
private const string GlobalNullableEntityUidName = "global::Robust.Shared.GameObjects.EntityUid?";
private const string GlobalNetEntityName = "global::Robust.Shared.GameObjects.NetEntity";
private const string GlobalNetEntityNullableName = "global::Robust.Shared.GameObjects.NetEntity?";
private const string GlobalEntityCoordinatesName = "global::Robust.Shared.Map.EntityCoordinates";
private const string GlobalNullableEntityCoordinatesName = "global::Robust.Shared.Map.EntityCoordinates?";
private const string GlobalEntityUidSetName = "global::System.Collections.Generic.HashSet<global::Robust.Shared.GameObjects.EntityUid>";
private const string GlobalNetEntityUidSetName = "global::System.Collections.Generic.HashSet<global::Robust.Shared.GameObjects.NetEntity>";
private const string GlobalNetEntityUidSetName = $"global::System.Collections.Generic.HashSet<{GlobalNetEntityName}>";
private const string GlobalEntityUidListName = "global::System.Collections.Generic.List<global::Robust.Shared.GameObjects.EntityUid>";
private const string GlobalNetEntityUidListName = "global::System.Collections.Generic.List<global::Robust.Shared.GameObjects.NetEntity>";
private const string GlobalNetEntityUidListName = $"global::System.Collections.Generic.List<{GlobalNetEntityName}>";
private const string GlobalDictionaryName = "global::System.Collections.Generic.Dictionary<TKey, TValue>";
private const string GlobalHashSetName = "global::System.Collections.Generic.HashSet<T>";
private const string GlobalListName = "global::System.Collections.Generic.List<T>";
private static readonly SymbolDisplayFormat FullNullableFormat =
FullyQualifiedFormat.WithMiscellaneousOptions(IncludeNullableReferenceTypeModifier);
private static string? GenerateSource(in GeneratorExecutionContext context, INamedTypeSymbol classSymbol, CSharpCompilation comp, bool raiseAfterAutoHandle)
{
var nameSpace = classSymbol.ContainingNamespace.ToDisplayString();
@@ -132,7 +136,7 @@ namespace Robust.Shared.CompNetworkGenerator
foreach (var (type, name) in fields)
{
var typeDisplayStr = type.ToDisplayString(FullyQualifiedFormat);
var typeDisplayStr = type.ToDisplayString(FullNullableFormat);
var nullable = type.NullableAnnotation == NullableAnnotation.Annotated;
var nullableAnnotation = nullable ? "?" : string.Empty;
@@ -181,6 +185,62 @@ namespace Robust.Shared.CompNetworkGenerator
break;
default:
if (type is INamedTypeSymbol { TypeArguments.Length: 2 } named &&
named.ConstructedFrom.ToDisplayString(FullyQualifiedFormat) == GlobalDictionaryName)
{
var key = named.TypeArguments[0].ToDisplayString(FullNullableFormat);
var keyNullable = key.EndsWith("?");
var value = named.TypeArguments[1].ToDisplayString(FullNullableFormat);
var valueNullable = value.EndsWith("?");
if (key is GlobalEntityUidName or GlobalNullableEntityUidName)
{
key = keyNullable ? GlobalNetEntityNullableName : GlobalNetEntityName;
var ensureGeneric = $"{componentName}, {value}";
if (value is GlobalEntityUidName or GlobalNullableEntityUidName)
{
value = valueNullable ? GlobalNetEntityNullableName : GlobalNetEntityName;
ensureGeneric = componentName;
}
stateFields.Append($@"
public Dictionary<{key}, {value}> {name} = default!;");
getStateInit.Append($@"
{name} = GetNetEntityDictionary(component.{name}),");
if (valueNullable && value is not GlobalNetEntityName and not GlobalNetEntityNullableName)
{
handleStateSetters.Append($@"
EnsureEntityDictionaryNullableValue<{componentName}, {value}>(state.{name}, uid, component.{name});");
}
else
{
handleStateSetters.Append($@"
EnsureEntityDictionary<{ensureGeneric}>(state.{name}, uid, component.{name});");
}
break;
}
if (value is GlobalEntityUidName or GlobalNullableEntityUidName)
{
value = valueNullable ? GlobalNetEntityNullableName : GlobalNetEntityName;
stateFields.Append($@"
public Dictionary<{key}, {value}> {name} = default!;");
getStateInit.Append($@"
{name} = GetNetEntityDictionary(component.{name}),");
handleStateSetters.Append($@"
EnsureEntityDictionary<{componentName}, {key}>(state.{name}, uid, component.{name});");
break;
}
}
stateFields.Append($@"
public {typeDisplayStr} {name} = default!;");
@@ -193,7 +253,7 @@ namespace Robust.Shared.CompNetworkGenerator
handleStateSetters.Append($@"
if (state.{name} == null)
component.{name} = null;
component.{name} = null!;
else
component.{name} = new(state.{name});");
}
@@ -219,6 +279,7 @@ namespace Robust.Shared.CompNetworkGenerator
}
return $@"// <auto-generated />
#nullable enable
using System;
using Robust.Shared.GameStates;
using Robust.Shared.GameObjects;

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
@@ -279,6 +278,66 @@ public partial class EntityManager
return entities;
}
public Dictionary<EntityUid, T> GetEntityDictionary<T>(Dictionary<NetEntity, T> netEntities)
{
var entities = new Dictionary<EntityUid, T>(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(GetEntity(pair.Key), pair.Value);
}
return entities;
}
public Dictionary<T, EntityUid> GetEntityDictionary<T>(Dictionary<T, NetEntity> netEntities) where T : notnull
{
var entities = new Dictionary<T, EntityUid>(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(pair.Key, GetEntity(pair.Value));
}
return entities;
}
public Dictionary<T, EntityUid?> GetEntityDictionary<T>(Dictionary<T, NetEntity?> netEntities) where T : notnull
{
var entities = new Dictionary<T, EntityUid?>(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(pair.Key, GetEntity(pair.Value));
}
return entities;
}
public Dictionary<EntityUid, EntityUid> GetEntityDictionary(Dictionary<NetEntity, NetEntity> netEntities)
{
var entities = new Dictionary<EntityUid, EntityUid>(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(GetEntity(pair.Key), GetEntity(pair.Value));
}
return entities;
}
public Dictionary<EntityUid, EntityUid?> GetEntityDictionary(Dictionary<NetEntity, NetEntity?> netEntities)
{
var entities = new Dictionary<EntityUid, EntityUid?>(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(GetEntity(pair.Key), GetEntity(pair.Value));
}
return entities;
}
public HashSet<EntityUid> EnsureEntitySet<T>(HashSet<NetEntity> netEntities, EntityUid callerEntity)
{
var entities = new HashSet<EntityUid>(netEntities.Count);
@@ -324,6 +383,72 @@ public partial class EntityManager
}
}
public void EnsureEntityDictionary<TComp, TValue>(Dictionary<NetEntity, TValue> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, TValue> entities)
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(EnsureEntity<TComp>(pair.Key, callerEntity), pair.Value);
}
}
public void EnsureEntityDictionaryNullableValue<TComp, TValue>(Dictionary<NetEntity, TValue?> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, TValue?> entities)
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(EnsureEntity<TComp>(pair.Key, callerEntity), pair.Value);
}
}
public void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity> netEntities, EntityUid callerEntity,
Dictionary<TKey, EntityUid> entities) where TKey : notnull
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(pair.Key, EnsureEntity<TComp>(pair.Value, callerEntity));
}
}
public void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity?> netEntities, EntityUid callerEntity,
Dictionary<TKey, EntityUid?> entities) where TKey : notnull
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(pair.Key, EnsureEntity<TComp>(pair.Value, callerEntity));
}
}
public void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, EntityUid> entities)
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(EnsureEntity<TComp>(pair.Key, callerEntity), EnsureEntity<TComp>(pair.Value, callerEntity));
}
}
public void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity?> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, EntityUid?> entities)
{
entities.Clear();
entities.EnsureCapacity(netEntities.Count);
foreach (var pair in netEntities)
{
entities.Add(EnsureEntity<TComp>(pair.Key, callerEntity), EnsureEntity<TComp>(pair.Value, callerEntity));
}
}
/// <inheritdoc />
public List<EntityUid> GetEntityList(ICollection<NetEntity> netEntities)
{
@@ -467,6 +592,71 @@ public partial class EntityManager
return netEntities;
}
/// <inheritdoc />
public Dictionary<NetEntity, T> GetNetEntityDictionary<T>(Dictionary<EntityUid, T> entities)
{
var netEntities = new Dictionary<NetEntity, T>(entities.Count);
foreach (var pair in entities)
{
netEntities.Add(GetNetEntity(pair.Key), pair.Value);
}
return netEntities;
}
/// <inheritdoc />
public Dictionary<T, NetEntity> GetNetEntityDictionary<T>(Dictionary<T, EntityUid> entities) where T : notnull
{
var netEntities = new Dictionary<T, NetEntity>(entities.Count);
foreach (var pair in entities)
{
netEntities.Add(pair.Key, GetNetEntity(pair.Value));
}
return netEntities;
}
/// <inheritdoc />
public Dictionary<T, NetEntity?> GetNetEntityDictionary<T>(Dictionary<T, EntityUid?> entities) where T : notnull
{
var netEntities = new Dictionary<T, NetEntity?>(entities.Count);
foreach (var pair in entities)
{
netEntities.Add(pair.Key, GetNetEntity(pair.Value));
}
return netEntities;
}
/// <inheritdoc />
public Dictionary<NetEntity, NetEntity> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid> entities)
{
var netEntities = new Dictionary<NetEntity, NetEntity>(entities.Count);
foreach (var pair in entities)
{
netEntities.Add(GetNetEntity(pair.Key), GetNetEntity(pair.Value));
}
return netEntities;
}
/// <inheritdoc />
public Dictionary<NetEntity, NetEntity?> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid?> entities)
{
var netEntities = new Dictionary<NetEntity, NetEntity?>(entities.Count);
foreach (var pair in entities)
{
netEntities.Add(GetNetEntity(pair.Key), GetNetEntity(pair.Value));
}
return netEntities;
}
/// <inheritdoc />
public HashSet<EntityCoordinates> GetEntitySet(HashSet<NetCoordinates> netEntities)
{

View File

@@ -1049,6 +1049,42 @@ public partial class EntitySystem
EntityManager.EnsureEntityList<T>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionary<TComp, TValue>(Dictionary<NetEntity, TValue> netEntities, EntityUid callerEntity, Dictionary<EntityUid, TValue> entities)
{
EntityManager.EnsureEntityDictionary<TComp, TValue>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionaryNullableValue<TComp, TValue>(Dictionary<NetEntity, TValue?> netEntities, EntityUid callerEntity, Dictionary<EntityUid, TValue?> entities)
{
EntityManager.EnsureEntityDictionaryNullableValue<TComp, TValue>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity> netEntities, EntityUid callerEntity, Dictionary<TKey, EntityUid> entities) where TKey : notnull
{
EntityManager.EnsureEntityDictionary<TComp, TKey>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity?> netEntities, EntityUid callerEntity, Dictionary<TKey, EntityUid?> entities) where TKey : notnull
{
EntityManager.EnsureEntityDictionary<TComp, TKey>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity> netEntities, EntityUid callerEntity, Dictionary<EntityUid, EntityUid> entities)
{
EntityManager.EnsureEntityDictionary<TComp>(netEntities, callerEntity, entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity?> netEntities, EntityUid callerEntity, Dictionary<EntityUid, EntityUid?> entities)
{
EntityManager.EnsureEntityDictionary<TComp>(netEntities, callerEntity, entities);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> of a <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
@@ -1184,6 +1220,96 @@ public partial class EntitySystem
return EntityManager.GetEntityArray(netEntities);
}
/// <summary>
/// Returns the <see cref="NetEntity"/> versions of the supplied entities. Logs an error if the entities do not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<NetEntity, T> GetNetEntityDictionary<T>(Dictionary<EntityUid, T> uids)
{
return EntityManager.GetNetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="NetEntity"/> versions of the supplied entities. Logs an error if the entities do not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<T, NetEntity> GetNetEntityDictionary<T>(Dictionary<T, EntityUid> uids) where T : notnull
{
return EntityManager.GetNetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="NetEntity"/> versions of the supplied entities. Logs an error if the entities do not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<T, NetEntity?> GetNetEntityDictionary<T>(Dictionary<T, EntityUid?> uids) where T : notnull
{
return EntityManager.GetNetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="NetEntity"/> versions of the supplied entities. Logs an error if the entities do not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<NetEntity, NetEntity> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid> uids)
{
return EntityManager.GetNetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="NetEntity"/> versions of the supplied entities. Logs an error if the entities do not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<NetEntity, NetEntity?> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid?> uids)
{
return EntityManager.GetNetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> versions of the supplied <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<EntityUid, T> GetEntityDictionary<T>(Dictionary<NetEntity, T> uids)
{
return EntityManager.GetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> versions of the supplied <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<T, EntityUid> GetEntityDictionary<T>(Dictionary<T, NetEntity> uids) where T : notnull
{
return EntityManager.GetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> versions of the supplied <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<T, EntityUid?> GetEntityDictionary<T>(Dictionary<T, NetEntity?> uids) where T : notnull
{
return EntityManager.GetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> versions of the supplied <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<EntityUid, EntityUid> GetEntityDictionary(Dictionary<NetEntity, NetEntity> uids)
{
return EntityManager.GetEntityDictionary(uids);
}
/// <summary>
/// Returns the <see cref="EntityUid"/> versions of the supplied <see cref="NetEntity"/>. Returns <see cref="EntityUid.Invalid"/> if it doesn't exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Dictionary<EntityUid, EntityUid?> GetEntityDictionary(Dictionary<NetEntity, NetEntity?> uids)
{
return EntityManager.GetEntityDictionary(uids);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected NetCoordinates GetNetCoordinates(EntityCoordinates coordinates, MetaDataComponent? metadata = null)
{

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Robust.Shared.Map;
@@ -107,6 +106,16 @@ public partial interface IEntityManager
/// </summary>
EntityUid?[] GetEntityArray(NetEntity?[] netEntities);
/// <summary>
/// Dictionary version of <see cref="GetEntity"/>
/// </summary>
Dictionary<EntityUid, T> GetEntityDictionary<T>(Dictionary<NetEntity, T> netEntities);
/// <summary>
/// Dictionary version of <see cref="GetEntity"/>
/// </summary>
Dictionary<T, EntityUid> GetEntityDictionary<T>(Dictionary<T, NetEntity> netEntities) where T : notnull;
/// <summary>
/// HashSet version of <see cref="GetNetEntity"/>
/// </summary>
@@ -117,6 +126,11 @@ public partial interface IEntityManager
/// </summary>
public List<NetEntity> GetNetEntityList(List<EntityUid> entities);
/// <summary>
/// List version of <see cref="GetNetEntity"/>
/// </summary>
List<NetEntity> GetNetEntityList(IReadOnlyList<EntityUid> entities);
/// <summary>
/// List version of <see cref="GetNetEntity"/>
/// </summary>
@@ -128,15 +142,40 @@ public partial interface IEntityManager
public List<NetEntity?> GetNetEntityList(List<EntityUid?> entities);
/// <summary>
/// List version of <see cref="GetNetEntity"/>
/// Array version of <see cref="GetNetEntity"/>
/// </summary>
NetEntity[] GetNetEntityArray(EntityUid[] entities);
/// <summary>
/// List version of <see cref="GetNetEntity"/>
/// Array version of <see cref="GetNetEntity"/>
/// </summary>
NetEntity?[] GetNetEntityArray(EntityUid?[] entities);
/// <summary>
/// Dictionary version of <see cref="GetNetEntity"/>
/// </summary>
Dictionary<NetEntity, T> GetNetEntityDictionary<T>(Dictionary<EntityUid, T> entities);
/// <summary>
/// Dictionary version of <see cref="GetNetEntity"/>
/// </summary>
Dictionary<T, NetEntity> GetNetEntityDictionary<T>(Dictionary<T, EntityUid> entities) where T : notnull;
/// <summary>
/// Dictionary version of <see cref="GetNetEntity"/>
/// </summary>
Dictionary<T, NetEntity?> GetNetEntityDictionary<T>(Dictionary<T, EntityUid?> entities) where T : notnull;
/// <summary>
/// Dictionary version of <see cref="GetNetEntity"/>
/// </summary>
Dictionary<NetEntity, NetEntity> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid> entities);
/// <summary>
/// Dictionary version of <see cref="GetNetEntity"/>
/// </summary>
Dictionary<NetEntity, NetEntity?> GetNetEntityDictionary(Dictionary<EntityUid, EntityUid?> entities);
/// <summary>
/// Returns the corresponding <see cref="NetCoordinates"/> for the specified local coordinates.
/// </summary>
@@ -178,6 +217,27 @@ public partial interface IEntityManager
public List<EntityUid> EnsureEntityList<T>(List<NetEntity> netEntities, EntityUid callerEntity);
void EnsureEntityList<T>(List<NetEntity> netEntities, EntityUid callerEntity, List<EntityUid> entities);
void EnsureEntityDictionary<TComp, TValue>(Dictionary<NetEntity, TValue> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, TValue> entities);
void EnsureEntityDictionaryNullableValue<TComp, TValue>(Dictionary<NetEntity, TValue?> netEntities,
EntityUid callerEntity,
Dictionary<EntityUid, TValue?> entities);
void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity> netEntities, EntityUid callerEntity,
Dictionary<TKey, EntityUid> entities) where TKey : notnull;
void EnsureEntityDictionary<TComp, TKey>(Dictionary<TKey, NetEntity?> netEntities, EntityUid callerEntity,
Dictionary<TKey, EntityUid?> entities) where TKey : notnull;
void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, EntityUid> entities);
void EnsureEntityDictionary<TComp>(Dictionary<NetEntity, NetEntity?> netEntities, EntityUid callerEntity,
Dictionary<EntityUid, EntityUid?> entities);
public List<EntityCoordinates> GetEntityList(ICollection<NetCoordinates> netEntities);
public List<EntityCoordinates?> GetEntityList(List<NetCoordinates?> netEntities);