Browse Source

Mega work in progress to support entity views as structs

tags/Rel25a
sebas77 6 years ago
parent
commit
2c40b46d35
19 changed files with 313 additions and 313 deletions
  1. +4
    -4
      Svelto.ECS/DataStructures/TypeSafeDictionary.cs
  2. +6
    -6
      Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs
  3. +1
    -1
      Svelto.ECS/EGID.cs
  4. +1
    -1
      Svelto.ECS/EnginesRootEngines.cs
  5. +3
    -3
      Svelto.ECS/EnginesRootEntities.cs
  6. +1
    -1
      Svelto.ECS/EnginesRootSubmission.cs
  7. +5
    -129
      Svelto.ECS/EntityFactory.cs
  8. +16
    -79
      Svelto.ECS/EntityViewBuilder.cs
  9. +56
    -0
      Svelto.ECS/EntityViewStructBuilder.cs
  10. +9
    -10
      Svelto.ECS/EntityViewsDB.cs
  11. +129
    -0
      Svelto.ECS/FillEntityView.cs
  12. +32
    -32
      Svelto.ECS/GenericEntityDescriptor.cs
  13. +2
    -2
      Svelto.ECS/IEngine.cs
  14. +9
    -22
      Svelto.ECS/IEntityView.cs
  15. +16
    -0
      Svelto.ECS/IEntityViewBuilder.cs
  16. +6
    -6
      Svelto.ECS/IEntityViewsDB.cs
  17. +12
    -12
      Svelto.ECS/MultiEntityViewsEngine.cs
  18. +2
    -2
      Svelto.ECS/Profiler/EngineProfiler.cs
  19. +3
    -3
      Svelto.ECS/SingleEntityViewEngine.cs

+ 4
- 4
Svelto.ECS/DataStructures/TypeSafeDictionary.cs View File

@@ -15,10 +15,10 @@ namespace Svelto.ECS.Internal
{
void FillWithIndexedEntityViews(ITypeSafeList entityViews);
bool Remove(EGID entityId);
IEntityView GetIndexedEntityView(EGID entityID);
IEntityData GetIndexedEntityView(EGID entityID);
}

class TypeSafeDictionaryForClass<TValue> : Dictionary<long, TValue>, ITypeSafeDictionary where TValue : EntityView
class TypeSafeDictionaryForClass<TValue> : Dictionary<long, TValue>, ITypeSafeDictionary where TValue : IEntityData
{
internal static readonly ReadOnlyDictionary<long, TValue> Default =
new ReadOnlyDictionary<long, TValue>(new Dictionary<long, TValue>());
@@ -34,7 +34,7 @@ namespace Svelto.ECS.Internal
{
var entityView = buffer[i];

Add(entityView._ID.GID, entityView);
Add(entityView.ID.GID, entityView);
}
}
catch (Exception e)
@@ -50,7 +50,7 @@ namespace Svelto.ECS.Internal
return Count > 0;
}

public IEntityView GetIndexedEntityView(EGID entityID)
public IEntityData GetIndexedEntityView(EGID entityID)
{
return this[entityID.GID];
}


+ 6
- 6
Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs View File

@@ -14,11 +14,11 @@ namespace Svelto.ECS.Internal
ITypeSafeList Create();
bool MappedRemove(EGID entityID);
ITypeSafeDictionary CreateIndexedDictionary();
IEntityView[] ToArrayFast(out int count);
IEntityData[] ToArrayFast(out int count);
void AddCapacity(int capacity);
}

class TypeSafeFasterListForECS<T> : FasterList<T> where T : IEntityView
class TypeSafeFasterListForECS<T> : FasterList<T> where T : IEntityData
{
readonly Dictionary<long, int> _mappedIndices;

@@ -98,7 +98,7 @@ namespace Svelto.ECS.Internal
}

class TypeSafeFasterListForECSForStructs<T> : TypeSafeFasterListForECS<T>, ITypeSafeList
where T : struct, IEntityStruct
where T : struct, IEntityData
{
public TypeSafeFasterListForECSForStructs(int size) : base(size)
{}
@@ -121,7 +121,7 @@ namespace Svelto.ECS.Internal
throw new NotSupportedException();
}

public IEntityView[] ToArrayFast(out int count)
public IEntityData[] ToArrayFast(out int count)
{
throw new Exception("Not Allowed");
}
@@ -132,7 +132,7 @@ namespace Svelto.ECS.Internal
}
}

class TypeSafeFasterListForECSForClasses<T> : TypeSafeFasterListForECS<T>, ITypeSafeList where T : EntityView, new()
class TypeSafeFasterListForECSForClasses<T> : TypeSafeFasterListForECS<T>, ITypeSafeList where T : IEntityData, new()
{
public TypeSafeFasterListForECSForClasses(int size) : base(size)
{}
@@ -155,7 +155,7 @@ namespace Svelto.ECS.Internal
return new TypeSafeDictionaryForClass<T>();
}

public IEntityView[] ToArrayFast(out int count)
public IEntityData[] ToArrayFast(out int count)
{
count = Count;



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

@@ -33,7 +33,7 @@ namespace Svelto.ECS

static long MAKE_GLOBAL_ID(int entityId, int groupId)
{
return entityId | (long)groupId << 32;
return (long)groupId << 32 | (uint)entityId;
}

public bool IsEqualTo(EGID otherGID)


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

@@ -120,7 +120,7 @@ namespace Svelto.ECS
readonly Dictionary<Type, FasterList<IHandleEntityViewEngine>> _entityViewEngines;
readonly FasterList<IEngine> _otherEngines;
static readonly Type _entityViewType= typeof(EntityView);
static readonly Type _entityViewType= typeof(IEntityData);
static readonly Type _object = typeof(object);
}
}

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

@@ -17,7 +17,7 @@ namespace Svelto.ECS
foreach (var entity in _globalEntityViewsDB)
if (entity.Value.isQueryiableEntityView)
foreach (var entityView in entity.Value)
RemoveEntityViewFromEngines(_entityViewEngines, entityView as EntityView, entity.Key);
RemoveEntityViewFromEngines(_entityViewEngines, entityView as IEntityData, entity.Key);
}

///--------------------------------------------
@@ -192,7 +192,7 @@ namespace Svelto.ECS

//the reason why this for exists is because in the past hierarchical entity views
//where supported :(
//Only EntityView can be removed from engines (won't work for IEntityStruct or IEntityView)
//Only EntityView can be removed from engines (won't work for IEntityData or IEntityData)
for (var current = entityViewType; current != _entityViewType; current = current.BaseType)
{
#if DEBUG && !PROFILER
@@ -207,7 +207,7 @@ namespace Svelto.ECS
}
static void RemoveEntityViewFromEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines,
IEntityView entityView,
IEntityData entityView,
Type entityViewType)
{
FasterList<IHandleEntityViewEngine> enginesForEntityView;


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

@@ -122,7 +122,7 @@ namespace Svelto.ECS
{
int count;
var fastList = FasterList<IHandleEntityViewEngine>.NoVirt.ToArrayFast(enginesForEntityView, out count);
IEntityView entityView = entityViews[i];
IEntityData entityView = entityViews[i];
for (int j = 0; j < count; j++)
{
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR


+ 5
- 129
Svelto.ECS/EntityFactory.cs View File

@@ -47,151 +47,27 @@ namespace Svelto.ECS.Internal
var entityViewBuilder = entityViewsToBuild[index];
var entityViewType = entityViewBuilder.GetEntityViewType();

var entityViewObjectToFill =
BuildEntityView(entityID, entityViewsByType, entityViewType, entityViewBuilder);

if (entityViewBuilder.mustBeFilled)
FillEntityView(entityViewObjectToFill as EntityView
, implementors
, entityViewsToBuildDescriptor.name);
BuildEntityView(entityID, entityViewsByType, entityViewType, entityViewBuilder, implementors);
}
}

static IEntityView BuildEntityView(EGID entityID, Dictionary<Type, ITypeSafeList> entityViewsByType,
Type entityViewType, IEntityViewBuilder entityViewBuilder)
static void BuildEntityView(EGID entityID, Dictionary<Type, ITypeSafeList> entityViewsByType,
Type entityViewType, IEntityViewBuilder entityViewBuilder, object[] implementors)
{
ITypeSafeList entityViewsList;

var entityViewsPoolWillBeCreated =
entityViewsByType.TryGetValue(entityViewType, out entityViewsList) == false;

IEntityView entityViewObjectToFill;
IEntityData entityViewObjectToFill;

//passing the undefined entityViewsByType inside the entityViewBuilder will allow
//it to be created with the correct type and casted back to the undefined list.
//that's how the list will be eventually of the target type.
entityViewBuilder.BuildEntityViewAndAddToList(ref entityViewsList, entityID, out entityViewObjectToFill);
entityViewBuilder.BuildEntityViewAndAddToList(ref entityViewsList, entityID, implementors);

if (entityViewsPoolWillBeCreated)
entityViewsByType.Add(entityViewType, entityViewsList);

return entityViewObjectToFill;
}

//this is used to avoid newing a dictionary every time, but it's used locally only and it's clearead for each use
#if DEBUG && !PROFILER
static readonly Dictionary<Type, Tuple<object, int>> implementorsByType =
new Dictionary<Type, Tuple<object, int>>();
#else
static readonly Dictionary<Type, object> implementorsByType = new Dictionary<Type, object>();
#endif

static void FillEntityView(EntityView entityView
, object[] implementors
, string entityDescriptorName)
{
int count;

//Very efficent way to collect the fields of every EntityViewType
var setters =
FasterList<KeyValuePair<Type, CastedAction<EntityView>>>
.NoVirt.ToArrayFast(entityView.entityViewBlazingFastReflection, out count);

if (count == 0) return;

for (var index = 0; index < implementors.Length; index++)
{
var implementor = implementors[index];

if (implementor != null)
{
var type = implementor.GetType();

Type[] interfaces;
if (_cachedTypes.TryGetValue(type, out interfaces) == false)
interfaces = _cachedTypes[type] = type.GetInterfacesEx();

for (var iindex = 0; iindex < interfaces.Length; iindex++)
{
var componentType = interfaces[iindex];
#if DEBUG && !PROFILER
Tuple<object, int> implementorHolder;

if (implementorsByType.TryGetValue(componentType, out implementorHolder))
implementorHolder.numberOfImplementations++;
else
implementorsByType[componentType] = new Tuple<object, int>(implementor, 1);
#else
implementorsByType[componentType] = implementor;
#endif
}
}
#if DEBUG && !PROFILER
else
{
Console.LogError(NULL_IMPLEMENTOR_ERROR.FastConcat("Type ", entityDescriptorName, " entityView ", entityView.ToString()));
}
#endif
}

for (var i = 0; i < count; i++)
{
var fieldSetter = setters[i];
var fieldType = fieldSetter.Key;

#if DEBUG && !PROFILER
Tuple<object, int> component;
#else
object component;
#endif

if (implementorsByType.TryGetValue(fieldType, out component) == false)
{
var e = new Exception(NOT_FOUND_EXCEPTION + " Component Type: " + fieldType.Name +
" - EntityView: " +
entityView.GetType().Name + " - EntityDescriptor " + entityDescriptorName);

throw e;
}
#if DEBUG && !PROFILER
if (component.numberOfImplementations > 1)
Console.LogError(DUPLICATE_IMPLEMENTOR_ERROR.FastConcat(
"Component Type: ", fieldType.Name,
" implementor: ",
component.implementorType.ToString()) +
" - EntityView: " +
entityView.GetType().Name + " - EntityDescriptor " + entityDescriptorName);
#endif
#if DEBUG && !PROFILER
fieldSetter.Value.Call(entityView, component.implementorType);
#else
fieldSetter.Value.Call(entityView, component);
#endif
}

implementorsByType.Clear();
}
#if DEBUG && !PROFILER
struct Tuple<T1, T2>
{
public readonly T1 implementorType;
public T2 numberOfImplementations;

public Tuple(T1 implementor, T2 v)
{
implementorType = implementor;
numberOfImplementations = v;
}
}
#endif
static readonly Dictionary<Type, Type[]> _cachedTypes = new Dictionary<Type, Type[]>();
const string DUPLICATE_IMPLEMENTOR_ERROR =
"<color=orange>Svelto.ECS</color> the same component is implemented with more than one implementor. This is considered an error and MUST be fixed. ";

const string NULL_IMPLEMENTOR_ERROR =
"<color=orange>Svelto.ECS</color> Null implementor, please be careful about the implementors passed to avoid performance loss ";

const string NOT_FOUND_EXCEPTION = "<color=orange>Svelto.ECS</color> Implementor not found for an EntityView. ";
}
}

+ 16
- 79
Svelto.ECS/EntityViewBuilder.cs View File

@@ -1,22 +1,14 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
using Svelto.Utilities;

namespace Svelto.ECS
{
public interface IEntityViewBuilder
public class EntityViewBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : IEntityData
{
void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, out IEntityView entityView);
ITypeSafeList Preallocate(ref ITypeSafeList list, int size);

Type GetEntityViewType();
void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList);
bool mustBeFilled { get; }
bool isQueryiableEntityView { get; }
}

public class EntityViewBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : EntityView, new()
{
public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, out IEntityView entityView)
public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors)
{
if (list == null)
list = new TypeSafeFasterListForECSForClasses<EntityViewType>();
@@ -27,7 +19,12 @@ namespace Svelto.ECS

castedList.Add(lentityView);

entityView = lentityView;
var entityView = lentityView;

this.FillEntityView(ref entityView
, entityViewBlazingFastReflection
, implementors
, DESCRIPTOR_NAME);
}

public ITypeSafeList Preallocate(ref ITypeSafeList list, int size)
@@ -53,77 +50,17 @@ namespace Svelto.ECS
toCastedList.Add(fromCastedList[fromCastedList.GetIndexFromID(entityID)]);
}

public bool mustBeFilled
{
get { return true; }
}
public bool isQueryiableEntityView
{
get { return true; }
}

public static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType);
}

public class EntityViewStructBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : struct, IEntityStruct
{
public EntityViewStructBuilder()
{}
public EntityViewStructBuilder(ref EntityViewType initializer)
{
_initializer = initializer;
}
public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, out IEntityView entityView)
{
_initializer.ID = entityID;
if (list == null)
list = new TypeSafeFasterListForECSForStructs<EntityViewType>();

var castedList = list as TypeSafeFasterListForECSForStructs<EntityViewType>;
castedList.Add(_initializer);

entityView = null;
}

public ITypeSafeList Preallocate(ref ITypeSafeList list, int size)
{
if (list == null)
list = new TypeSafeFasterListForECSForStructs<EntityViewType>(size);
else
list.AddCapacity(size);

return list;
}

public Type GetEntityViewType()
{
return ENTITY_VIEW_TYPE;
}

public void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList)
{
var fromCastedList = fromSafeList as TypeSafeFasterListForECSForStructs<EntityViewType>;
var toCastedList = toSafeList as TypeSafeFasterListForECSForStructs<EntityViewType>;

toCastedList.Add(fromCastedList[fromCastedList.GetIndexFromID(entityID)]);
}

public bool mustBeFilled
FasterList<KeyValuePair<Type, CastedAction<EntityViewType>>> entityViewBlazingFastReflection
{
get { return false; }
get { return EntityView<EntityViewType>.FieldCache<EntityViewType>.list; }
}

public bool isQueryiableEntityView
{
get { return false; }
}

public static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType);
EntityViewType _initializer;
}
static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType);
static string DESCRIPTOR_NAME = ENTITY_VIEW_TYPE.ToString();
}
}

+ 56
- 0
Svelto.ECS/EntityViewStructBuilder.cs View File

@@ -0,0 +1,56 @@
using System;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public class EntityViewStructBuilder<EntityViewType> : IEntityViewBuilder where EntityViewType : struct, IEntityData
{
public EntityViewStructBuilder(ref EntityViewType initializer)
{
_initializer = initializer;
}
public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors = null)
{
_initializer.ID = entityID;
if (list == null)
list = new TypeSafeFasterListForECSForStructs<EntityViewType>();

var castedList = list as TypeSafeFasterListForECSForStructs<EntityViewType>;
castedList.Add(_initializer);
}

public ITypeSafeList Preallocate(ref ITypeSafeList list, int size)
{
if (list == null)
list = new TypeSafeFasterListForECSForStructs<EntityViewType>(size);
else
list.AddCapacity(size);

return list;
}

public Type GetEntityViewType()
{
return ENTITY_VIEW_TYPE;
}

public void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList)
{
var fromCastedList = fromSafeList as TypeSafeFasterListForECSForStructs<EntityViewType>;
var toCastedList = toSafeList as TypeSafeFasterListForECSForStructs<EntityViewType>;

toCastedList.Add(fromCastedList[fromCastedList.GetIndexFromID(entityID)]);
}

public bool isQueryiableEntityView
{
get { return false; }
}

static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType);
EntityViewType _initializer;
}
}

+ 9
- 10
Svelto.ECS/EntityViewsDB.cs View File

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

public FasterReadOnlyList<T> QueryEntityViews<T>() where T:EntityView
public FasterReadOnlyList<T> QueryEntityViews<T>() where T:IEntityData
{
var type = typeof(T);

@@ -27,7 +27,7 @@ namespace Svelto.ECS.Internal
return new FasterReadOnlyList<T>((FasterList<T>)entityViews);
}

public FasterReadOnlyList<T> QueryGroupedEntityViews<T>(int @group) where T:EntityView
public FasterReadOnlyList<T> QueryGroupedEntityViews<T>(int @group) where T:IEntityData
{
Dictionary<Type, ITypeSafeList> entitiesInGroupPerType;

@@ -41,7 +41,7 @@ namespace Svelto.ECS.Internal
return new FasterReadOnlyList<T>((FasterList<T>) outList);
}

public T[] QueryEntityViewsAsArray<T>(out int count) where T : IEntityView
public T[] QueryEntityViewsAsArray<T>(out int count) where T : IEntityData
{
var type = typeof(T);
count = 0;
@@ -54,7 +54,7 @@ namespace Svelto.ECS.Internal
return FasterList<T>.NoVirt.ToArrayFast((FasterList<T>)entityViews, out count);
}
public T[] QueryGroupedEntityViewsAsArray<T>(int @group, out int count) where T : EntityView
public T[] QueryGroupedEntityViewsAsArray<T>(int @group, out int count) where T : IEntityData
{
var type = typeof(T);
count = 0;
@@ -71,7 +71,7 @@ namespace Svelto.ECS.Internal
return FasterList<T>.NoVirt.ToArrayFast((FasterList<T>)entitiesInGroupPerType[type], out count);
}

public T QueryEntityView<T>(EGID entityGID) where T : EntityView
public T QueryEntityView<T>(EGID entityGID) where T : IEntityData
{
T entityView;

@@ -80,22 +80,21 @@ namespace Svelto.ECS.Internal
return entityView;
}

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

bool TryQueryEntityViewInGroup<T>(EGID entityGID, out T entityView) where T:EntityView
bool TryQueryEntityViewInGroup<T>(EGID entityGID, out T entityView) where T:IEntityData
{
var type = typeof(T);

T internalEntityView;

ITypeSafeDictionary entityViews;
TypeSafeDictionaryForClass<T> casted;

_groupedEntityViewsDBDic.TryGetValue(type, out entityViews);
casted = entityViews as TypeSafeDictionaryForClass<T>;
var casted = entityViews as TypeSafeDictionaryForClass<T>;

if (casted != null &&
casted.TryGetValue(entityGID.GID, out internalEntityView))
@@ -105,7 +104,7 @@ namespace Svelto.ECS.Internal
return true;
}

entityView = null;
entityView = default(T);

return false;
}


+ 129
- 0
Svelto.ECS/FillEntityView.cs View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.Utilities;
using Console = Utility.Console;

static class FillEntityViewASD
{
public static void FillEntityView<T>(this IEntityViewBuilder entityViewBuilder,
ref T entityView,
FasterList<KeyValuePair<Type, CastedAction<T>>> entityViewBlazingFastReflection ,
object[] implementors
, string entityDescriptorName)
{
int count;

//Very efficent way to collect the fields of every EntityViewType
var setters =
FasterList<KeyValuePair<Type, CastedAction<T>>>
.NoVirt.ToArrayFast(entityViewBlazingFastReflection, out count);

if (count == 0) return;

for (var index = 0; index < implementors.Length; index++)
{
var implementor = implementors[index];

if (implementor != null)
{
var type = implementor.GetType();

Type[] interfaces;
if (_cachedTypes.TryGetValue(type, out interfaces) == false)
interfaces = _cachedTypes[type] = type.GetInterfacesEx();

for (var iindex = 0; iindex < interfaces.Length; iindex++)
{
var componentType = interfaces[iindex];
#if DEBUG && !PROFILER
Tuple<object, int> implementorHolder;

if (implementorsByType.TryGetValue(componentType, out implementorHolder))
implementorHolder.numberOfImplementations++;
else
implementorsByType[componentType] = new Tuple<object, int>(implementor, 1);
#else
implementorsByType[componentType] = implementor;
#endif
}
}
#if DEBUG && !PROFILER
else
{
Console.LogError(NULL_IMPLEMENTOR_ERROR.FastConcat("Type ", entityDescriptorName, " entityView ", entityViewBuilder.GetEntityViewType().ToString()));
}
#endif
}

for (var i = 0; i < count; i++)
{
var fieldSetter = setters[i];
var fieldType = fieldSetter.Key;

#if DEBUG && !PROFILER
Tuple<object, int> component;
#else
object component;
#endif

if (implementorsByType.TryGetValue(fieldType, out component) == false)
{
var e = new Exception(NOT_FOUND_EXCEPTION + " Component Type: " + fieldType.Name +
" - EntityView: " +
entityViewBuilder.GetEntityViewType().Name + " - EntityDescriptor " + entityDescriptorName);

throw e;
}
#if DEBUG && !PROFILER
if (component.numberOfImplementations > 1)
Console.LogError(DUPLICATE_IMPLEMENTOR_ERROR.FastConcat(
"Component Type: ", fieldType.Name,
" implementor: ",
component.implementorType.ToString()) +
" - EntityView: " +
entityViewBuilder.GetEntityViewType().Name + " - EntityDescriptor " + entityDescriptorName);
#endif
#if DEBUG && !PROFILER
fieldSetter.Value.Call(ref entityView, component.implementorType);
#else
fieldSetter.Value.Call(entityView, component);
#endif
}

implementorsByType.Clear();
}
//this is used to avoid newing a dictionary every time, but it's used locally only and it's clearead for each use
#if DEBUG && !PROFILER
static readonly Dictionary<Type, Tuple<object, int>> implementorsByType =
new Dictionary<Type, Tuple<object, int>>();
#else
static readonly Dictionary<Type, object> implementorsByType = new Dictionary<Type, object>();
#endif

#if DEBUG && !PROFILER
struct Tuple<T1, T2>
{
public readonly T1 implementorType;
public T2 numberOfImplementations;

public Tuple(T1 implementor, T2 v)
{
implementorType = implementor;
numberOfImplementations = v;
}
}
#endif
static readonly Dictionary<Type, Type[]> _cachedTypes = new Dictionary<Type, Type[]>();
const string DUPLICATE_IMPLEMENTOR_ERROR =
"<color=orange>Svelto.ECS</color> the same component is implemented with more than one implementor. This is considered an error and MUST be fixed. ";

const string NULL_IMPLEMENTOR_ERROR =
"<color=orange>Svelto.ECS</color> Null implementor, please be careful about the implementors passed to avoid performance loss ";

const string NOT_FOUND_EXCEPTION = "<color=orange>Svelto.ECS</color> Implementor not found for an EntityView. ";
}

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

@@ -1,6 +1,6 @@
namespace Svelto.ECS
{
public abstract class GenericEntityDescriptor<T>:IEntityDescriptor where T : EntityView, new()
public abstract class GenericEntityDescriptor<T>:IEntityDescriptor where T : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -12,12 +12,12 @@
get { return entityViewBuilders; }
}

public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U> : IEntityDescriptor where T : EntityView, new()
where U : EntityView, new()
public abstract class GenericEntityDescriptor<T, U> : IEntityDescriptor where T : struct, IEntityData
where U : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -28,13 +28,13 @@
{
get { return entityViewBuilders; }
}
public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V> : IEntityDescriptor where T : EntityView, new()
where U : EntityView, new()
where V : EntityView, new()
public abstract class GenericEntityDescriptor<T, U, V> : IEntityDescriptor where T : struct, IEntityData
where U : struct, IEntityData
where V : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -45,14 +45,14 @@
{
get { return entityViewBuilders; }
}
public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W> : IEntityDescriptor where T : EntityView, new()
where U : EntityView, new()
where V : EntityView, new()
where W : EntityView, new()
public abstract class GenericEntityDescriptor<T, U, V, W> : IEntityDescriptor where T : struct, IEntityData
where U : struct, IEntityData
where V : struct, IEntityData
where W : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -63,15 +63,15 @@
{
get { return entityViewBuilders; }
}
public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W, X> : IEntityDescriptor where T : EntityView, new()
where U : EntityView, new()
where V : EntityView, new()
where W : EntityView, new()
where X : EntityView, new()
public abstract class GenericEntityDescriptor<T, U, V, W, X> : IEntityDescriptor where T : struct, IEntityData
where U : struct, IEntityData
where V : struct, IEntityData
where W : struct, IEntityData
where X : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -82,16 +82,16 @@
{
get { return entityViewBuilders; }
}
public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}

public abstract class GenericEntityDescriptor<T, U, V, W, X, Y> : IEntityDescriptor where T : EntityView, new()
where U : EntityView, new()
where V : EntityView, new()
where W : EntityView, new()
where X : EntityView, new()
where Y : EntityView, new()
public abstract class GenericEntityDescriptor<T, U, V, W, X, Y> : IEntityDescriptor where T : struct, IEntityData
where U : struct, IEntityData
where V : struct, IEntityData
where W : struct, IEntityData
where X : struct, IEntityData
where Y : struct, IEntityData
{
static GenericEntityDescriptor()
{
@@ -102,7 +102,7 @@
{
get { return entityViewBuilders; }
}
public static readonly IEntityViewBuilder[] entityViewBuilders;
static readonly IEntityViewBuilder[] entityViewBuilders;
}
}

+ 2
- 2
Svelto.ECS/IEngine.cs View File

@@ -2,8 +2,8 @@ namespace Svelto.ECS.Internal
{
public interface IHandleEntityViewEngine : IEngine
{
void Add(IEntityView entityView);
void Remove(IEntityView entityView);
void Add(IEntityData entityView);
void Remove(IEntityData entityView);
}
}



Svelto.ECS/EntityView.cs → Svelto.ECS/IEntityView.cs View File

@@ -8,25 +8,12 @@ namespace Svelto.ECS
{
//todo: can I remove the ID from the struct?
public interface IEntityView
public interface IEntityData
{
EGID ID { get; }
EGID ID { get; set; }
}
public interface IEntityStruct:IEntityView
{
new EGID ID { get; set; }
}

public class EntityView : IEntityView
{
public EGID ID { get { return _ID; } }

internal FasterList<KeyValuePair<Type, CastedAction<EntityView>>> entityViewBlazingFastReflection;
internal EGID _ID;
}

static class EntityView<T> where T: EntityView, new()
static class EntityView<T> where T: IEntityData, new()
{
internal static T BuildEntityView(EGID ID)
{
@@ -41,20 +28,20 @@ namespace Svelto.ECS
{
var field = fields[i];

CastedAction<EntityView> setter = FastInvoke<T>.MakeSetter<EntityView>(field);
CastedAction<T> setter = FastInvoke<T>.MakeSetter(field);
FieldCache<T>.list.Add(new KeyValuePair<Type, CastedAction<EntityView>>(field.FieldType, setter));
FieldCache<T>.list.Add(new KeyValuePair<Type, CastedAction<T>>(field.FieldType, setter));
}
}

return new T { _ID = ID, entityViewBlazingFastReflection = FieldCache<T>.list };
return new T { ID = ID };
}

//check if I can remove W
static class FieldCache<W> where W:T
internal static class FieldCache<W>
{
internal static readonly FasterList<KeyValuePair<Type, CastedAction<EntityView>>> list
= new FasterList<KeyValuePair<Type, CastedAction<EntityView>>>();
internal static readonly FasterList<KeyValuePair<Type, CastedAction<T>>> list
= new FasterList<KeyValuePair<Type, CastedAction<T>>>();
}
}
}

+ 16
- 0
Svelto.ECS/IEntityViewBuilder.cs View File

@@ -0,0 +1,16 @@
using System;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public interface IEntityViewBuilder
{
void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors);
ITypeSafeList Preallocate(ref ITypeSafeList list, int size);

Type GetEntityViewType();
void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList);

bool isQueryiableEntityView { get; }
}
}

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

@@ -4,13 +4,13 @@ namespace Svelto.ECS
{
public interface IEntityViewsDB
{
FasterReadOnlyList<T> QueryEntityViews<T>() where T : EntityView;
FasterReadOnlyList<T> QueryGroupedEntityViews<T>(int group) where T : EntityView;
FasterReadOnlyList<T> QueryEntityViews<T>() where T : IEntityData;
FasterReadOnlyList<T> QueryGroupedEntityViews<T>(int group) where T : IEntityData;

T[] QueryEntityViewsAsArray<T>(out int count) where T : IEntityView;
T[] QueryGroupedEntityViewsAsArray<T>(int group, out int count) where T : EntityView;
T[] QueryEntityViewsAsArray<T>(out int count) where T : IEntityData;
T[] QueryGroupedEntityViewsAsArray<T>(int group, out int count) where T : IEntityData;

bool TryQueryEntityView<T>(EGID ID, out T entityView) where T : EntityView;
T QueryEntityView<T>(EGID entityGID) where T : EntityView;
bool TryQueryEntityView<T>(EGID ID, out T entityView) where T : IEntityData;
T QueryEntityView<T>(EGID entityGID) where T : IEntityData;
}
}

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

@@ -2,14 +2,14 @@ using Svelto.ECS.Internal;

namespace Svelto.ECS.Internal
{
public abstract class MultiEntityViewsEngine<T> : IHandleEntityViewEngine where T : class, IEntityView
public abstract class MultiEntityViewsEngine<T> : IHandleEntityViewEngine where T : class, IEntityData
{
public virtual void Add(IEntityView entityView)
public virtual void Add(IEntityData entityView)
{
Add((T) entityView);
}

public virtual void Remove(IEntityView entityView)
public virtual void Remove(IEntityData entityView)
{
Remove((T) entityView);
}
@@ -22,12 +22,12 @@ namespace Svelto.ECS.Internal
namespace Svelto.ECS
{
public abstract class MultiEntityViewsEngine<T, U> : MultiEntityViewsEngine<T>
where U : class, IEntityView where T : class, IEntityView
where U : class, IEntityData where T : class, IEntityData
{
protected abstract void Add(U entityView);
protected abstract void Remove(U entityView);

public override void Add(IEntityView entityView)
public override void Add(IEntityData entityView)
{
if (entityView is U)
Add((U) entityView);
@@ -35,7 +35,7 @@ namespace Svelto.ECS
base.Add(entityView);
}

public override void Remove(IEntityView entityView)
public override void Remove(IEntityData entityView)
{
if (entityView is U)
Remove((U) entityView);
@@ -45,12 +45,12 @@ namespace Svelto.ECS
}

public abstract class MultiEntityViewsEngine<T, U, V> : MultiEntityViewsEngine<T, U>
where V : class, IEntityView where U : class, IEntityView where T : class, IEntityView
where V : class, IEntityData where U : class, IEntityData where T : class, IEntityData
{
protected abstract void Add(V entityView);
protected abstract void Remove(V entityView);

public override void Add(IEntityView entityView)
public override void Add(IEntityData entityView)
{
if (entityView is V)
Add((V) entityView);
@@ -58,7 +58,7 @@ namespace Svelto.ECS
base.Add(entityView);
}

public override void Remove(IEntityView entityView)
public override void Remove(IEntityData entityView)
{
if (entityView is V)
Remove((V) entityView);
@@ -73,12 +73,12 @@ namespace Svelto.ECS
/// already too many responsabilities.
/// </summary>
public abstract class MultiEntityViewsEngine<T, U, V, W> : MultiEntityViewsEngine<T, U, V>
where W : class, IEntityView where V : class, IEntityView where U : class, IEntityView where T : class, IEntityView
where W : class, IEntityData where V : class, IEntityData where U : class, IEntityData where T : class, IEntityData
{
protected abstract void Add(W entityView);
protected abstract void Remove(W entityView);

public override void Add(IEntityView entityView)
public override void Add(IEntityData entityView)
{
if (entityView is W)
Add((W) entityView);
@@ -86,7 +86,7 @@ namespace Svelto.ECS
base.Add(entityView);
}

public override void Remove(IEntityView entityView)
public override void Remove(IEntityData entityView)
{
if (entityView is W)
Remove((W) entityView);


+ 2
- 2
Svelto.ECS/Profiler/EngineProfiler.cs View File

@@ -14,7 +14,7 @@ namespace Svelto.ECS.Profiler

public static readonly Dictionary<Type, EngineInfo> engineInfos = new Dictionary<Type, EngineInfo>();

public static void MonitorAddDuration(IHandleEntityViewEngine engine, IEntityView entityView)
public static void MonitorAddDuration(IHandleEntityViewEngine engine, IEntityData entityView)
{
EngineInfo info;
if (engineInfos.TryGetValue(engine.GetType(), out info))
@@ -27,7 +27,7 @@ namespace Svelto.ECS.Profiler
}
}

public static void MonitorRemoveDuration(IHandleEntityViewEngine engine, IEntityView entityView)
public static void MonitorRemoveDuration(IHandleEntityViewEngine engine, IEntityData entityView)
{
EngineInfo info;
if (engineInfos.TryGetValue(engine.GetType(), out info))


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

@@ -2,14 +2,14 @@ using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public abstract class SingleEntityViewEngine<T> : IHandleEntityViewEngine where T : EntityView, new()
public abstract class SingleEntityViewEngine<T> : IHandleEntityViewEngine where T : class, IEntityData
{
public void Add(IEntityView entityView)
public void Add(IEntityData entityView)
{
Add((T) entityView); //when byref returns will be vailable, this should be passed by reference, not copy!
}

public void Remove(IEntityView entityView)
public void Remove(IEntityData entityView)
{
Remove((T) entityView);
}


Loading…
Cancel
Save