@@ -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]; | |||
} | |||
@@ -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; | |||
@@ -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) | |||
@@ -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); | |||
} | |||
} |
@@ -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; | |||
@@ -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 | |||
@@ -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. "; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
@@ -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. "; | |||
} |
@@ -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,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); | |||
} | |||
} | |||
@@ -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>>>(); | |||
} | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
@@ -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)) | |||
@@ -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); | |||
} | |||