Browse Source

rename IEntityData into IEntityStruct, it's not necessary to add confusion with more names

fix MoveEntityView function
fix Preallocate function
tags/Rel25a
sebas77 6 years ago
parent
commit
9b470a8dee
11 changed files with 110 additions and 106 deletions
  1. +1
    -6
      Svelto.ECS/DataStructures/TypeSafeDictionary.cs
  2. +33
    -31
      Svelto.ECS/EnginesRoot.Entities.cs
  3. +13
    -8
      Svelto.ECS/EntityViewBuilder.cs
  4. +14
    -14
      Svelto.ECS/EntityViewsDB.cs
  5. +21
    -21
      Svelto.ECS/GenericEntityDescriptor.cs
  6. +8
    -6
      Svelto.ECS/IEntityView.cs
  7. +12
    -12
      Svelto.ECS/IEntityViewsDB.cs
  8. +3
    -3
      Svelto.ECS/MultiEntitiesEngine.cs
  9. +3
    -3
      Svelto.ECS/MultiEntityViewsEngine.cs
  10. +1
    -1
      Svelto.ECS/SingleEntityEngine.cs
  11. +1
    -1
      Svelto.ECS/SingleEntityViewEngine.cs

+ 1
- 6
Svelto.ECS/DataStructures/TypeSafeDictionary.cs View File

@@ -32,7 +32,7 @@ namespace Svelto.ECS.Internal
int Count { get; }
}

class TypeSafeDictionary<TValue> : FasterDictionary<int, TValue>, ITypeSafeDictionary where TValue : IEntityData
class TypeSafeDictionary<TValue> : FasterDictionary<int, TValue>, ITypeSafeDictionary where TValue : IEntityStruct
{
public TypeSafeDictionary(int size):base(size)
{}
@@ -109,11 +109,6 @@ namespace Svelto.ECS.Internal
}
}

public void AddCapacity(int size)
{
throw new NotImplementedException();
}

public ITypeSafeDictionary Create()
{
return new TypeSafeDictionary<TValue>();


+ 33
- 31
Svelto.ECS/EnginesRoot.Entities.cs View File

@@ -61,44 +61,48 @@ namespace Svelto.ECS

///--------------------------------------------

/// <summary>
/// This function is experimental and untested. I never used it in production
/// it may not be necessary.
/// TODO: understand if this method is useful in a performance critical
/// scenario
/// </summary>
void Preallocate<T>(int groupID, int size) where T : class, IEntityDescriptor, new()
{
var entityViewsToBuild = EntityDescriptorTemplate<T>.Info.entityViewsToBuild;
var count = entityViewsToBuild.Length;

//reserve space in the database
Dictionary<Type, ITypeSafeDictionary> @group;
if (_groupEntityDB.TryGetValue(groupID, out group) == false)
group = _groupEntityDB[groupID] = new Dictionary<Type, ITypeSafeDictionary>();

//reserve space in building buffer
Dictionary<Type, ITypeSafeDictionary> @groupBuffer;
if (_groupedEntityToAdd.current.TryGetValue(groupID, out @groupBuffer) == false)
@groupBuffer = _groupedEntityToAdd.current[groupID] = new Dictionary<Type, ITypeSafeDictionary>();

ITypeSafeDictionary dbList;

for (var index = 0; index < count; index++)
{
var entityViewBuilder = entityViewsToBuild[index];
var entityViewType = entityViewBuilder.GetEntityType();

//reserve space for the global pool
ITypeSafeDictionary dbList;

//reserve space for the single group
Dictionary<Type, ITypeSafeDictionary> @group;
if (_groupEntityDB.TryGetValue(groupID, out group) == false)
group = _groupEntityDB[groupID] = new Dictionary<Type, ITypeSafeDictionary>();
if (group.TryGetValue(entityViewType, out dbList) == false)
group[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size);
else
dbList.AddCapacity(size);
if (_groupedEntityToAdd.current.TryGetValue(groupID, out group) == false)
group = _groupEntityDB[groupID] = new Dictionary<Type, ITypeSafeDictionary>();
//reserve space to the temporary buffer
if (group.TryGetValue(entityViewType, out dbList) == false)
group[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size);
if (@groupBuffer.TryGetValue(entityViewType, out dbList) == false)
@groupBuffer[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size);
else
dbList.AddCapacity(size);
}

if (group.TryGetValue(_typeEntityInfoView, out dbList) == false)
group[_typeEntityInfoView] = EntityViewBuilder<EntityInfoView>.Preallocate(ref dbList, size);
else
dbList.AddCapacity(size);

if (@groupBuffer.TryGetValue(_typeEntityInfoView, out dbList) == false)
@groupBuffer[_typeEntityInfoView] = EntityViewBuilder<EntityInfoView>.Preallocate(ref dbList, size);
else
dbList.AddCapacity(size);
}
///--------------------------------------------
@@ -161,26 +165,24 @@ namespace Svelto.ECS
_groupEntityDB.Add(toGroupID, groupedEntityViewsTyped);
}
ITypeSafeDictionary toSafeList;
ITypeSafeDictionary toSafeDic;

for (var i = 0; i < entityViewBuildersCount; i++)
{
var entityViewBuilder = entityViewBuilders[i];
var entityViewType = entityViewBuilder.GetEntityType();

var fromSafeList = groupedEntities[entityViewType];
if (groupedEntityViewsTyped.TryGetValue(entityViewType, out toSafeList) == false)
groupedEntityViewsTyped[entityViewType] = toSafeList = fromSafeList.Create();
var fromSafeDic = groupedEntities[entityViewType];
if (groupedEntityViewsTyped.TryGetValue(entityViewType, out toSafeDic) == false)
groupedEntityViewsTyped[entityViewType] = toSafeDic = fromSafeDic.Create();

entityViewBuilder.MoveEntityView(entityegid, toGroupID, fromSafeList, toSafeList);
fromSafeList.Remove(entityegid.entityID);
entityViewBuilder.MoveEntityView(entityegid, toGroupID, fromSafeDic, toSafeDic);
}
if (groupedEntityViewsTyped.TryGetValue(_typeEntityInfoView, out toSafeList) == false)
groupedEntityViewsTyped[_typeEntityInfoView] = toSafeList = entityInfoViewDictionary.Create();
if (groupedEntityViewsTyped.TryGetValue(_typeEntityInfoView, out toSafeDic) == false)
groupedEntityViewsTyped[_typeEntityInfoView] = toSafeDic = entityInfoViewDictionary.Create();

EntityViewBuilder<EntityInfoView>.MoveEntityView(entityegid, toGroupID, entityInfoViewDictionary, toSafeList);
entityInfoViewDictionary.Remove(entityegid.entityID);
EntityViewBuilder<EntityInfoView>.MoveEntityView(entityegid, toGroupID, entityInfoViewDictionary, toSafeDic);
}
EGID SwapFirstEntityGroup(int fromGroupID, int toGroupId)
@@ -208,7 +210,7 @@ namespace Svelto.ECS
_id = id;
}

public void Init<T>(ref T initializer) where T: struct, IEntityData
public void Init<T>(ref T initializer) where T: struct, IEntityStruct
{
var typeSafeDictionary = (TypeSafeDictionary<T>) _current[typeof(T)];



+ 13
- 8
Svelto.ECS/EntityViewBuilder.cs View File

@@ -9,13 +9,13 @@ using Svelto.Utilities;

namespace Svelto.ECS
{
public class EntityViewBuilder<T> : IEntityViewBuilder where T : IEntityData, new()
public class EntityViewBuilder<T> : IEntityViewBuilder where T : IEntityStruct, new()
{
public EntityViewBuilder()
{
_initializer = default(T);
#if DEBUG && !PROFILER
#if DEBUG && !PROFILER
if (needsReflection == false && typeof(T) != typeof(EntityInfoView))
{
var type = typeof(T);
@@ -30,10 +30,10 @@ namespace Svelto.ECS
if (field.FieldType.IsPrimitive == true || field.FieldType.IsValueType == true)
continue;
throw new EntityStructException();
throw new EntityStructException(field.FieldType);
}
}
#endif
#endif
if (needsReflection == true)
{
EntityView<T>.InitCache();
@@ -69,7 +69,12 @@ namespace Svelto.ECS
}
}

public ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary dictionary, int size)
ITypeSafeDictionary IEntityViewBuilder.Preallocate(ref ITypeSafeDictionary dictionary, int size)
{
return Preallocate(ref dictionary, size);
}

public static ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary dictionary, int size)
{
if (dictionary == null)
dictionary = new TypeSafeDictionary<T>(size);
@@ -95,9 +100,9 @@ namespace Svelto.ECS
var toCastedDic = toSafeDic as TypeSafeDictionary<T>;

var entity = fromCastedDic[entityID.entityID];
fromCastedDic.Remove(entityID.entityID);
entity.ID = new EGID(entityID.entityID, toGroupID);
toCastedDic.Add(entityID.entityID, entity);
fromCastedDic.Remove(entityID.entityID);
}

static FasterList<KeyValuePair<Type, ActionCast<T>>> entityViewBlazingFastReflection
@@ -114,7 +119,7 @@ namespace Svelto.ECS

public class EntityStructException : Exception
{
public EntityStructException():base("EntityStruct must contains only value types!")
public EntityStructException(Type fieldType):base("EntityStruct must contains only value types! " + fieldType.ToString())
{}
}
}

+ 14
- 14
Svelto.ECS/EntityViewsDB.cs View File

@@ -12,12 +12,12 @@ namespace Svelto.ECS.Internal
_groupEntityViewsDB = groupEntityViewsDB;
}

public ReadOnlyCollectionStruct<T> QueryEntityViews<T>() where T:class, IEntityData
public ReadOnlyCollectionStruct<T> QueryEntityViews<T>() where T:class, IEntityStruct
{
return QueryEntityViews<T>(ExclusiveGroups.StandardEntity);
}

public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int @group) where T:class, IEntityData
public ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int @group) where T:class, IEntityStruct
{
Dictionary<Type, ITypeSafeDictionary> entitiesInGroupPerType;

@@ -31,12 +31,12 @@ namespace Svelto.ECS.Internal
return (outList as TypeSafeDictionary<T>).FasterValues;
}

public T[] QueryEntities<T>(out int count) where T : IEntityData
public T[] QueryEntities<T>(out int count) where T : IEntityStruct
{
return QueryEntities<T>(ExclusiveGroups.StandardEntity, out count);
}
public T[] QueryEntities<T>(int @group, out int count) where T : IEntityData
public T[] QueryEntities<T>(int @group, out int count) where T : IEntityStruct
{
count = 0;
@@ -52,7 +52,7 @@ namespace Svelto.ECS.Internal
return ((TypeSafeDictionary<T>)typeSafeDictionary).GetFasterValuesBuffer(out count);
}

public T[] QueryEntities<T>(EGID entityGID, out uint index) where T : IEntityData
public T[] QueryEntities<T>(EGID entityGID, out uint index) where T : IEntityStruct
{
TypeSafeDictionary<T> casted;
if (!FindSafeDictionary(entityGID, out casted))
@@ -74,7 +74,7 @@ namespace Svelto.ECS.Internal
return QueryEntities<T>(out count);
}

public T QueryEntityView<T>(EGID entityGID) where T : class, IEntityData
public T QueryEntityView<T>(EGID entityGID) where T : class, IEntityStruct
{
T entityView;

@@ -83,7 +83,7 @@ namespace Svelto.ECS.Internal
return entityView;
}

public void ExecuteOnEntity<T, W>(EGID entityGID, ref W value, ActionRef<T, W> action) where T : IEntityData
public void ExecuteOnEntity<T, W>(EGID entityGID, ref W value, ActionRef<T, W> action) where T : IEntityStruct
{
TypeSafeDictionary<T> casted;
if (!FindSafeDictionary(entityGID, out casted)) return;
@@ -92,7 +92,7 @@ namespace Svelto.ECS.Internal
casted.ExecuteOnEntityView(entityGID.entityID, ref value, action);
}
public void ExecuteOnEntity<T>(EGID entityGID, ActionRef<T> action) where T : IEntityData
public void ExecuteOnEntity<T>(EGID entityGID, ActionRef<T> action) where T : IEntityStruct
{
TypeSafeDictionary<T> casted;
if (!FindSafeDictionary(entityGID, out casted)) return;
@@ -101,7 +101,7 @@ namespace Svelto.ECS.Internal
casted.ExecuteOnEntityView(entityGID.entityID, action);
}

public bool Exists<T>(EGID entityGID) where T : IEntityData
public bool Exists<T>(EGID entityGID) where T : IEntityStruct
{
TypeSafeDictionary<T> casted;
if (!FindSafeDictionary(entityGID, out casted)) return false;
@@ -115,7 +115,7 @@ namespace Svelto.ECS.Internal
return false;
}

bool FindSafeDictionary<T>(EGID entityGID, out TypeSafeDictionary<T> casted) where T : IEntityData
bool FindSafeDictionary<T>(EGID entityGID, out TypeSafeDictionary<T> casted) where T : IEntityStruct
{
var type = typeof(T);

@@ -133,26 +133,26 @@ namespace Svelto.ECS.Internal
return true;
}

public bool HasAny<T>() where T : IEntityData
public bool HasAny<T>() where T : IEntityStruct
{
int count;
QueryEntities<T>(out count);
return count > 0;
}

public bool HasAny<T>(int @group) where T : IEntityData
public bool HasAny<T>(int @group) where T : IEntityStruct
{
int count;
QueryEntities<T>(group, out count);
return count > 0;
}

public bool TryQueryEntityView<T>(EGID entityegid, out T entityView) where T : class, IEntityData
public bool TryQueryEntityView<T>(EGID entityegid, out T entityView) where T : class, IEntityStruct
{
return TryQueryEntityViewInGroup(entityegid, out entityView);
}

bool TryQueryEntityViewInGroup<T>(EGID entityGID, out T entityView) where T:IEntityData
bool TryQueryEntityViewInGroup<T>(EGID entityGID, out T entityView) where T:IEntityStruct
{
TypeSafeDictionary<T> casted;
if (!FindSafeDictionary(entityGID, out casted))


+ 21
- 21
Svelto.ECS/GenericEntityDescriptor.cs View File

@@ -1,6 +1,6 @@
namespace Svelto.ECS
{
public abstract class GenericEntityDescriptor<T>:IEntityDescriptor where T : IEntityData, new()
public abstract class GenericEntityDescriptor<T>:IEntityDescriptor where T : IEntityStruct, new()
{
static GenericEntityDescriptor()
{
@@ -15,8 +15,8 @@
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U> : IEntityDescriptor where T : IEntityData, new()
where U : IEntityData, new()
public abstract class GenericEntityDescriptor<T, U> : IEntityDescriptor where T : IEntityStruct, new()
where U : IEntityStruct, new()
{
static GenericEntityDescriptor()
{
@@ -31,9 +31,9 @@
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V> : IEntityDescriptor where T : IEntityData, new()
where U : IEntityData, new()
where V : IEntityData, new()
public abstract class GenericEntityDescriptor<T, U, V> : IEntityDescriptor where T : IEntityStruct, new()
where U : IEntityStruct, new()
where V : IEntityStruct, new()
{
static GenericEntityDescriptor()
{
@@ -48,10 +48,10 @@
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W> : IEntityDescriptor where T : IEntityData, new()
where U : IEntityData, new()
where V : IEntityData, new()
where W : IEntityData, new()
public abstract class GenericEntityDescriptor<T, U, V, W> : IEntityDescriptor where T : IEntityStruct, new()
where U : IEntityStruct, new()
where V : IEntityStruct, new()
where W : IEntityStruct, new()
{
static GenericEntityDescriptor()
{
@@ -66,11 +66,11 @@
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W, X> : IEntityDescriptor where T : IEntityData, new()
where U : IEntityData, new()
where V : IEntityData, new()
where W : IEntityData, new()
where X : IEntityData, new()
public abstract class GenericEntityDescriptor<T, U, V, W, X> : IEntityDescriptor where T : IEntityStruct, new()
where U : IEntityStruct, new()
where V : IEntityStruct, new()
where W : IEntityStruct, new()
where X : IEntityStruct, new()
{
static GenericEntityDescriptor()
{
@@ -85,12 +85,12 @@
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W, X, Y> : IEntityDescriptor where T : IEntityData, new()
where U : IEntityData, new()
where V : IEntityData, new()
where W : IEntityData, new()
where X : IEntityData, new()
where Y : IEntityData, new()
public abstract class GenericEntityDescriptor<T, U, V, W, X, Y> : IEntityDescriptor where T : IEntityStruct, new()
where U : IEntityStruct, new()
where V : IEntityStruct, new()
where W : IEntityStruct, new()
where X : IEntityStruct, new()
where Y : IEntityStruct, new()
{
static GenericEntityDescriptor()
{


+ 8
- 6
Svelto.ECS/IEntityView.cs View File

@@ -5,13 +5,15 @@ using Svelto.DataStructures;
using Svelto.Utilities;

namespace Svelto.ECS
{
public interface IEntityData
{
///<summary>EntityStruct MUST implement IEntiyStruct</summary>
public interface IEntityStruct
{
EGID ID { get; set; }
}
public interface IEntityView:IEntityData

///<summary>EntityViews and EntityViewStructs MUST implement IEntityView</summary>
public interface IEntityView:IEntityStruct
{}
public class EntityView : IEntityView
@@ -25,14 +27,14 @@ namespace Svelto.ECS
EGID _ID;
}

public struct EntityInfoView : IEntityData
public struct EntityInfoView : IEntityStruct
{
public EGID ID { get; set; }
public IEntityViewBuilder[] entityToBuild;
}

public static class EntityView<T> where T: IEntityData, new()
public static class EntityView<T> where T: IEntityStruct, new()
{
internal static readonly FasterList<KeyValuePair<Type, ActionCast<T>>> cachedFields;



+ 12
- 12
Svelto.ECS/IEntityViewsDB.cs View File

@@ -7,25 +7,25 @@ namespace Svelto.ECS
public interface IEntityViewsDB
{
//to use with EntityViews
ReadOnlyCollectionStruct<T> QueryEntityViews<T>() where T : class, IEntityData;
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int group) where T : class, IEntityData;
ReadOnlyCollectionStruct<T> QueryEntityViews<T>() where T : class, IEntityStruct;
ReadOnlyCollectionStruct<T> QueryEntityViews<T>(int group) where T : class, IEntityStruct;

//to use with EntityViews, EntityStructs and EntityViewStructs
T[] QueryEntities<T>(out int count) where T : IEntityData;
T[] QueryEntities<T>(int group, out int count) where T : IEntityData;
T[] QueryEntities<T>(EGID entityGID, out uint index) where T : IEntityData;
T[] QueryEntities<T>(out int count) where T : IEntityStruct;
T[] QueryEntities<T>(int group, out int count) where T : IEntityStruct;
T[] QueryEntities<T>(EGID entityGID, out uint index) where T : IEntityStruct;

//to use with EntityViews
bool TryQueryEntityView<T>(EGID egid, out T entityView) where T : class, IEntityData;
T QueryEntityView<T>(EGID egid) where T : class, IEntityData;
bool TryQueryEntityView<T>(EGID egid, out T entityView) where T : class, IEntityStruct;
T QueryEntityView<T>(EGID egid) where T : class, IEntityStruct;
//to use with EntityViews, EntityStructs and EntityViewStructs
void ExecuteOnEntity<T, W>(EGID egid, ref W value, ActionRef<T, W> action) where T : IEntityData;
void ExecuteOnEntity<T>(EGID egid, ActionRef<T> action) where T : IEntityData;
void ExecuteOnEntity<T, W>(EGID egid, ref W value, ActionRef<T, W> action) where T : IEntityStruct;
void ExecuteOnEntity<T>(EGID egid, ActionRef<T> action) where T : IEntityStruct;
bool Exists<T>(EGID egid) where T : IEntityData;
bool Exists<T>(EGID egid) where T : IEntityStruct;
bool HasAny<T>() where T:IEntityData;
bool HasAny<T>(int group) where T:IEntityData;
bool HasAny<T>() where T:IEntityStruct;
bool HasAny<T>(int group) where T:IEntityStruct;
}
}

+ 3
- 3
Svelto.ECS/MultiEntitiesEngine.cs View File

@@ -1,7 +1,7 @@
namespace Svelto.ECS
{
public abstract class MultiEntitiesEngine<T, U> : SingleEntityEngine<T>, IHandleEntityStructEngine<U>
where U : IEntityData where T : IEntityData
where U : IEntityStruct where T : IEntityStruct
{
public void AddInternal(ref U entityView)
{ Add(ref entityView); }
@@ -13,7 +13,7 @@ namespace Svelto.ECS
}
public abstract class MultiEntitiesEngine<T, U, V> : MultiEntitiesEngine<T, U>, IHandleEntityStructEngine<V>
where V : IEntityData where U : IEntityData where T : IEntityData
where V : IEntityStruct where U : IEntityStruct where T : IEntityStruct
{
public void AddInternal(ref V entityView)
{ Add(ref entityView); }
@@ -30,7 +30,7 @@ namespace Svelto.ECS
/// already too many responsabilities.
/// </summary>
public abstract class MultiEntitiesEngine<T, U, V, W> : MultiEntitiesEngine<T, U, V>, IHandleEntityStructEngine<W>
where W : IEntityData where V : IEntityData where U : IEntityData where T : IEntityData
where W : IEntityStruct where V : IEntityStruct where U : IEntityStruct where T : IEntityStruct
{
public void AddInternal(ref W entityView)
{ Add(ref entityView); }


+ 3
- 3
Svelto.ECS/MultiEntityViewsEngine.cs View File

@@ -1,7 +1,7 @@
namespace Svelto.ECS
{
public abstract class MultiEntityViewsEngine<T, U> : SingleEntityViewEngine<T>, IHandleEntityStructEngine<U>
where U : class, IEntityData where T : class, IEntityData
where U : class, IEntityStruct where T : class, IEntityStruct
{
public void AddInternal(ref U entityView)
{ Add(entityView); }
@@ -13,7 +13,7 @@ namespace Svelto.ECS
}

public abstract class MultiEntityViewsEngine<T, U, V> : MultiEntityViewsEngine<T, U>, IHandleEntityStructEngine<V>
where V : class, IEntityData where U : class, IEntityData where T : class, IEntityData
where V : class, IEntityStruct where U : class, IEntityStruct where T : class, IEntityStruct
{
public void AddInternal(ref V entityView)
{ Add(entityView); }
@@ -30,7 +30,7 @@ namespace Svelto.ECS
/// already too many responsabilities.
/// </summary>
public abstract class MultiEntityViewsEngine<T, U, V, W> : MultiEntityViewsEngine<T, U, V>, IHandleEntityStructEngine<W>
where W : class, IEntityData where V : class, IEntityData where U : class, IEntityData where T : class, IEntityData
where W : class, IEntityStruct where V : class, IEntityStruct where U : class, IEntityStruct where T : class, IEntityStruct
{
public void AddInternal(ref W entityView)
{ Add(entityView); }


+ 1
- 1
Svelto.ECS/SingleEntityEngine.cs View File

@@ -1,6 +1,6 @@
namespace Svelto.ECS
{
public abstract class SingleEntityEngine<T> : IHandleEntityStructEngine<T> where T : IEntityData
public abstract class SingleEntityEngine<T> : IHandleEntityStructEngine<T> where T : IEntityStruct
{
public void AddInternal(ref T entityView)
{ Add(ref entityView); }


+ 1
- 1
Svelto.ECS/SingleEntityViewEngine.cs View File

@@ -1,6 +1,6 @@
namespace Svelto.ECS
{
public abstract class SingleEntityViewEngine<T> : IHandleEntityStructEngine<T> where T : class, IEntityData
public abstract class SingleEntityViewEngine<T> : IHandleEntityStructEngine<T> where T : class, IEntityStruct
{
public void AddInternal(ref T entityView)
{ Add(entityView); }


Loading…
Cancel
Save