diff --git a/Context/Factories/GameObjectFactory.cs b/Context/Factories/GameObjectFactory.cs
index 551c88f..a8cde2b 100644
--- a/Context/Factories/GameObjectFactory.cs
+++ b/Context/Factories/GameObjectFactory.cs
@@ -42,7 +42,7 @@ namespace Svelto.Context
/// Register a prefab to be built later using a string ID.
///
/// original prefab
- public GameObject Build(GameObject prefab)
+ virtual public GameObject Build(GameObject prefab)
{
var copy = Object.Instantiate(prefab) as GameObject;
diff --git a/Context/Factories/MonoBehaviourFactory.cs b/Context/Factories/MonoBehaviourFactory.cs
index 62502f6..94786dd 100644
--- a/Context/Factories/MonoBehaviourFactory.cs
+++ b/Context/Factories/MonoBehaviourFactory.cs
@@ -10,11 +10,7 @@ namespace Svelto.Context
{
public class MonoBehaviourFactory : Factories.IMonoBehaviourFactory
{
- public MonoBehaviourFactory()
- {
- }
-
- public M Build(Func constructor) where M : MonoBehaviour
+ virtual public M Build(Func constructor) where M : MonoBehaviour
{
var mb = constructor();
diff --git a/DataStructures/FasterList.cs b/DataStructures/FasterList.cs
index 78cbaa2..ae44d60 100644
--- a/DataStructures/FasterList.cs
+++ b/DataStructures/FasterList.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Threading;
using UnityEngine;
namespace Svelto.DataStructures
@@ -188,6 +189,183 @@ namespace Svelto.DataStructures
readonly FasterList _list;
}
+ public struct FasterListThreadSafe : IList
+ {
+ public FasterListThreadSafe(FasterList list)
+ {
+ _list = list;
+ _lockQ = new ReaderWriterLockSlim();
+ }
+
+ public int Count
+ {
+ get
+ {
+ _lockQ.EnterReadLock();
+ try
+ {
+ return _list.Count;
+ }
+ finally
+ {
+ _lockQ.ExitReadLock();
+ }
+ }
+ }
+ public bool IsReadOnly { get { return false; } }
+
+ public T this[int index]
+ {
+ get
+ {
+ _lockQ.EnterReadLock();
+ try
+ {
+ return _list[index];
+ }
+ finally
+ {
+ _lockQ.ExitReadLock();
+ }
+ }
+ set
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list[index] = value;
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+ }
+
+ public FasterListEnumerator GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Add(T item)
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list.Add(item);
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ public void Clear()
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list.Clear();
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ public bool Contains(T item)
+ {
+ _lockQ.EnterReadLock();
+ try
+ {
+ return _list.Contains(item);
+ }
+ finally
+ {
+ _lockQ.ExitReadLock();
+ }
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list.CopyTo(array, arrayIndex);
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ public bool Remove(T item)
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ return _list.Remove(item);
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ public int IndexOf(T item)
+ {
+ _lockQ.EnterReadLock();
+ try
+ {
+ return _list.IndexOf(item);
+ }
+ finally
+ {
+ _lockQ.ExitReadLock();
+ }
+ }
+
+ public void Insert(int index, T item)
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list.Insert(index, item);
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ public void RemoveAt(int index)
+ {
+ _lockQ.EnterWriteLock();
+ try
+ {
+ _list.RemoveAt(index);
+ }
+ finally
+ {
+ _lockQ.ExitWriteLock();
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ readonly FasterList _list;
+
+ readonly ReaderWriterLockSlim _lockQ;
+ }
+
public struct FasterReadOnlyListCast : IList where U:T
{
public static FasterList DefaultList = new FasterList();
@@ -320,6 +498,14 @@ namespace Svelto.DataStructures
_buffer[_count++] = item;
}
+
+ ///
+ /// this is a dirtish trick to be able to use the index operastor
+ /// before adding the elements through the Add functions
+ ///
+ ///
+ ///
+ ///
public static FasterList PreFill(int initialSize) where U:T, new()
{
var list = new FasterList(initialSize);
diff --git a/DataStructures/ThreadSafeDictionary.cs b/DataStructures/ThreadSafeDictionary.cs
index 94a3646..1505547 100644
--- a/DataStructures/ThreadSafeDictionary.cs
+++ b/DataStructures/ThreadSafeDictionary.cs
@@ -1,7 +1,10 @@
+
using System;
using System.Collections.Generic;
using System.Threading;
+//note, rewrite like ThreadSafeQueue
+
namespace Svelto.DataStructures
{
///
@@ -13,6 +16,16 @@ namespace Svelto.DataStructures
[Serializable]
public class ThreadSafeDictionary
{
+ public ThreadSafeDictionary(int v)
+ {
+ dict = new Dictionary(v);
+ }
+
+ public ThreadSafeDictionary()
+ {
+ dict = new Dictionary();
+ }
+
// setup the lock;
public virtual int Count
{
@@ -183,7 +196,7 @@ namespace Svelto.DataStructures
}
// This is the internal dictionary that we are wrapping
- readonly IDictionary dict = new Dictionary();
+ readonly IDictionary dict;
[NonSerialized] readonly ReaderWriterLockSlim dictionaryLock = Locks.GetLockInstance(LockRecursionPolicy.NoRecursion);
}
diff --git a/DataStructures/ThreadSafeQueue.cs b/DataStructures/ThreadSafeQueue.cs
index 4505dd8..d9197f0 100644
--- a/DataStructures/ThreadSafeQueue.cs
+++ b/DataStructures/ThreadSafeQueue.cs
@@ -1,4 +1,3 @@
-using System.Collections;
using System.Collections.Generic;
using System.Threading;
@@ -6,9 +5,9 @@ namespace Svelto.DataStructures
{
public class ThreadSafeQueue
{
- private readonly Queue m_Queue;
+ readonly Queue m_Queue;
- private readonly ReaderWriterLockSlim LockQ = new ReaderWriterLockSlim();
+ readonly ReaderWriterLockSlim LockQ = new ReaderWriterLockSlim();
public ThreadSafeQueue()
{
@@ -121,6 +120,22 @@ namespace Svelto.DataStructures
}
}
+ public void DequeueInto(FasterList list, int count)
+ {
+ LockQ.EnterWriteLock();
+ try
+ {
+ int originalSize = m_Queue.Count;
+ while (m_Queue.Count > 0 && originalSize - m_Queue.Count < count)
+ list.Add(m_Queue.Dequeue());
+ }
+
+ finally
+ {
+ LockQ.ExitWriteLock();
+ }
+ }
+
public FasterList DequeueAllAs() where U:class
{
LockQ.EnterWriteLock();
diff --git a/ECS/Dispatcher/DispatcherOnChange.cs b/ECS/Dispatcher/DispatchOnChange.cs
similarity index 100%
rename from ECS/Dispatcher/DispatcherOnChange.cs
rename to ECS/Dispatcher/DispatchOnChange.cs
diff --git a/ECS/Dispatcher/DispatcherOnChange.cs.meta b/ECS/Dispatcher/DispatchOnChange.cs.meta
similarity index 100%
rename from ECS/Dispatcher/DispatcherOnChange.cs.meta
rename to ECS/Dispatcher/DispatchOnChange.cs.meta
diff --git a/ECS/EngineNodeDB.cs b/ECS/EngineNodeDB.cs
index 1ed8944..8c73fa2 100644
--- a/ECS/EngineNodeDB.cs
+++ b/ECS/EngineNodeDB.cs
@@ -94,6 +94,10 @@ namespace Svelto.ECS
Dictionary> _nodesDBdic;
Dictionary> _nodesDBgroups;
+ //Dictionary> _nodesDB;
+ //Dictionary> _nodesDBdic;
+// Dictionary> _nodesDBgroups;
+
ReadOnlyDictionary _defaultEmptyNodeDict = new ReadOnlyDictionary(new Dictionary());
}
}
diff --git a/ECS/EnginesRoot.cs b/ECS/EnginesRoot.cs
index 0f1867a..d3af55c 100644
--- a/ECS/EnginesRoot.cs
+++ b/ECS/EnginesRoot.cs
@@ -122,31 +122,32 @@ namespace Svelto.ECS
var nodesEngine = engine as INodesEngine;
AddEngine(nodesEngine, nodesEngine.AcceptedNodes(), _nodeEngines);
-
- return;
}
+ else
+ {
+
+ var engineType = engine.GetType();
+// Type baseInterface = null;
+
#if !NETFX_CORE
- var baseType = engine.GetType().BaseType;
+ var baseType = engineType.BaseType;
- if (baseType.IsGenericType)
+ if (baseType.IsGenericType
#else
- var baseType = engine.GetType().GetTypeInfo().BaseType;
+ var baseType = engineType.GetTypeInfo().BaseType;
- if (baseType.IsConstructedGenericType)
+ if (baseType.IsConstructedGenericType
#endif
-
- {
- var genericType = baseType.GetGenericTypeDefinition();
-
- if (genericType == typeof(SingleNodeEngine<>))
+ && baseType.GetGenericTypeDefinition() == typeof (SingleNodeEngine<>))
{
AddEngine(engine as INodeEngine, baseType.GetGenericArguments(), _nodeEngines);
-
- return;
}
+ else
+ _otherEnginesReferences.Add(engine);
}
-
- _otherEnginesReferences.Add(engine);
+
+ if (engine is ICallBackOnAddEngine)
+ (engine as ICallBackOnAddEngine).Ready();
}
public void BuildEntity(int ID, EntityDescriptor ed)
@@ -160,6 +161,19 @@ namespace Svelto.ECS
_nodesToAdd.AddRange(entityNodes);
}
+ ///
+ /// An entity group is a meta entity. It's a way to create a set of entitites that
+ /// are not easily queriable otherwise. For example you may group existing entities
+ /// by size and type and then use the groupID to retrieve a single node that is shared
+ /// among the single entities of the same type and size. This willwd prevent the scenario
+ /// where the coder is forced to parse all the entities to find the ones of the same
+ /// size and type. Since the entity group is managed through the shared node, the same
+ /// shared node must be found on the single entities of the same type and size.
+ /// The shared node is then used by engines that are meant to manage a group of entities
+ /// through a single node. The same engine can manage several groups of entitites.
+ ///
+ ///
+ ///
public void BuildEntityGroup(int groupID, EntityDescriptor ed)
{
var entityNodes = ed.BuildNodes(groupID, (node) =>
@@ -234,7 +248,7 @@ namespace Svelto.ECS
{
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
EngineProfiler.MonitorAddDuration(AddNodeToEngine, enginesForNode[j], node);
-#else
+#else
enginesForNode[j].Add(node);
#endif
}
@@ -280,7 +294,7 @@ namespace Svelto.ECS
{
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
EngineProfiler.MonitorRemoveDuration(RemoveNodeFromEngine, enginesForNode[j], node);
-#else
+#else
enginesForNode[j].Remove(node);
#endif
}
@@ -317,22 +331,15 @@ namespace Svelto.ECS
Dictionary>> _nodeEngines;
FasterList _otherEnginesReferences;
- Dictionary> _nodesDB;
- Dictionary> _nodesDBdic;
-
- Dictionary> _nodesDBgroups;
-
- FasterList _nodesToAdd;
- FasterList _groupNodesToAdd;
+ Dictionary> _nodesDB;
+ Dictionary> _nodesDBdic;
- WeakReference _engineRootWeakReference;
+ Dictionary> _nodesDBgroups;
- //integrated pooling system
- //add debug panel like Entitas has
- //GCHandle should be used to reduce the number of strong references
- //datastructure could be thread safe
+ FasterList _nodesToAdd;
+ FasterList _groupNodesToAdd;
- //future enhancements:
+ WeakReference _engineRootWeakReference;
}
}
diff --git a/ECS/EntityDescriptor.cs b/ECS/EntityDescriptor.cs
index 6183fd5..7dab7ee 100644
--- a/ECS/EntityDescriptor.cs
+++ b/ECS/EntityDescriptor.cs
@@ -1,6 +1,9 @@
using System;
using System.Reflection;
using Svelto.DataStructures;
+#if NETFX_CORE
+using BindingFlags = System.Reflection.BindingFlags;
+#endif
namespace Svelto.ECS
{
@@ -12,6 +15,16 @@ namespace Svelto.ECS
_nodesToBuild = nodesToBuild;
}
+ public void AddImplementors(params object[] componentsImplementor)
+ {
+ var implementors = new object[componentsImplementor.Length + _implementors.Length];
+
+ Array.Copy(_implementors, implementors, _implementors.Length);
+ Array.Copy(componentsImplementor, 0, implementors, _implementors.Length, componentsImplementor.Length);
+
+ _implementors = implementors;
+ }
+
public virtual FasterList BuildNodes(int ID, Action removeAction)
{
var nodes = new FasterList();
@@ -73,8 +86,9 @@ namespace Svelto.ECS
return node;
}
- readonly object[] _implementors;
- INodeBuilder[] _nodesToBuild;
+ object[] _implementors;
+
+ readonly INodeBuilder[] _nodesToBuild;
}
public interface INodeBuilder
diff --git a/ECS/GenericEntityDescriptor.cs b/ECS/GenericEntityDescriptor.cs
index 16c2687..62ddd73 100644
--- a/ECS/GenericEntityDescriptor.cs
+++ b/ECS/GenericEntityDescriptor.cs
@@ -5,14 +5,11 @@
{
static GenericEntityDescriptor()
{
- _nodesToBuild = new INodeBuilder[]
- {
- new NodeBuilder()
- };
+ _nodesToBuild = new INodeBuilder[] { new NodeBuilder() };
}
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
- {
- }
+ {}
+
static INodeBuilder[] _nodesToBuild;
}
@@ -28,9 +25,10 @@
new NodeBuilder()
};
}
+
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
- {
- }
+ {}
+
static INodeBuilder[] _nodesToBuild;
}
diff --git a/ECS/GenericEntityDescriptorHolder.cs b/ECS/GenericEntityDescriptorHolder.cs
new file mode 100644
index 0000000..4758fa2
--- /dev/null
+++ b/ECS/GenericEntityDescriptorHolder.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Svelto.ECS
+{
+ public class GenericEntityDescriptorHolder: UnityEngine.MonoBehaviour, IEntityDescriptorHolder where T:EntityDescriptor
+ {
+ public EntityDescriptor BuildDescriptorType(object[] externalImplentors)
+ {
+ I[] implementors;
+
+ if (externalImplentors != null)
+ {
+ I[] baseImplentors = gameObject.GetComponents();
+
+ implementors = new I[externalImplentors.Length + baseImplentors.Length];
+
+ Array.Copy(baseImplentors, implementors, baseImplentors.Length);
+ Array.Copy(externalImplentors, 0, implementors, baseImplentors.Length, externalImplentors.Length);
+ }
+ else
+ {
+ implementors = gameObject.GetComponents();
+ }
+
+ return (T)Activator.CreateInstance(typeof(T), implementors);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ECS/GenericEntityDescriptorHolder.cs.meta b/ECS/GenericEntityDescriptorHolder.cs.meta
new file mode 100644
index 0000000..fc5bfc6
--- /dev/null
+++ b/ECS/GenericEntityDescriptorHolder.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f2bc0783e8d4a7b49a84705c55d8b255
+timeCreated: 1498225965
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/ECS/ICallBackOnAddEngine.cs b/ECS/ICallBackOnAddEngine.cs
new file mode 100644
index 0000000..30ac6de
--- /dev/null
+++ b/ECS/ICallBackOnAddEngine.cs
@@ -0,0 +1,7 @@
+namespace Svelto.ECS
+{
+ interface ICallBackOnAddEngine
+ {
+ void Ready();
+ }
+}
\ No newline at end of file
diff --git a/ECS/ICallBackOnAddEngine.cs.meta b/ECS/ICallBackOnAddEngine.cs.meta
new file mode 100644
index 0000000..80e5f96
--- /dev/null
+++ b/ECS/ICallBackOnAddEngine.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3928de9a08e5b534ab857ea8b5bebdaf
+timeCreated: 1497524074
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs b/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs
index 1ac387a..a691298 100644
--- a/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs
+++ b/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs
@@ -21,7 +21,6 @@ namespace Svelto.ECS.Profiler
}
static bool _hideEmptyEngines = true;
- static bool _showTickEngines;
static bool _showAddEngines;
static bool _showRemoveEngines;
@@ -31,9 +30,6 @@ namespace Svelto.ECS.Profiler
string maxTitle = "Max".PadRight(15, ' ');
string avgTitle = "Avg".PadRight(15, ' ');
- EnginesMonitor _enginesMonitor;
- Queue _engineMonitorData;
- const int SYSTEM_MONITOR_DATA_LENGTH = 300;
SORTING_OPTIONS _sortingOption = SORTING_OPTIONS.AVERAGE;
public override void OnInspectorGUI()
diff --git a/ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta b/ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta
index 489305b..11f6ff4 100644
--- a/ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta
+++ b/ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 3e961e5c8cc40064fa25092d835d1a80
+guid: de0de03babf2e9d4db95c2be94eb8c95
timeCreated: 1462527509
licenseType: Pro
MonoImporter:
diff --git a/ECS/SingleNodeEngine.cs b/ECS/SingleNodeEngine.cs
index f888ee2..6b43243 100644
--- a/ECS/SingleNodeEngine.cs
+++ b/ECS/SingleNodeEngine.cs
@@ -12,9 +12,7 @@
Remove(obj as TNodeType);
}
- protected virtual void Add(TNodeType node)
- {}
- protected virtual void Remove(TNodeType node)
- {}
+ protected abstract void Add(TNodeType node);
+ protected abstract void Remove(TNodeType node);
}
}
diff --git a/Utilities/WeakActionStruct.cs b/Utilities/WeakActionStruct.cs
index 8bb39b4..dff59f6 100644
--- a/Utilities/WeakActionStruct.cs
+++ b/Utilities/WeakActionStruct.cs
@@ -12,11 +12,16 @@ namespace BetterWeakEvents
public WeakAction(Action listener)
{
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
-
-#if !NETFX_CORE
- Method = listener.Method;
-#else
+#if NETFX_CORE
Method = listener.GetMethodInfo();
+ var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
+ if(attributes.Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
+#else
+ Method = listener.Method;
+
+ if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
#endif
}
@@ -51,10 +56,16 @@ namespace BetterWeakEvents
public WeakAction(Action listener)
{
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
-#if !NETFX_CORE
- Method = listener.Method;
-#else
+#if NETFX_CORE
Method = listener.GetMethodInfo();
+ var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
+ if(attributes.Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
+#else
+ Method = listener.Method;
+
+ if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
#endif
}
@@ -89,10 +100,16 @@ namespace BetterWeakEvents
public WeakAction(Action listener)
{
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak);
-#if !NETFX_CORE
- Method = listener.Method;
-#else
+#if NETFX_CORE
Method = listener.GetMethodInfo();
+ var attributes = (CompilerGeneratedAttribute[])Method.GetType().GetTypeInfo().GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
+ if(attributes.Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
+#else
+ Method = listener.Method;
+
+ if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0)
+ throw new ArgumentException("Cannot create weak event to anonymous method with closure.");
#endif
}