@@ -16,12 +16,12 @@ namespace Svelto.ECS.Internal | |||
ITypeSafeDictionary CreateIndexedDictionary(); | |||
IEntityView[] ToArrayFast(out int count); | |||
void ReserveCapacity(int capacity); | |||
void Fill(FasterList<IHandleEntityViewEngineAbstracted> enginesForEntityView); | |||
} | |||
class TypeSafeFasterListForECS<T> : FasterList<T> where T : IEntityView | |||
{ | |||
readonly Dictionary<int, int> _mappedIndices; | |||
protected TypeSafeFasterListForECS() | |||
{ | |||
_mappedIndices = new Dictionary<int, int>(); | |||
@@ -76,10 +76,11 @@ namespace Svelto.ECS.Internal | |||
{ | |||
return _mappedIndices[entityID]; | |||
} | |||
readonly Dictionary<int, int> _mappedIndices; | |||
} | |||
class TypeSafeFasterListForECSForStructs<T> : TypeSafeFasterListForECS<T>, ITypeSafeList | |||
where T : struct, IEntityStruct | |||
class TypeSafeFasterListForECSForStructs<T> : TypeSafeFasterListForECS<T>, ITypeSafeList where T:struct, IEntityView | |||
{ | |||
public TypeSafeFasterListForECSForStructs(int size) : base(size) | |||
{ | |||
@@ -101,12 +102,30 @@ namespace Svelto.ECS.Internal | |||
public ITypeSafeDictionary CreateIndexedDictionary() | |||
{ | |||
throw new Exception("Not Allowed"); | |||
throw new NotImplementedException(); | |||
} | |||
public IEntityView[] ToArrayFast(out int count) | |||
{ | |||
throw new Exception("Not Allowed"); | |||
throw new NotImplementedException(); | |||
} | |||
public void Fill(FasterList<IHandleEntityViewEngineAbstracted> enginesForEntityView) | |||
{ | |||
var thisfastList = NoVirt.ToArrayFast(this); | |||
for (int i = 0; i < Count; i++) | |||
{ | |||
int count; | |||
var fastList = FasterList<IHandleEntityViewEngineAbstracted>.NoVirt.ToArrayFast(enginesForEntityView, out count); | |||
for (int j = 0; j < count; j++) | |||
{ | |||
#if ENGINE_PROFILER_ENABLED | |||
EngineProfiler.MonitorAddDuration<T>(fastList[j], entityView); | |||
#else | |||
(fastList[j] as IHandleEntityStructEngine<T>).Add(ref thisfastList[j]); | |||
#endif | |||
} | |||
} | |||
} | |||
public ITypeSafeList Create(int size) | |||
@@ -114,8 +133,8 @@ namespace Svelto.ECS.Internal | |||
return new TypeSafeFasterListForECSForStructs<T>(size); | |||
} | |||
} | |||
class TypeSafeFasterListForECSForClasses<T> : TypeSafeFasterListForECS<T>, ITypeSafeList where T : EntityView, new() | |||
class TypeSafeFasterListForECSForClasses<T> : TypeSafeFasterListForECS<T>, ITypeSafeList where T:class, IEntityView, new() | |||
{ | |||
public TypeSafeFasterListForECSForClasses(int size) : base(size) | |||
{ | |||
@@ -147,6 +166,24 @@ namespace Svelto.ECS.Internal | |||
return ToArrayFast(); | |||
} | |||
public void Fill(FasterList<IHandleEntityViewEngineAbstracted> enginesForEntityView) | |||
{ | |||
var thisfastList = NoVirt.ToArrayFast(this); | |||
for (int i = 0; i < Count; i++) | |||
{ | |||
int count; | |||
var fastList = FasterList<IHandleEntityViewEngineAbstracted>.NoVirt.ToArrayFast(enginesForEntityView, out count); | |||
for (int j = 0; j < count; j++) | |||
{ | |||
#if ENGINE_PROFILER_ENABLED | |||
EngineProfiler.MonitorAddDuration(fastList[j], entityView); | |||
#else | |||
(fastList[j] as IHandleEntityStructEngine<T>).Add(ref thisfastList[j]); | |||
#endif | |||
} | |||
} | |||
} | |||
public ITypeSafeList Create(int size) | |||
{ | |||
return new TypeSafeFasterListForECSForClasses<T>(size); | |||
@@ -35,7 +35,7 @@ namespace Svelto.ECS | |||
/// </summary> | |||
public EnginesRoot(EntitySubmissionScheduler entityViewScheduler) | |||
{ | |||
_entityViewEngines = new Dictionary<Type, FasterList<IHandleEntityViewEngine>>(); | |||
_entityViewEngines = new Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>>(); | |||
_otherEngines = new FasterList<IEngine>(); | |||
_entityViewsDB = new Dictionary<Type, ITypeSafeList>(); | |||
@@ -59,7 +59,7 @@ namespace Svelto.ECS | |||
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR | |||
Profiler.EngineProfiler.AddEngine(engine); | |||
#endif | |||
var viewEngine = engine as IHandleEntityViewEngine; | |||
var viewEngine = engine as IHandleEntityViewEngineAbstracted; | |||
if (viewEngine != null) | |||
CheckEntityViewsEngine(viewEngine); | |||
@@ -78,12 +78,13 @@ namespace Svelto.ECS | |||
{ | |||
var baseType = engine.GetType().GetBaseType(); | |||
while (baseType != _object) | |||
while (baseType != _objectType) | |||
{ | |||
if (baseType.IsGenericTypeEx()) | |||
{ | |||
var genericArguments = baseType.GetGenericArgumentsEx(); | |||
AddEngine(engine as IHandleEntityViewEngine, genericArguments, _entityViewEngines); | |||
AddEngine(engine as IHandleEntityViewEngineAbstracted, genericArguments, _entityViewEngines); | |||
return; | |||
} | |||
@@ -120,11 +121,12 @@ namespace Svelto.ECS | |||
list.Add(engine); | |||
} | |||
readonly Dictionary<Type, FasterList<IHandleEntityViewEngine>> _entityViewEngines; | |||
readonly Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>> _entityViewEngines; | |||
readonly FasterList<IEngine> _otherEngines; | |||
static readonly Type _entityViewType= typeof(EntityView); | |||
static readonly Type _object = typeof(object); | |||
static readonly Type _objectType = typeof(object); | |||
static readonly Type _valueType = typeof(ValueType); | |||
class DoubleBufferedEntityViews<T> where T : class, IDictionary, new() | |||
{ | |||
@@ -15,7 +15,7 @@ namespace Svelto.ECS | |||
public void Dispose() | |||
{ | |||
foreach (var entity in _entityViewsDB) | |||
if (entity.Value.isQueryiableEntityView) | |||
if (entity.Value.isQueryiableEntityView == true) | |||
foreach (var entityView in entity.Value) | |||
RemoveEntityViewFromEngines(_entityViewEngines, entityView as EntityView, entity.Key); | |||
@@ -204,6 +204,11 @@ namespace Svelto.ECS | |||
Type entityViewType, | |||
int entityID) | |||
{ | |||
#if DEBUG && !PROFILE | |||
if (entityViewsDB.ContainsKey(entityViewType) == false) | |||
throw new Exception(NO_ENTITY_FOUND_EXCEPTION + " - EntityViewType: " + | |||
entityViewType.Name + " - ID " + entityID); | |||
#endif | |||
var entityViews = entityViewsDB[entityViewType]; | |||
if (entityViews.MappedRemove(entityID) == false) | |||
entityViewsDB.Remove(entityViewType); | |||
@@ -300,23 +305,23 @@ namespace Svelto.ECS | |||
} | |||
} | |||
static void RemoveEntityViewFromEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines, | |||
IEntityView entityView, | |||
Type entityViewType) | |||
static void RemoveEntityViewFromEngines(Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>> entityViewEngines, | |||
IEntityView entityView, Type entityViewType) | |||
{ | |||
FasterList<IHandleEntityViewEngine> enginesForEntityView; | |||
FasterList<IHandleEntityViewEngineAbstracted> enginesForEntityView; | |||
if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) | |||
{ | |||
int count; | |||
var fastList = FasterList<IHandleEntityViewEngine>.NoVirt.ToArrayFast(enginesForEntityView, out count); | |||
var fastList = FasterList<IHandleEntityViewEngineAbstracted>.NoVirt.ToArrayFast(enginesForEntityView, out count); | |||
for (var j = 0; j < count; j++) | |||
{ | |||
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR | |||
EngineProfiler.MonitorRemoveDuration(fastList[j], entityView); | |||
#else | |||
fastList[j].Remove(entityView); | |||
var handleMixedEntityViewEngine = (fastList[j] as IHandleEntityViewEngine); | |||
handleMixedEntityViewEngine.Remove(entityView); | |||
#endif | |||
} | |||
} | |||
@@ -401,6 +406,9 @@ namespace Svelto.ECS | |||
readonly Dictionary<Type, ITypeSafeDictionary> _entityViewsDBDic; | |||
readonly Dictionary<int, Dictionary<Type, ITypeSafeList>> _groupEntityViewsDB; | |||
readonly Dictionary<Type, ITypeSafeList> _metaEntityViewsDB; | |||
const string NO_ENTITY_FOUND_EXCEPTION = | |||
"<color=orange>Svelto.ECS</color> Trying to remove an Entity never added, please be sure the " + | |||
"Entity is submitted before trying to remove it"; | |||
readonly Dictionary<Type, ITypeSafeDictionary> _metaEntityViewsDBDic; | |||
} |
@@ -71,13 +71,10 @@ namespace Svelto.ECS | |||
foreach (var entityViewList in entityViewsToAdd) | |||
{ | |||
if (entityViewList.Value.isQueryiableEntityView) | |||
{ | |||
var type = entityViewList.Key; | |||
for (var current = type; current != _entityViewType; current = current.BaseType) | |||
for (var current = type; current != _entityViewType && current != _objectType && current != _valueType; current = current.BaseType) | |||
AddEntityViewToTheSuitableEngines(_entityViewEngines, entityViewList.Value, | |||
current); | |||
} | |||
} | |||
} | |||
@@ -129,30 +126,15 @@ namespace Svelto.ECS | |||
entityViewsDic.FillWithIndexedEntityViews(entityViews); | |||
} | |||
static void AddEntityViewToTheSuitableEngines(Dictionary<Type, FasterList<IHandleEntityViewEngine>> entityViewEngines, ITypeSafeList entityViewsList, Type entityViewType) | |||
static void AddEntityViewToTheSuitableEngines(Dictionary<Type, FasterList<IHandleEntityViewEngineAbstracted>> entityViewEngines, | |||
ITypeSafeList entityViewsList, | |||
Type entityViewType) | |||
{ | |||
FasterList<IHandleEntityViewEngine> enginesForEntityView; | |||
FasterList<IHandleEntityViewEngineAbstracted> enginesForEntityView; | |||
if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) | |||
{ | |||
int viewsCount; | |||
var entityViews = entityViewsList.ToArrayFast(out viewsCount); | |||
for (int i = 0; i < viewsCount; i++) | |||
{ | |||
int count; | |||
var fastList = FasterList<IHandleEntityViewEngine>.NoVirt.ToArrayFast(enginesForEntityView, out count); | |||
IEntityView entityView = entityViews[i]; | |||
for (int j = 0; j < count; j++) | |||
{ | |||
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR | |||
EngineProfiler.MonitorAddDuration(fastList[j], entityView); | |||
#else | |||
fastList[j].Add(entityView); | |||
#endif | |||
} | |||
} | |||
entityViewsList.Fill(enginesForEntityView); | |||
} | |||
} | |||
@@ -5,7 +5,7 @@ namespace Svelto.ECS | |||
UnityEngine.MonoBehaviour , IEntityDescriptorHolder | |||
where T: class, IEntityDescriptor, new() | |||
{ | |||
public IEntityDescriptorInfo RetrieveDescriptor() | |||
public IEntityDescriptorInfo RetrieveDescriptorInfo() | |||
{ | |||
return EntityDescriptorTemplate<T>.Default; | |||
} | |||
@@ -44,10 +44,10 @@ namespace Svelto.ECS.Schedulers.Unity | |||
internal WeakAction OnTick; | |||
WaitForEndOfFrame _wait = new WaitForEndOfFrame(); | |||
readonly WaitForEndOfFrame _wait = new WaitForEndOfFrame(); | |||
} | |||
Scheduler _scheduler; | |||
readonly Scheduler _scheduler; | |||
} | |||
} | |||
#endif |
@@ -1,8 +1,12 @@ | |||
using Svelto.ECS.Internal; | |||
namespace Svelto.ECS.Internal | |||
{ | |||
public interface IHandleEntityViewEngine : IEngine | |||
public interface IHandleEntityViewEngineAbstracted : IEngine | |||
{} | |||
public interface IHandleEntityViewEngine : IHandleEntityViewEngineAbstracted | |||
{ | |||
void Add(IEntityView entityView); | |||
void Remove(IEntityView entityView); | |||
} | |||
} | |||
@@ -10,6 +14,10 @@ namespace Svelto.ECS.Internal | |||
namespace Svelto.ECS | |||
{ | |||
public interface IEngine | |||
{} | |||
public interface IHandleEntityStructEngine<T> : IHandleEntityViewEngineAbstracted | |||
{ | |||
void Add(ref T entityView); | |||
} | |||
} |
@@ -2,6 +2,6 @@ namespace Svelto.ECS | |||
{ | |||
public interface IEntityDescriptorHolder | |||
{ | |||
IEntityDescriptorInfo RetrieveDescriptor(); | |||
IEntityDescriptorInfo RetrieveDescriptorInfo(); | |||
} | |||
} |
@@ -2,11 +2,12 @@ using Svelto.ECS.Internal; | |||
namespace Svelto.ECS.Internal | |||
{ | |||
public abstract class MultiEntityViewsEngine<T> : IHandleEntityViewEngine where T : class, IEntityView | |||
public abstract class MultiEntityViewsEngine<T>:IHandleEntityStructEngine<T>, | |||
IHandleEntityViewEngine where T:IEntityView | |||
{ | |||
public virtual void Add(IEntityView entityView) | |||
public void Add(ref T entityView) | |||
{ | |||
Add((T) entityView); | |||
Add(entityView); | |||
} | |||
public virtual void Remove(IEntityView entityView) | |||
@@ -14,27 +15,19 @@ namespace Svelto.ECS.Internal | |||
Remove((T) entityView); | |||
} | |||
protected abstract void Add(T entityView); | |||
protected abstract void Add(T entityView); | |||
protected abstract void Remove(T entityView); | |||
} | |||
} | |||
namespace Svelto.ECS | |||
{ | |||
public abstract class MultiEntityViewsEngine<T, U> : MultiEntityViewsEngine<T> | |||
where U : class, IEntityView where T : class, IEntityView | |||
public abstract class MultiEntityViewsEngine<T, U> : MultiEntityViewsEngine<T>, IHandleEntityStructEngine<U> | |||
where U : IEntityView where T : IEntityView | |||
{ | |||
protected abstract void Add(U entityView); | |||
protected abstract void Remove(U entityView); | |||
public override void Add(IEntityView entityView) | |||
{ | |||
if (entityView is U) | |||
Add((U) entityView); | |||
else | |||
base.Add(entityView); | |||
} | |||
public override void Remove(IEntityView entityView) | |||
{ | |||
if (entityView is U) | |||
@@ -42,22 +35,19 @@ namespace Svelto.ECS | |||
else | |||
base.Remove(entityView); | |||
} | |||
public void Add(ref U entityView) | |||
{ | |||
Add(entityView); | |||
} | |||
} | |||
public abstract class MultiEntityViewsEngine<T, U, V> : MultiEntityViewsEngine<T, U> | |||
where V : class, IEntityView where U : class, IEntityView where T : class, IEntityView | |||
public abstract class MultiEntityViewsEngine<T, U, V> : MultiEntityViewsEngine<T, U>, IHandleEntityStructEngine<V> | |||
where V : IEntityView where U : IEntityView where T : IEntityView | |||
{ | |||
protected abstract void Add(V entityView); | |||
protected abstract void Remove(V entityView); | |||
public override void Add(IEntityView entityView) | |||
{ | |||
if (entityView is V) | |||
Add((V) entityView); | |||
else | |||
base.Add(entityView); | |||
} | |||
public override void Remove(IEntityView entityView) | |||
{ | |||
if (entityView is V) | |||
@@ -65,6 +55,11 @@ namespace Svelto.ECS | |||
else | |||
base.Remove(entityView); | |||
} | |||
public void Add(ref V entityView) | |||
{ | |||
Add(entityView); | |||
} | |||
} | |||
/// <summary> | |||
@@ -72,20 +67,12 @@ namespace Svelto.ECS | |||
/// if you use more than 4 nodes, your engine has | |||
/// 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 | |||
public abstract class MultiEntityViewsEngine<T, U, V, W> : MultiEntityViewsEngine<T, U, V>, IHandleEntityStructEngine<W> | |||
where W : IEntityView where V : IEntityView where U : IEntityView where T : IEntityView | |||
{ | |||
protected abstract void Add(W entityView); | |||
protected abstract void Remove(W entityView); | |||
public override void Add(IEntityView entityView) | |||
{ | |||
if (entityView is W) | |||
Add((W) entityView); | |||
else | |||
base.Add(entityView); | |||
} | |||
public override void Remove(IEntityView entityView) | |||
{ | |||
if (entityView is W) | |||
@@ -93,5 +80,10 @@ namespace Svelto.ECS | |||
else | |||
base.Remove(entityView); | |||
} | |||
public void Add(ref W entityView) | |||
{ | |||
Add(entityView); | |||
} | |||
} | |||
} |
@@ -12,28 +12,26 @@ namespace Svelto.ECS.Profiler | |||
{ | |||
static readonly Stopwatch _stopwatch = new Stopwatch(); | |||
public static readonly Dictionary<Type, EngineInfo> engineInfos = new Dictionary<Type, EngineInfo>(); | |||
public static void MonitorAddDuration(IHandleEntityViewEngine engine, IEntityView entityView) | |||
public static void MonitorAddDuration<T>(IHandleEntityViewEngineAbstracted engine, T entityView) | |||
{ | |||
EngineInfo info; | |||
if (engineInfos.TryGetValue(engine.GetType(), out info)) | |||
{ | |||
_stopwatch.Start(); | |||
engine.Add(entityView); | |||
(engine as IHandleEntityStructEngine<T>).Add(ref entityView); | |||
_stopwatch.Stop(); | |||
info.AddAddDuration(_stopwatch.Elapsed.TotalMilliseconds); | |||
_stopwatch.Reset(); | |||
} | |||
} | |||
public static void MonitorRemoveDuration(IHandleEntityViewEngine engine, IEntityView entityView) | |||
public static void MonitorRemoveDuration<T>(IHandleEntityViewEngineAbstracted engine, IEntityView entityView) | |||
{ | |||
EngineInfo info; | |||
if (engineInfos.TryGetValue(engine.GetType(), out info)) | |||
{ | |||
_stopwatch.Start(); | |||
engine.Remove(entityView); | |||
(engine as IHandleEntityViewEngine).Remove(entityView); | |||
_stopwatch.Stop(); | |||
info.AddRemoveDuration(_stopwatch.Elapsed.TotalMilliseconds); | |||
@@ -44,12 +42,19 @@ namespace Svelto.ECS.Profiler | |||
public static void AddEngine(IEngine engine) | |||
{ | |||
if (engineInfos.ContainsKey(engine.GetType()) == false) | |||
{ | |||
engineInfos.Add(engine.GetType(), new EngineInfo(engine)); | |||
} | |||
} | |||
public static void ResetDurations() | |||
{ | |||
foreach (var engine in engineInfos) engine.Value.ResetDurations(); | |||
foreach (var engine in engineInfos) | |||
{ | |||
engine.Value.ResetDurations(); | |||
} | |||
} | |||
public static readonly Dictionary<Type, EngineInfo> engineInfos = new Dictionary<Type, EngineInfo>(); | |||
} | |||
} | |||
} |
@@ -2,11 +2,11 @@ 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, IEntityView | |||
{ | |||
public void Add(IEntityView entityView) | |||
{ | |||
Add((T) entityView); //when byref returns will be vailable, this should be passed by reference, not copy! | |||
Add((T) entityView); | |||
} | |||
public void Remove(IEntityView entityView) | |||