Browse Source

Merge pull request #7 from sebas77/alpha

Alpha
tags/Rel1
Sebastiano Mandalà GitHub 7 years ago
parent
commit
b624a6929f
89 changed files with 1294 additions and 1028 deletions
  1. +2
    -0
      .gitignore
  2. +0
    -9
      Context.meta
  3. +0
    -12
      Context/ContextNotifier.cs.meta
  4. +0
    -9
      Context/Factories.meta
  5. +0
    -12
      Context/Factories/GameObjectFactory.cs.meta
  6. +0
    -12
      Context/Factories/MonoBehaviourFactory.cs.meta
  7. +0
    -7
      Context/ICompositionRoot.cs.meta
  8. +0
    -8
      Context/IContextNotifer.cs.meta
  9. +0
    -8
      Context/IWaitForFrameworkDestruction.cs.meta
  10. +0
    -8
      Context/IWaitForFrameworkInitialization.cs.meta
  11. +0
    -7
      Context/UnityContext.cs.meta
  12. +0
    -9
      DataStructures.meta
  13. +1
    -1
      DataStructures/CircularBufferIndexer.cs
  14. +0
    -8
      DataStructures/CircularBufferIndexer.cs.meta
  15. +59
    -21
      DataStructures/FasterList.cs
  16. +0
    -12
      DataStructures/FasterList.cs.meta
  17. +0
    -12
      DataStructures/HashableWeakReference.cs.meta
  18. +142
    -0
      DataStructures/LockFreeQueue.cs
  19. +0
    -5
      DataStructures/Priority Queue.meta
  20. +1
    -1
      DataStructures/Priority Queue/HeapPriorityQueue.cs
  21. +0
    -8
      DataStructures/Priority Queue/HeapPriorityQueue.cs.meta
  22. +0
    -8
      DataStructures/Priority Queue/IPriorityQueue.cs.meta
  23. +0
    -8
      DataStructures/Priority Queue/PriorityQueueNode.cs.meta
  24. +0
    -12
      DataStructures/ReadOnlyDictionary.cs.meta
  25. +112
    -137
      DataStructures/ThreadSafeDictionary.cs
  26. +0
    -12
      DataStructures/ThreadSafeDictionary.cs.meta
  27. +0
    -8
      DataStructures/ThreadSafeQueue.cs.meta
  28. +0
    -12
      DataStructures/WeakReference.cs.meta
  29. +0
    -7
      ECS.meta
  30. +0
    -9
      ECS/Dispatcher.meta
  31. +0
    -8
      ECS/Dispatcher/DispatchOnChange.cs.meta
  32. +0
    -12
      ECS/Dispatcher/DispatcherOnSet.cs.meta
  33. +30
    -22
      ECS/EngineNodeDB.cs
  34. +0
    -12
      ECS/EngineNodeDB.cs.meta
  35. +350
    -142
      ECS/EnginesRoot.cs
  36. +0
    -8
      ECS/EnginesRoot.cs.meta
  37. +124
    -47
      ECS/EntityDescriptor.cs
  38. +0
    -12
      ECS/EntityDescriptor.cs.meta
  39. +41
    -0
      ECS/Extensions/Unity/UnitySumbmissionNodeScheduler.cs
  40. +132
    -18
      ECS/GenericEntityDescriptor.cs
  41. +0
    -12
      ECS/GenericEntityDescriptor.cs.meta
  42. +0
    -12
      ECS/GenericEntityDescriptorHolder.cs.meta
  43. +2
    -2
      ECS/ICallBackOnAddEngine.cs
  44. +0
    -12
      ECS/ICallBackOnAddEngine.cs.meta
  45. +48
    -7
      ECS/IEngine.cs
  46. +0
    -8
      ECS/IEngine.cs.meta
  47. +4
    -4
      ECS/IEngineNodeDB.cs
  48. +0
    -12
      ECS/IEngineNodeDB.cs.meta
  49. +5
    -1
      ECS/IEnginesRoot.cs
  50. +0
    -8
      ECS/IEnginesRoot.cs.meta
  51. +0
    -12
      ECS/IEntityDescriptorHolder.cs.meta
  52. +16
    -1
      ECS/INode.cs
  53. +0
    -8
      ECS/INode.cs.meta
  54. +10
    -0
      ECS/IRemoveEntityComponent.cs
  55. +0
    -12
      ECS/IRemoveEntityComponent.cs.meta
  56. +47
    -0
      ECS/MultiNodesEngine.cs
  57. +9
    -0
      ECS/NodeSubmissionScheduler.cs
  58. +0
    -9
      ECS/Profiler.meta
  59. +0
    -9
      ECS/Profiler/Editor.meta
  60. +0
    -9
      ECS/Profiler/Editor/EngineProfiler.meta
  61. +0
    -12
      ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs.meta
  62. +1
    -1
      ECS/Profiler/Editor/EngineProfiler/EngineProfilerMenuItem.cs
  63. +0
    -12
      ECS/Profiler/Editor/EngineProfiler/EngineProfilerMenuItem.cs.meta
  64. +0
    -12
      ECS/Profiler/Editor/EngineProfiler/EnginesMonitor.cs.meta
  65. +0
    -12
      ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta
  66. +0
    -12
      ECS/Profiler/EngineInfo.cs.meta
  67. +3
    -2
      ECS/Profiler/EngineProfiler.cs
  68. +0
    -12
      ECS/Profiler/EngineProfiler.cs.meta
  69. +1
    -1
      ECS/Profiler/EngineProfilerBehaviour.cs
  70. +0
    -12
      ECS/Profiler/EngineProfilerBehaviour.cs.meta
  71. +0
    -12
      ECS/Sequencer.cs.meta
  72. +9
    -6
      ECS/SingleNodeEngine.cs
  73. +0
    -12
      ECS/SingleNodeEngine.cs.meta
  74. +134
    -0
      ECS/StructNodes.cs
  75. +0
    -4
      ECS/note.txt.meta
  76. +0
    -9
      Factories.meta
  77. +0
    -8
      Factories/IGameObjectFactory.cs.meta
  78. +0
    -8
      Factories/IMonoBehaviourFactory.cs.meta
  79. +0
    -8
      LICENSE.meta
  80. +0
    -8
      README.md.meta
  81. +0
    -9
      Utilities.meta
  82. +3
    -3
      Utilities/DesignByContract.cs
  83. +0
    -10
      Utilities/DesignByContract.cs.meta
  84. +3
    -6
      Utilities/Print.cs
  85. +0
    -8
      Utilities/Print.cs.meta
  86. +1
    -1
      Utilities/WeakActionStruct.cs
  87. +0
    -12
      Utilities/WeakActionStruct.cs.meta
  88. +4
    -3
      Utilities/WeakEvent.cs
  89. +0
    -12
      Utilities/WeakEvent.cs.meta

+ 2
- 0
.gitignore View File

@@ -1,2 +1,4 @@
/EntitySystem/note.txt
/EntitySystem/note.txt.meta
/*.meta
*.meta

+ 0
- 9
Context.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 9e37272d8aa8b6e4cb7b1fc15f1e57a8
folderAsset: yes
timeCreated: 1431201025
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
Context/ContextNotifier.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: d74bed1689bb4114aa8a1f95cd95c788
timeCreated: 1431300049
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
Context/Factories.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: ec4bd87e898bf7c42823fb5ec2456b43
folderAsset: yes
timeCreated: 1431630831
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
Context/Factories/GameObjectFactory.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 613a705e128b35e4f9361e29f4661191
timeCreated: 1431630831
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
Context/Factories/MonoBehaviourFactory.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 369e3378b91069c4aadba2af5aa8882b
timeCreated: 1431630831
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 7
Context/ICompositionRoot.cs.meta View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 48c80cc65bea8254ba8082043f53405e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

+ 0
- 8
Context/IContextNotifer.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a28c8df5741efe54ea588a1bcea92f0f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
Context/IWaitForFrameworkDestruction.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 36b1da25aaa515e4bad98fa0f61bc662
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
Context/IWaitForFrameworkInitialization.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 93cf465dd97f6144390620250c362485
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 7
Context/UnityContext.cs.meta View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 54e46daa2d2d723499a114d6d8de9dc2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

+ 0
- 9
DataStructures.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 6663fc83070cb0842b4665b38356feb2
folderAsset: yes
timeCreated: 1463348260
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 1
- 1
DataStructures/CircularBufferIndexer.cs View File

@@ -9,7 +9,7 @@ namespace Svelto.DataStructures
// isn't taken into account (we would have to do a shift in both arrays)
// Could be added as an option?

class CircularBufferIndexer<TKey, TVal> : IDictionary<TKey, TVal>
public class CircularBufferIndexer<TKey, TVal> : IDictionary<TKey, TVal>
{
public ICollection<TKey> Keys
{


+ 0
- 8
DataStructures/CircularBufferIndexer.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 0d87fb4479e8365499c162fe0fc94acc
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 59
- 21
DataStructures/FasterList.cs View File

@@ -121,6 +121,8 @@ namespace Svelto.DataStructures

public struct FasterReadOnlyList<T> : IList<T>
{
public static FasterReadOnlyList<T> DefaultList = new FasterReadOnlyList<T>(new FasterList<T>());

public int Count { get { return _list.Count; } }
public bool IsReadOnly { get { return true; } }

@@ -193,7 +195,8 @@ namespace Svelto.DataStructures
{
public FasterListThreadSafe(FasterList<T> list)
{
_list = list;
if (list == null) throw new ArgumentException("invalid list");
_list = list;
_lockQ = new ReaderWriterLockSlim();
}

@@ -273,6 +276,19 @@ namespace Svelto.DataStructures
}
}

public void FastClear()
{
_lockQ.EnterWriteLock();
try
{
_list.FastClear();
}
finally
{
_lockQ.ExitWriteLock();
}
}

public bool Contains(T item)
{
_lockQ.EnterReadLock();
@@ -288,14 +304,14 @@ namespace Svelto.DataStructures

public void CopyTo(T[] array, int arrayIndex)
{
_lockQ.EnterWriteLock();
_lockQ.EnterReadLock();
try
{
_list.CopyTo(array, arrayIndex);
}
finally
{
_lockQ.ExitWriteLock();
_lockQ.ExitReadLock();
}
}

@@ -351,6 +367,19 @@ namespace Svelto.DataStructures
}
}

public void UnorderedRemoveAt(int index)
{
_lockQ.EnterWriteLock();
try
{
_list.UnorderedRemoveAt(index);
}
finally
{
_lockQ.ExitWriteLock();
}
}

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
throw new NotImplementedException();
@@ -368,7 +397,7 @@ namespace Svelto.DataStructures

public struct FasterReadOnlyListCast<T, U> : IList<U> where U:T
{
public static FasterList<T> DefaultList = new FasterList<T>();
public static FasterReadOnlyListCast<T, U> DefaultList = new FasterReadOnlyListCast<T, U>(new FasterList<T>());

public int Count { get { return _list.Count; } }
public bool IsReadOnly { get { return true; } }
@@ -402,7 +431,7 @@ namespace Svelto.DataStructures

public void CopyTo(U[] array, int arrayIndex)
{
throw new NotImplementedException();
Array.Copy(_list.ToArrayFast(), 0, array, arrayIndex, _list.Count);
}

public bool Remove(U item)
@@ -438,7 +467,10 @@ namespace Svelto.DataStructures
readonly FasterList<T> _list;
}

public class FasterList<T> : IList<T>
public interface IFasterList
{}

public class FasterList<T> : IList<T>, IFasterList
{
const int MIN_SIZE = 4;

@@ -513,7 +545,7 @@ namespace Svelto.DataStructures
for (int i = 0; i < initialSize; i++)
list.Add(new U());

list.Clear();
list._count = 0;

return list;
}
@@ -553,6 +585,11 @@ namespace Svelto.DataStructures
_count += count;
}

public void AddRange(T[] items)
{
AddRange(items, items.Length);
}

public FasterReadOnlyList<T> AsReadOnly()
{
return new FasterReadOnlyList<T>(this);
@@ -562,12 +599,12 @@ namespace Svelto.DataStructures
/// Careful, you could keep on holding references you don't want to hold to anymore
/// Use DeepClear in case.
/// </summary>
public void Clear()
public void FastClear()
{
_count = 0;
}

public void DeepClear()
public void Clear()
{
Array.Clear(_buffer, 0, _buffer.Length);

@@ -689,32 +726,32 @@ namespace Svelto.DataStructures
return _buffer;
}

public bool UnorderredRemove(T item)
public bool UnorderedRemove(T item)
{
var index = IndexOf(item);

if (index == -1)
return false;

UnorderredRemoveAt(index);
UnorderedRemoveAt(index);

return true;
}

public T UnorderredRemoveAt(int index)
public bool UnorderedRemoveAt(int index)
{
DesignByContract.Check.Require(index < _count && _count > 0, "out of bound index");

T item = _buffer[index];

if (index == --_count)
return item;
{
_buffer[_count] = default(T);
return false;
}

T swap = _buffer[index];
_buffer[index] = _buffer[_count];
_buffer[_count] = swap;
_buffer[_count] = default(T);

return item;
return true;
}

IEnumerator IEnumerable.GetEnumerator()
@@ -752,14 +789,15 @@ namespace Svelto.DataStructures
Resize(_count);
}

public bool Reuse(int index, out T result)
public bool Reuse<U>(int index, out U result)
where U:class, T
{
result = default(T);
result = default(U);

if (index >= _buffer.Length)
return false;

result = _buffer[index];
result = (U)_buffer[index];

return result != null;
}


+ 0
- 12
DataStructures/FasterList.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: d19e59cbec974dd4d821a7dd21f87a88
timeCreated: 1472488070
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
DataStructures/HashableWeakReference.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 0cfa789b3147c2e4e80d067693a58103
timeCreated: 1455809369
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 142
- 0
DataStructures/LockFreeQueue.cs View File

@@ -0,0 +1,142 @@
using System.Collections.Generic;
using System.Threading;

//from unify wiki
namespace Svelto.DataStructures
{
public class SingleLinkNode<T>
{
// Note; the Next member cannot be a property since
// it participates in many CAS operations
public SingleLinkNode<T> Next;
public T Item;
}

public static class SyncMethods
{
public static bool CAS<T>(ref T location, T comparand, T newValue) where T : class
{
return
(object)comparand ==
(object)Interlocked.CompareExchange<T>(ref location, newValue, comparand);
}
}

public class LockFreeLinkPool<T>
{
private SingleLinkNode<T> head;

public LockFreeLinkPool()
{
head = new SingleLinkNode<T>();
}

public void Push(SingleLinkNode<T> newNode)
{
newNode.Item = default(T);
do
{
newNode.Next = head.Next;
} while (!SyncMethods.CAS<SingleLinkNode<T>>(ref head.Next, newNode.Next, newNode));
return;
}

public bool Pop(out SingleLinkNode<T> node)
{
do
{
node = head.Next;
if (node == null)
{
return false;
}
} while (!SyncMethods.CAS<SingleLinkNode<T>>(ref head.Next, node, node.Next));
return true;
}
}

public class LockFreeQueue<T>
{

SingleLinkNode<T> head;
SingleLinkNode<T> tail;
LockFreeLinkPool<T> trash;

public LockFreeQueue()
{
head = new SingleLinkNode<T>();
tail = head;
trash = new LockFreeLinkPool<T>();
}

public void Enqueue(T item)
{
SingleLinkNode<T> oldTail = null;
SingleLinkNode<T> oldTailNext;

SingleLinkNode<T> newNode;
if (!trash.Pop(out newNode))
{
newNode = new SingleLinkNode<T>();
}
else
{
newNode.Next = null;
}
newNode.Item = item;

bool newNodeWasAdded = false;
while (!newNodeWasAdded)
{
oldTail = tail;
oldTailNext = oldTail.Next;

if (tail == oldTail)
{
if (oldTailNext == null)
newNodeWasAdded = SyncMethods.CAS<SingleLinkNode<T>>(ref tail.Next, null, newNode);
else
SyncMethods.CAS<SingleLinkNode<T>>(ref tail, oldTail, oldTailNext);
}
}
SyncMethods.CAS<SingleLinkNode<T>>(ref tail, oldTail, newNode);
}

public bool Dequeue(out T item)
{
item = default(T);
SingleLinkNode<T> oldHead = null;

bool haveAdvancedHead = false;
while (!haveAdvancedHead)
{

oldHead = head;
SingleLinkNode<T> oldTail = tail;
SingleLinkNode<T> oldHeadNext = oldHead.Next;

if (oldHead == head)
{
if (oldHead == oldTail)
{
if (oldHeadNext == null)
{
return false;
}
SyncMethods.CAS<SingleLinkNode<T>>(ref tail, oldTail, oldHeadNext);
}
else
{
item = oldHeadNext.Item;
haveAdvancedHead = SyncMethods.CAS<SingleLinkNode<T>>(ref head, oldHead, oldHeadNext);
if (haveAdvancedHead)
{
trash.Push(oldHead);
}
}
}
}
return true;
}
}
}

+ 0
- 5
DataStructures/Priority Queue.meta View File

@@ -1,5 +0,0 @@
fileFormatVersion: 2
guid: 8fffa27a4e8919a4db6fe1369e22e1b5
folderAsset: yes
DefaultImporter:
userData:

+ 1
- 1
DataStructures/Priority Queue/HeapPriorityQueue.cs View File

@@ -66,7 +66,7 @@ namespace Svelto.DataStructures
#endif
public void Clear()
{
_nodes.Clear();
_nodes.FastClear();

_numNodes = 0;
}


+ 0
- 8
DataStructures/Priority Queue/HeapPriorityQueue.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ac754b29409379046935c0890bab6dc5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
DataStructures/Priority Queue/IPriorityQueue.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 5d399e4c2c1fe1f47833d6b70bf16184
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
DataStructures/Priority Queue/PriorityQueueNode.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 2a6cc02a61a6ff549b1dcac74c71681f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 12
DataStructures/ReadOnlyDictionary.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: e13aaf89d27048246bcf0d30c0993cf3
timeCreated: 1459332966
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 112
- 137
DataStructures/ThreadSafeDictionary.cs View File

@@ -3,8 +3,6 @@ using System;
using System.Collections.Generic;
using System.Threading;

//note, rewrite like ThreadSafeQueue

namespace Svelto.DataStructures
{
/// <summary>
@@ -31,10 +29,15 @@ namespace Svelto.DataStructures
{
get
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict.Count;
}
finally
{
LockQ.ExitReadLock();
}
}
}

@@ -42,10 +45,15 @@ namespace Svelto.DataStructures
{
get
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict.IsReadOnly;
}
finally
{
LockQ.ExitReadLock();
}
}
}

@@ -53,10 +61,15 @@ namespace Svelto.DataStructures
{
get
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return new FasterList<TKey>(dict.Keys);
}
finally
{
LockQ.ExitReadLock();
}
}
}

@@ -64,10 +77,15 @@ namespace Svelto.DataStructures
{
get
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return new FasterList<TValue>(dict.Values);
}
finally
{
LockQ.ExitReadLock();
}
}
}

@@ -75,91 +93,146 @@ namespace Svelto.DataStructures
{
get
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict[key];
}
finally
{
LockQ.ExitReadLock();
}
}

set
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
dict[key] = value;
}
finally
{
LockQ.ExitWriteLock();
}
}
}

public virtual void Add(KeyValuePair<TKey, TValue> item)
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
dict.Add(item);
}
finally
{
LockQ.ExitWriteLock();
}
}

public virtual void Clear()
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
dict.Clear();
}
finally
{
LockQ.ExitWriteLock();
}
}

public virtual bool Contains(KeyValuePair<TKey, TValue> item)
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict.Contains(item);
}
finally
{
LockQ.ExitReadLock();
}
}

public virtual void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
dict.CopyTo(array, arrayIndex);
}
finally
{
LockQ.ExitReadLock();
}
}

public virtual bool Remove(KeyValuePair<TKey, TValue> item)
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
return dict.Remove(item);
}
finally
{
LockQ.ExitWriteLock();
}
}

public virtual void Add(TKey key, TValue value)
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
dict.Add(key, value);
}
finally
{
LockQ.ExitWriteLock();
}
}

public virtual bool ContainsKey(TKey key)
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict.ContainsKey(key);
}
finally
{
LockQ.ExitReadLock();
}
}

public virtual bool Remove(TKey key)
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
return dict.Remove(key);
}
finally
{
LockQ.ExitWriteLock();
}
}

public virtual bool TryGetValue(TKey key, out TValue value)
{
using (new ReadOnlyLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
return dict.TryGetValue(key, out value);
}
finally
{
LockQ.ExitReadLock();
}
}

/// <summary>
@@ -169,7 +242,8 @@ namespace Svelto.DataStructures
/// <param name = "newValue">New Value</param>
public void MergeSafe(TKey key, TValue newValue)
{
using (new WriteLock(dictionaryLock))
LockQ.EnterWriteLock();
try
{
// take a writelock immediately since we will always be writing
if (dict.ContainsKey(key))
@@ -177,6 +251,10 @@ namespace Svelto.DataStructures

dict.Add(key, newValue);
}
finally
{
LockQ.ExitWriteLock();
}
}

/// <summary>
@@ -185,132 +263,29 @@ namespace Svelto.DataStructures
/// <param name = "key">Key to remove</param>
public void RemoveSafe(TKey key)
{
using (new ReadLock(dictionaryLock))
LockQ.EnterReadLock();
try
{
if (dict.ContainsKey(key))
using (new WriteLock(dictionaryLock))
{
dict.Remove(key);
}
LockQ.EnterWriteLock();
try
{
dict.Remove(key);
}
finally
{
LockQ.ExitWriteLock();
}
}
finally
{
LockQ.ExitReadLock();
}
}

// This is the internal dictionary that we are wrapping
readonly IDictionary<TKey, TValue> dict;

[NonSerialized] readonly ReaderWriterLockSlim dictionaryLock = Locks.GetLockInstance(LockRecursionPolicy.NoRecursion);
}

public static class Locks
{
public static ReaderWriterLockSlim GetLockInstance()
{
return GetLockInstance(LockRecursionPolicy.SupportsRecursion);
}

public static ReaderWriterLockSlim GetLockInstance(LockRecursionPolicy recursionPolicy)
{
return new ReaderWriterLockSlim(recursionPolicy);
}

public static void GetReadLock(ReaderWriterLockSlim locks)
{
var lockAcquired = false;
while (!lockAcquired)
lockAcquired = locks.TryEnterUpgradeableReadLock(1);
}

public static void GetReadOnlyLock(ReaderWriterLockSlim locks)
{
var lockAcquired = false;
while (!lockAcquired)
lockAcquired = locks.TryEnterReadLock(1);
}

public static void GetWriteLock(ReaderWriterLockSlim locks)
{
var lockAcquired = false;
while (!lockAcquired)
lockAcquired = locks.TryEnterWriteLock(1);
}

public static void ReleaseLock(ReaderWriterLockSlim locks)
{
ReleaseWriteLock(locks);
ReleaseReadLock(locks);
ReleaseReadOnlyLock(locks);
}

public static void ReleaseReadLock(ReaderWriterLockSlim locks)
{
if (locks.IsUpgradeableReadLockHeld)
locks.ExitUpgradeableReadLock();
}

public static void ReleaseReadOnlyLock(ReaderWriterLockSlim locks)
{
if (locks.IsReadLockHeld)
locks.ExitReadLock();
}

public static void ReleaseWriteLock(ReaderWriterLockSlim locks)
{
if (locks.IsWriteLockHeld)
locks.ExitWriteLock();
}
}

public abstract class BaseLock : IDisposable
{
protected ReaderWriterLockSlim _Locks;

public BaseLock(ReaderWriterLockSlim locks)
{
_Locks = locks;
}

public abstract void Dispose();
}

public class ReadLock : BaseLock
{
public ReadLock(ReaderWriterLockSlim locks)
: base(locks)
{
Locks.GetReadLock(_Locks);
}

public override void Dispose()
{
Locks.ReleaseReadLock(_Locks);
}
}

public class ReadOnlyLock : BaseLock
{
public ReadOnlyLock(ReaderWriterLockSlim locks)
: base(locks)
{
Locks.GetReadOnlyLock(_Locks);
}

public override void Dispose()
{
Locks.ReleaseReadOnlyLock(_Locks);
}
}

public class WriteLock : BaseLock
{
public WriteLock(ReaderWriterLockSlim locks)
: base(locks)
{
Locks.GetWriteLock(_Locks);
}

public override void Dispose()
{
Locks.ReleaseWriteLock(_Locks);
}
readonly ReaderWriterLockSlim LockQ = new ReaderWriterLockSlim();
}
}

+ 0
- 12
DataStructures/ThreadSafeDictionary.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: db7c720ce4e437f48b1380223ba08192
timeCreated: 1470829214
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 8
DataStructures/ThreadSafeQueue.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 57d029cda5232f8468d50d4eb3bf5489
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 12
DataStructures/WeakReference.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 205cba76ee94d0e47aba9510ca92c540
timeCreated: 1452175408
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 7
ECS.meta View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 5015ea56c030d6542bd4daa46f59e549
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
ECS/Dispatcher.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 2eae335fd33e33c4f951bf28bbf4914f
folderAsset: yes
timeCreated: 1462445195
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 8
ECS/Dispatcher/DispatchOnChange.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 908688d3b784d644e88a06e20f9ea159
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 12
ECS/Dispatcher/DispatcherOnSet.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: cbb1d54b291794b4686526222ee2bbb6
timeCreated: 1471250507
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 30
- 22
ECS/EngineNodeDB.cs View File

@@ -4,15 +4,15 @@ using Svelto.DataStructures;

namespace Svelto.ECS
{
class EngineNodeDB : IEngineNodeDB
public class EngineNodeDB : IEngineNodeDB
{
internal EngineNodeDB( Dictionary<Type, FasterList<INode>> nodesDB,
Dictionary<Type, Dictionary<int, INode>> nodesDBdic,
Dictionary<Type, FasterList<INode>> nodesDBgroups)
Dictionary<Type, FasterList<INode>> metaNodesDB)
{
_nodesDB = nodesDB;
_nodesDBdic = nodesDBdic;
_nodesDBgroups = nodesDBgroups;
_metaNodesDB = metaNodesDB;
}

public FasterReadOnlyListCast<INode, T> QueryNodes<T>() where T:INode
@@ -35,33 +35,34 @@ namespace Svelto.ECS
return new ReadOnlyDictionary<int, INode>(_nodesDBdic[type]);
}

public T QueryNodeFromGroup<T>(int groupID) where T : INode
public T QueryMetaNode<T>(int metaEntityID) where T : INode
{
return QueryNode<T>(groupID);
return QueryNode<T>(metaEntityID);
}

public bool QueryNodeFromGroup<T>(int groupID, out T node) where T : INode
public bool TryQueryMetaNode<T>(int metaEntityID, out T node) where T : INode
{
return QueryNode<T>(groupID, out node);
return TryQueryNode(metaEntityID, out node);
}

public FasterReadOnlyListCast<INode, T> QueryNodesFromGroups<T>() where T : INode
public FasterReadOnlyListCast<INode, T> QueryMetaNodes<T>() where T : INode
{
var type = typeof(T);

if (_nodesDBgroups.ContainsKey(type) == false)
if (_metaNodesDB.ContainsKey(type) == false)
return RetrieveEmptyNodeList<T>();

return new FasterReadOnlyListCast<INode, T>(_nodesDBgroups[type]);
return new FasterReadOnlyListCast<INode, T>(_metaNodesDB[type]);
}

public bool QueryNode<T>(int ID, out T node) where T:INode
public bool TryQueryNode<T>(int ID, out T node) where T:INode
{
var type = typeof(T);

INode internalNode;

if (_nodesDBdic.ContainsKey(type) && _nodesDBdic[type].TryGetValue(ID, out internalNode))
if (_nodesDBdic.ContainsKey(type) &&
_nodesDBdic[type].TryGetValue(ID, out internalNode))
{
node = (T)internalNode;

@@ -79,25 +80,32 @@ namespace Svelto.ECS

INode internalNode;

if (_nodesDBdic.ContainsKey(type) && _nodesDBdic[type].TryGetValue(ID, out internalNode))
if (_nodesDBdic.ContainsKey(type) &&
_nodesDBdic[type].TryGetValue(ID, out internalNode))
return (T)internalNode;

throw new Exception("Node Not Found");
}

static FasterReadOnlyListCast<INode, T> RetrieveEmptyNodeList<T>() where T : INode
public FasterReadOnlyListCast<INode, T> QueryGroupNodes<T>(int groupID) where T : INode
{
return new FasterReadOnlyListCast<INode, T>(FasterReadOnlyListCast<INode, T>.DefaultList);
var type = typeof(T);

if (_nodesDB.ContainsKey(type) == false)
return RetrieveEmptyNodeList<T>();

return new FasterReadOnlyListCast<INode, T>(_nodesDB[type]);
}

Dictionary<Type, FasterList<INode>> _nodesDB;
Dictionary<Type, Dictionary<int, INode>> _nodesDBdic;
Dictionary<Type, FasterList<INode>> _nodesDBgroups;
static FasterReadOnlyListCast<INode, T> RetrieveEmptyNodeList<T>() where T : INode
{
return FasterReadOnlyListCast<INode, T>.DefaultList;
}

//Dictionary<Type, ThreadSafeFasterList<INode>> _nodesDB;
//Dictionary<Type, ThreadsSafeDictionary<int, INode>> _nodesDBdic;
// Dictionary<Type, ThreadSafeFasterList<INode>> _nodesDBgroups;
readonly Dictionary<Type, FasterList<INode>> _nodesDB;
readonly Dictionary<Type, Dictionary<int, INode>> _nodesDBdic;
readonly Dictionary<Type, FasterList<INode>> _metaNodesDB;

ReadOnlyDictionary<int, INode> _defaultEmptyNodeDict = new ReadOnlyDictionary<int, INode>(new Dictionary<int, INode>());
readonly ReadOnlyDictionary<int, INode> _defaultEmptyNodeDict = new ReadOnlyDictionary<int, INode>(new Dictionary<int, INode>());
}
}

+ 0
- 12
ECS/EngineNodeDB.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: b8aebbeeaf3d65d438359008c1f5d351
timeCreated: 1459422025
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 350
- 142
ECS/EnginesRoot.cs View File

@@ -2,6 +2,8 @@ using System;
using System.Collections;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
using Svelto.ECS.NodeSchedulers;
using UnityEngine;
using WeakReference = Svelto.DataStructures.WeakReference<Svelto.ECS.EnginesRoot>;

@@ -14,40 +16,39 @@ using System.Reflection;

namespace Svelto.ECS
{
class Scheduler : MonoBehaviour
{
IEnumerator Start()
{
while (true)
{
yield return new WaitForEndOfFrame();

OnTick();
}
}

internal Action OnTick;
}

public sealed class EnginesRoot : IEnginesRoot, IEntityFactory
{
public EnginesRoot()
public EnginesRoot(NodeSubmissionScheduler nodeScheduler)
{
_nodeEngines = new Dictionary<Type, FasterList<INodeEngine<INode>>>();
_nodeEngines = new Dictionary<Type, FasterList<IEngine>>();
_activableEngines = new Dictionary<Type, FasterList<IEngine>>();
_otherEngines = new FasterList<IEngine>();

_engineRootWeakReference = new WeakReference(this);
_otherEnginesReferences = new FasterList<IEngine>();

_nodesDB = new Dictionary<Type, FasterList<INode>>();
_nodesDBdic = new Dictionary<Type, Dictionary<int, INode>>();

_nodesToAdd = new FasterList<INode>();
_groupNodesToAdd = new FasterList<INode>();
_metaNodesToAdd = new FasterList<INode>();

_metaNodesDB = new Dictionary<Type, FasterList<INode>>();
_sharedStructNodeLists = new SharedStructNodeLists();
_sharedGroupedStructNodeLists = new SharedGroupedStructNodesLists();

_nodesDBgroups = new Dictionary<Type, FasterList<INode>>();
_internalRemove = InternalRemove;
_internalDisable = InternalDisable;
_internalEnable = InternalEnable;
_internalMetaRemove = InternalMetaRemove;

GameObject go = new GameObject("ECSScheduler");
_scheduler = nodeScheduler;
_scheduler.Schedule(SubmitNodes);

go.AddComponent<Scheduler>().OnTick += SubmitNodes;
_structNodeEngineType = typeof(IStructNodeEngine<>);
_groupedStructNodesEngineType = typeof(IGroupedStructNodesEngine<>);
_activableNodeEngineType = typeof(IActivableNodeEngine<>);
_implementedInterfaceTypes = new Dictionary<Type, Type[]>();

#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
GameObject debugEngineObject = new GameObject("Engine Debugger");
@@ -57,56 +58,75 @@ namespace Svelto.ECS

void SubmitNodes()
{
int groupNodesCount;
int nodesCount;
int metaNodesCount = _metaNodesToAdd.Count;
int nodesCount = _nodesToAdd.Count;

if (metaNodesCount + nodesCount == 0) return;

bool newNodesHaveBeenAddedWhileIterating;
int startNodes = 0;
int startGroupNodes = 0;
int startMetaNodes = 0;
int numberOfReenteringLoops = 0;

do
{
groupNodesCount = _groupNodesToAdd.Count;
nodesCount = _nodesToAdd.Count;
var nodesToAdd = _nodesToAdd.ToArrayFast();

for (int i = startNodes; i < nodesCount; i++)
{
var node = _nodesToAdd[i];
AddNodeToTheDB(node, node.GetType());
var node = nodesToAdd[i];
var nodeType = node.GetType();

AddNodeToTheDB(node, nodeType);
var nodeWithId = node as INodeWithID;
if (nodeWithId != null)
AddNodeToNodesDictionary(nodeWithId, nodeType);
}

for (int i = startGroupNodes; i < groupNodesCount; i++)
var metaNodesToAdd = _metaNodesToAdd.ToArrayFast();

for (int i = startMetaNodes; i < metaNodesCount; i++)
{
var node = _groupNodesToAdd[i];
AddNodeToGroupDB(node, node.GetType());
var node = metaNodesToAdd[i];
var nodeType = node.GetType();

AddNodeToMetaDB(node, nodeType);
var nodeWithId = node as INodeWithID;
if (nodeWithId != null)
AddNodeToNodesDictionary(nodeWithId, nodeType);
}

for (int i = startNodes; i < nodesCount; i++)
{
var node = _nodesToAdd[i];
var node = nodesToAdd[i];
AddNodeToTheSuitableEngines(node, node.GetType());
}

for (int i = startGroupNodes; i < groupNodesCount; i++)
for (int i = startMetaNodes; i < metaNodesCount; i++)
{
var node = _groupNodesToAdd[i];
var node = metaNodesToAdd[i];
AddNodeToTheSuitableEngines(node, node.GetType());
}

newNodesHaveBeenAddedWhileIterating = _groupNodesToAdd.Count > groupNodesCount || _nodesToAdd.Count > nodesCount;
newNodesHaveBeenAddedWhileIterating =
_metaNodesToAdd.Count > metaNodesCount ||
_nodesToAdd.Count > nodesCount;

startNodes = nodesCount;
startGroupNodes = groupNodesCount;
startMetaNodes = metaNodesCount;

if (numberOfReenteringLoops > 5)
throw new Exception("possible infinite loop found creating Entities inside INodesEngine Add method, please consider building entities outside INodesEngine Add method");

numberOfReenteringLoops++;
numberOfReenteringLoops++;

metaNodesCount = _metaNodesToAdd.Count;
nodesCount = _nodesToAdd.Count;

} while (newNodesHaveBeenAddedWhileIterating);

_nodesToAdd.Clear();
_groupNodesToAdd.Clear();
_metaNodesToAdd.Clear();
}

public void AddEngine(IEngine engine)
@@ -114,88 +134,201 @@ namespace Svelto.ECS
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
EngineProfiler.AddEngine(engine);
#endif
if (engine is IQueryableNodeEngine)
(engine as IQueryableNodeEngine).nodesDB = new EngineNodeDB(_nodesDB, _nodesDBdic, _nodesDBgroups);
var queryableNodeEngine = engine as IQueryableNodeEngine;
if (queryableNodeEngine != null)
queryableNodeEngine.nodesDB =
new EngineNodeDB(_nodesDB, _nodesDBdic, _metaNodesDB);

var engineType = engine.GetType();
var implementedInterfaces = engineType.GetInterfaces();

CollectImplementedInterfaces(implementedInterfaces);

var engineAdded = CheckGenericEngines(engine);

if (CheckLegacyNodesEngine(engine, ref engineAdded) == false)
CheckNodesEngine(engine, engineType, ref engineAdded);

if (engineAdded == false)
_otherEngines.Add(engine);

var callBackOnAddEngine = engine as ICallBackOnAddEngine;
if (callBackOnAddEngine != null)
callBackOnAddEngine.Ready();
}

if (engine is INodesEngine)
void CollectImplementedInterfaces(Type[] implementedInterfaces)
{
_implementedInterfaceTypes.Clear();

for (int index = 0; index < implementedInterfaces.Length; index++)
{
var nodesEngine = engine as INodesEngine;
var interfaceType = implementedInterfaces[index];
#if !NETFX_CORE

AddEngine(nodesEngine, nodesEngine.AcceptedNodes(), _nodeEngines);
if (false == interfaceType.IsGenericType)
#else
if (false == interfaceType.IsConstructedGenericType)
#endif
{
continue;
}

var genericTypeDefinition = interfaceType.GetGenericTypeDefinition();

_implementedInterfaceTypes.Add(genericTypeDefinition,
interfaceType.GetGenericArguments());
}
}

bool CheckGenericEngines(IEngine engine)
{
if (_implementedInterfaceTypes.Count == 0) return false;

bool engineAdded = false;

if (_implementedInterfaceTypes.ContainsKey(_structNodeEngineType))
{
((IStructNodeEngine)engine).CreateStructNodes
(_sharedStructNodeLists);
}
else

if (_implementedInterfaceTypes.ContainsKey(_groupedStructNodesEngineType))
{
((IGroupedStructNodesEngine)engine).CreateStructNodes
(_sharedGroupedStructNodeLists);
}

var engineType = engine.GetType();
// Type baseInterface = null;
Type[] arguments;
if (_implementedInterfaceTypes.TryGetValue(_activableNodeEngineType,
out arguments))
{
AddEngine(engine, arguments, _activableEngines);

#if !NETFX_CORE
var baseType = engineType.BaseType;
engineAdded = true;
}

if (baseType.IsGenericType
return engineAdded;
}

bool CheckLegacyNodesEngine(IEngine engine, ref bool engineAdded)
{
var nodesEngine = engine as INodesEngine;
if (nodesEngine != null)
{
AddEngine(nodesEngine, nodesEngine.AcceptedNodes(), _nodeEngines);

engineAdded = true;

return true;
}

return false;
}

bool CheckNodesEngine(IEngine engine, Type engineType, ref bool engineAdded)
{
#if !NETFX_CORE
var baseType = engineType.BaseType;
if (baseType.IsGenericType
#else
var baseType = engineType.GetTypeInfo().BaseType;

if (baseType.IsConstructedGenericType
#endif
&& baseType.GetGenericTypeDefinition() == typeof (SingleNodeEngine<>))
{
AddEngine(engine as INodeEngine<INode>, baseType.GetGenericArguments(), _nodeEngines);
}
else
_otherEnginesReferences.Add(engine);
&& engine is INodeEngine)
{
AddEngine(engine as INodeEngine, baseType.GetGenericArguments(), _nodeEngines);

engineAdded = true;

return true;
}
if (engine is ICallBackOnAddEngine)
(engine as ICallBackOnAddEngine).Ready();

return false;
}

public void BuildEntity(int ID, EntityDescriptor ed)
{
var entityNodes = ed.BuildNodes(ID, (node) =>
{
if (_engineRootWeakReference.IsValid == true)
InternalRemove(node);
});
var entityNodes = ed.BuildNodes(ID,
_internalRemove,
_internalEnable,
_internalDisable
);
_nodesToAdd.AddRange(entityNodes);
}

/// <summary>
/// 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
/// A meta entity is a way to manage a set of entitites that are not easily
/// queriable otherwise. For example you may want to group existing entities
/// by size and type and then use the meta entity node to manage the data
/// shared among the single entities of the same type and size. This will
/// 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 entities are 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.
/// The shared node of the meta entity is then used by engines that are meant
/// to manage a group of entities through a single node.
/// The same engine can manage several meta entities nodes too.
/// The Engine manages the logic of the Meta Node data and other engines
/// can read back this data through the normal entity as the shared node
/// will be present in their descriptor too.
/// </summary>
/// <param name="metaEntityID"></param>
/// <param name="ed"></param>
public void BuildMetaEntity(int metaEntityID, EntityDescriptor ed)
{
var entityNodes = ed.BuildNodes(metaEntityID,
_internalMetaRemove,
_internalEnable,
_internalDisable
);

_metaNodesToAdd.AddRange(entityNodes);
}

/// <summary>
/// Using this function is like building a normal entity, but the nodes
/// are grouped by groupID to be better processed inside engines and
/// improve cache locality. Only IGroupStructNodeWithID nodes are grouped
/// other nodes are managed as usual.
/// </summary>
/// <param name="entityID"></param>
/// <param name="groupID"></param>
/// <param name="ed"></param>
public void BuildEntityGroup(int groupID, EntityDescriptor ed)
public void BuildEntityInGroup(short entityID, short groupID,
EntityDescriptor ed)
{
var entityNodes = ed.BuildNodes(groupID, (node) =>
{
if (_engineRootWeakReference.IsValid == true)
InternalGroupRemove(node);
});
var entityNodes = ed.BuildNodes(entityID,
_internalRemove,
_internalEnable,
_internalDisable
);

_groupNodesToAdd.AddRange(entityNodes);
_nodesToAdd.AddRange(entityNodes);

for (int i = 0; i < entityNodes.Count; i++)
{
var groupNode = entityNodes[i] as IGroupedStructNodeWithID;
if (groupNode != null)
groupNode.groupID = groupID;
}
}

static void AddEngine<T>(T engine, Type[] types, Dictionary<Type, FasterList<INodeEngine<INode>>> engines) where T : INodeEngine<INode>
static void AddEngine(IEngine engine, Type[] types,
Dictionary<Type, FasterList<IEngine>> engines)
{
for (int i = 0; i < types.Length; i++)
{
FasterList<INodeEngine<INode>> list;
FasterList<IEngine> list;

var type = types[i];

if (engines.TryGetValue(type, out list) == false)
{
list = new FasterList<INodeEngine<INode>>();
list = new FasterList<IEngine>();

engines.Add(type, list);
}
@@ -204,15 +337,13 @@ namespace Svelto.ECS
}
}

void AddNodeToGroupDB(INode node, Type nodeType)
void AddNodeToMetaDB(INode node, Type nodeType)
{
FasterList<INode> nodes;
if (_nodesDBgroups.TryGetValue(nodeType, out nodes) == false)
nodes = _nodesDBgroups[nodeType] = new FasterList<INode>();
if (_metaNodesDB.TryGetValue(nodeType, out nodes) == false)
nodes = _metaNodesDB[nodeType] = new FasterList<INode>();

nodes.Add(node);

AddNodeToNodesDictionary(node, nodeType);
}

void AddNodeToTheDB<T>(T node, Type nodeType) where T : INode
@@ -222,34 +353,30 @@ namespace Svelto.ECS
nodes = _nodesDB[nodeType] = new FasterList<INode>();

nodes.Add(node);

AddNodeToNodesDictionary(node, nodeType);
}

void AddNodeToNodesDictionary<T>(T node, Type nodeType) where T : INode
void AddNodeToNodesDictionary<T>(T node, Type nodeType) where T : INodeWithID
{
if (node is NodeWithID)
{
Dictionary<int, INode> nodesDic;
if (_nodesDBdic.TryGetValue(nodeType, out nodesDic) == false)
nodesDic = _nodesDBdic[nodeType] = new Dictionary<int, INode>();
Dictionary<int, INode> nodesDic;

nodesDic[(node as NodeWithID).ID] = node;
}
if (_nodesDBdic.TryGetValue(nodeType, out nodesDic) == false)
nodesDic = _nodesDBdic[nodeType] = new Dictionary<int, INode>();

nodesDic.Add(node.ID, node);
}

void AddNodeToTheSuitableEngines<T>(T node, Type nodeType) where T : INode
void AddNodeToTheSuitableEngines(INode node, Type nodeType)
{
FasterList<INodeEngine<INode>> enginesForNode;
FasterList<IEngine> enginesForNode;

if (_nodeEngines.TryGetValue(nodeType, out enginesForNode))
{
for (int j = 0; j < enginesForNode.Count; j++)
{
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
EngineProfiler.MonitorAddDuration(AddNodeToEngine, enginesForNode[j], node);
EngineProfiler.MonitorAddDuration(AddNodeToEngine, enginesForNode[j] as INodeEngine, node);
#else
enginesForNode[j].Add(node);
(enginesForNode[j] as INodeEngine).Add(node);
#endif
}
}
@@ -259,87 +386,168 @@ namespace Svelto.ECS
{
FasterList<INode> nodes;
if (_nodesDB.TryGetValue(nodeType, out nodes) == true)
nodes.UnorderredRemove(node); //should I remove it from the dictionary if length is zero?

RemoveNodeFromNodesDictionary(node, nodeType);
nodes.UnorderedRemove(node); //should I remove it from the dictionary if length is zero?
}

void RemoveNodeFromNodesDictionary<T>(T node, Type nodeType) where T : INode
void RemoveNodeFromMetaDB<T>(T node, Type nodeType) where T : INode
{
if (node is NodeWithID)
{
Dictionary<int, INode> nodesDic;

if (_nodesDBdic.TryGetValue(nodeType, out nodesDic))
nodesDic.Remove((node as NodeWithID).ID);
}
FasterList<INode> nodes;
if (_metaNodesDB.TryGetValue(nodeType, out nodes) == true)
nodes.UnorderedRemove(node); //should I remove it from the dictionary if length is zero?
}

void RemoveNodeFromGroupDB<T>(T node, Type nodeType) where T : INode
void RemoveNodeFromNodesDictionary<T>(T node, Type nodeType) where T : INodeWithID
{
FasterList<INode> nodes;
if (_nodesDBgroups.TryGetValue(nodeType, out nodes) == true)
nodes.UnorderredRemove(node); //should I remove it from the dictionary if length is zero?
Dictionary<int, INode> nodesDic;

RemoveNodeFromNodesDictionary(node, nodeType);
if (_nodesDBdic.TryGetValue(nodeType, out nodesDic))
nodesDic.Remove(node.ID);
}

void RemoveNodeFromEngines<T>(T node, Type nodeType) where T : INode
{
FasterList<INodeEngine<INode>> enginesForNode;
FasterList<IEngine> enginesForNode;

if (_nodeEngines.TryGetValue(nodeType, out enginesForNode))
{
for (int j = 0; j < enginesForNode.Count; j++)
{
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
EngineProfiler.MonitorRemoveDuration(RemoveNodeFromEngine, enginesForNode[j], node);
EngineProfiler.MonitorRemoveDuration(RemoveNodeFromEngine, (enginesForNode[j] as INodeEngine), node);
#else
enginesForNode[j].Remove(node);
(enginesForNode[j] as INodeEngine).Remove(node);
#endif
}
}
}

void DisableNodeFromEngines(INode node, Type nodeType)
{
FasterList<IEngine> enginesForNode;

if (_activableEngines.TryGetValue(nodeType, out enginesForNode))
{
for (int j = 0; j < enginesForNode.Count; j++)
{
(enginesForNode[j] as IActivableNodeEngine).Disable(node);
}
}
}

void EnableNodeFromEngines(INode node, Type nodeType)
{
FasterList<IEngine> enginesForNode;

if (_activableEngines.TryGetValue(nodeType, out enginesForNode))
{
for (int j = 0; j < enginesForNode.Count; j++)
{
(enginesForNode[j] as IActivableNodeEngine).Enable(node);
}
}
}
#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
void AddNodeToEngine(INodeEngine<INode> engine, INode node)
void AddNodeToEngine(IEngine engine, INode node)
{
engine.Add(node);
(engine as INodeEngine).Add(node);
}

void RemoveNodeFromEngine(INodeEngine<INode> engine, INode node)
void RemoveNodeFromEngine(IEngine engine, INode node)
{
engine.Remove(node);
(engine as INodeEngine).Remove(node);
}
#endif
void InternalRemove<T>(T node) where T : INode

void InternalDisable(FasterList<INode> nodes)
{
if (_engineRootWeakReference.IsValid == false)
return;

for (int i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
Type nodeType = node.GetType();
DisableNodeFromEngines(node, nodeType);
}
}

void InternalEnable(FasterList<INode> nodes)
{
if (_engineRootWeakReference.IsValid == false)
return;

for (int i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
Type nodeType = node.GetType();
EnableNodeFromEngines(node, nodeType);
}
}

void InternalRemove(FasterList<INode> nodes)
{
Type nodeType = node.GetType();
if (_engineRootWeakReference.IsValid == false)
return;

RemoveNodeFromEngines(node, nodeType);
RemoveNodeFromTheDB(node, node.GetType());
for (int i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
Type nodeType = node.GetType();

RemoveNodeFromEngines(node, nodeType);
RemoveNodeFromTheDB(node, node.GetType());

var nodeWithId = node as INodeWithID;
if (nodeWithId != null)
RemoveNodeFromNodesDictionary(nodeWithId, nodeType);
}
}

void InternalGroupRemove<T>(T node) where T : INode
void InternalMetaRemove(FasterList<INode> nodes)
{
Type nodeType = node.GetType();
for (int i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
Type nodeType = node.GetType();

RemoveNodeFromEngines(node, nodeType);
RemoveNodeFromMetaDB(node, nodeType);

RemoveNodeFromEngines(node, nodeType);
RemoveNodeFromGroupDB(node, node.GetType());
var nodeWithId = node as INodeWithID;
if (nodeWithId != null)
RemoveNodeFromNodesDictionary(nodeWithId, nodeType);
}
}

Dictionary<Type, FasterList<INodeEngine<INode>>> _nodeEngines;
FasterList<IEngine> _otherEnginesReferences;
readonly Dictionary<Type, FasterList<IEngine>> _nodeEngines;
readonly Dictionary<Type, FasterList<IEngine>> _activableEngines;

readonly FasterList<IEngine> _otherEngines;

readonly Dictionary<Type, FasterList<INode>> _nodesDB;
readonly Dictionary<Type, FasterList<INode>> _metaNodesDB;

readonly Dictionary<Type, Dictionary<int, INode>> _nodesDBdic;

readonly FasterList<INode> _nodesToAdd;
readonly FasterList<INode> _metaNodesToAdd;

readonly WeakReference _engineRootWeakReference;
readonly SharedStructNodeLists _sharedStructNodeLists;
readonly SharedGroupedStructNodesLists _sharedGroupedStructNodeLists;

Dictionary<Type, FasterList<INode>> _nodesDB;
Dictionary<Type, Dictionary<int, INode>> _nodesDBdic;
readonly NodeSubmissionScheduler _scheduler;

Dictionary<Type, FasterList<INode>> _nodesDBgroups;
readonly Action<FasterList<INode>> _internalRemove;
readonly Action<FasterList<INode>> _internalEnable;
readonly Action<FasterList<INode>> _internalDisable;
readonly Action<FasterList<INode>> _internalMetaRemove;

FasterList<INode> _nodesToAdd;
FasterList<INode> _groupNodesToAdd;
readonly Type _structNodeEngineType;
readonly Type _groupedStructNodesEngineType;
readonly Type _activableNodeEngineType;

WeakReference _engineRootWeakReference;
readonly Dictionary<Type, Type[]> _implementedInterfaceTypes;
}
}


+ 0
- 8
ECS/EnginesRoot.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 89361a8514a38544ebb87df0bd766dc5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 124
- 47
ECS/EntityDescriptor.cs View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Svelto.DataStructures;
#if NETFX_CORE
@@ -9,100 +10,176 @@ namespace Svelto.ECS
{
public class EntityDescriptor
{
protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor)
protected EntityDescriptor(INodeBuilder[] nodesToBuild)
{
_implementors = componentsImplementor;
_nodesToBuild = nodesToBuild;
_nodesToBuild = new FasterList<INodeBuilder>(nodesToBuild);
}
protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor):this(nodesToBuild)
{
ProcessImplementors(componentsImplementor);
}

public void AddImplementors(params object[] componentsImplementor)
{
var implementors = new object[componentsImplementor.Length + _implementors.Length];
ProcessImplementors(componentsImplementor);
}

void ProcessImplementors(object[] implementors)
{
for (int index = 0; index < implementors.Length; index++)
{
var implementor = implementors[index];
if (implementor is IRemoveEntityComponent)
_removingImplementors.Add(implementor as IRemoveEntityComponent);
if (implementor is IDisableEntityComponent)
_disablingImplementors.Add(implementor as IDisableEntityComponent);
if (implementor is IEnableEntityComponent)
_enablingImplementors.Add(implementor as IEnableEntityComponent);

Array.Copy(_implementors, implementors, _implementors.Length);
Array.Copy(componentsImplementor, 0, implementors, _implementors.Length, componentsImplementor.Length);
var interfaces = implementor.GetType().GetInterfaces();

_implementors = implementors;
for (int iindex = 0; iindex < interfaces.Length; iindex++)
{
_implementorsByType[interfaces[iindex]] = implementor;
}
}
}

public void AddNodes(params INodeBuilder[] nodesWithID)
{
_nodesToBuild.AddRange(nodesWithID);
}

public virtual FasterList<INode> BuildNodes(int ID, Action<INode> removeAction)
public virtual FasterList<INode> BuildNodes(int ID)
{
var nodes = new FasterList<INode>();

for (int index = 0; index < _nodesToBuild.Length; index++)
for (int index = 0; index < _nodesToBuild.Count; index++)
{
var nodeBuilder = _nodesToBuild[index];
var node = FillNode(nodeBuilder.Build(ID), () =>
{
for (int i = 0; i < nodes.Count; i++)
removeAction(nodes[i]);
var node = nodeBuilder.Build(ID);

nodes.Clear();
}
);
if (nodeBuilder.reflects != FillNodeMode.None)
node = FillNode(node, nodeBuilder.reflects);

nodes.Add (node);
nodes.Add(node);
}

return nodes;
}

TNode FillNode<TNode>(TNode node, Action removeAction) where TNode: INode
internal FasterList<INode> BuildNodes(int ID,
Action<FasterList<INode>> removeEntity,
Action<FasterList<INode>> enableEntity,
Action<FasterList<INode>> disableEntity)
{
var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
var nodes = BuildNodes(ID);

for (int i = fields.Length - 1; i >=0 ; --i)
{
var field = fields[i];
Type fieldType = field.FieldType;
object component = null;

for (int j = 0; j < _implementors.Length; j++)
{
var implementor = _implementors[j];
SetupImplementors(removeEntity, enableEntity, disableEntity, nodes);

if (implementor != null && fieldType.IsAssignableFrom(implementor.GetType()))
{
component = implementor;
return nodes;
}

if (fieldType.IsAssignableFrom(typeof(IRemoveEntityComponent)))
(component as IRemoveEntityComponent).removeEntity = removeAction;
void SetupImplementors(
Action<FasterList<INode>> removeEntity,
Action<FasterList<INode>> enableEntity,
Action<FasterList<INode>> disableEntity,
FasterList<INode> nodes)
{
Action removeEntityAction = () => { removeEntity(nodes); nodes.Clear(); };
Action disableEntityAction = () => disableEntity(nodes);
Action enableEntityAction = () => enableEntity(nodes);

for (int index = 0; index < _removingImplementors.Count; index++)
_removingImplementors[index].removeEntity = removeEntityAction;
for (int index = 0; index < _disablingImplementors.Count; index++)
_disablingImplementors[index].disableEntity = disableEntityAction;
for (int index = 0; index < _enablingImplementors.Count; index++)
_enablingImplementors[index].enableEntity = enableEntityAction;
}

break;
}
}
TNode FillNode<TNode>(TNode node, FillNodeMode mode) where TNode : INode
{
var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);

if (component == null)
for (int i = fields.Length - 1; i >= 0; --i)
{
var field = fields[i];
Type fieldType = field.FieldType;
object component;
if ((_implementorsByType.TryGetValue(fieldType, out component)) == false)
{
Exception e = new Exception("Svelto.ECS: Implementor not found for a Node. " +
"Implementor Type: " + field.FieldType.Name + " - Node: " + node.GetType().Name + " - EntityDescriptor " + this);
if (mode == FillNodeMode.Strict)
{
Exception e =
new Exception("Svelto.ECS: Implementor not found for a Node. " + "Implementor Type: " +
field.FieldType.Name + " - Node: " + node.GetType().Name +
" - EntityDescriptor " + this);

throw e;
throw e;
}
}

field.SetValue(node, component);
else
field.SetValue(node, component);
}

return node;
}

object[] _implementors;
readonly FasterList<IDisableEntityComponent> _disablingImplementors = new FasterList<IDisableEntityComponent>();
readonly FasterList<IRemoveEntityComponent> _removingImplementors = new FasterList<IRemoveEntityComponent>();
readonly FasterList<IEnableEntityComponent> _enablingImplementors = new FasterList<IEnableEntityComponent>();
readonly Dictionary<Type, object> _implementorsByType = new Dictionary<Type, object>();

readonly INodeBuilder[] _nodesToBuild;
readonly FasterList<INodeBuilder> _nodesToBuild;
}

public interface INodeBuilder
{
NodeWithID Build(int ID);
INode Build(int ID);

FillNodeMode reflects { get; }
}

public class NodeBuilder<NodeType> : INodeBuilder where NodeType:NodeWithID, new()
public class NodeBuilder<NodeType> : INodeBuilder where NodeType : NodeWithID, new()
{
public NodeWithID Build(int ID)
public INode Build(int ID)
{
NodeWithID node = NodeWithID.BuildNode<NodeType>(ID);

return (NodeType)node;
}

public FillNodeMode reflects { get { return FillNodeMode.Strict; } }
}

public class StructNodeBuilder<NodeType> : INodeBuilder
where NodeType : struct, IStructNodeWithID
{
public INode Build(int ID)
{
var shortID = (short)ID;
IStructNodeWithID node = default(NodeType);
node.ID = shortID;

return node;
}

public virtual FillNodeMode reflects { get { return FillNodeMode.Relaxed; } }
}

public class FastStructNodeBuilder<NodeType> : StructNodeBuilder<NodeType>
where NodeType : struct, IStructNodeWithID
{
public override FillNodeMode reflects { get { return FillNodeMode.None; } }
}

public enum FillNodeMode
{
Strict,
Relaxed,

None
}
}

+ 0
- 12
ECS/EntityDescriptor.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 42ab9afd9889862468f4afdac4fffd8b
timeCreated: 1457096903
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 41
- 0
ECS/Extensions/Unity/UnitySumbmissionNodeScheduler.cs View File

@@ -0,0 +1,41 @@
#if UNITY_5 || UNITY_5_3_OR_NEWER
using System;
using System.Collections;
using UnityEngine;

namespace Svelto.ECS.NodeSchedulers
{
public class UnitySumbmissionNodeScheduler : NodeSubmissionScheduler
{
public UnitySumbmissionNodeScheduler()
{
GameObject go = new GameObject("ECSScheduler");

_scheduler = go.AddComponent<Scheduler>();
}

public override void Schedule(Action submitNodes)
{
_scheduler.OnTick += submitNodes;
}

class Scheduler : MonoBehaviour
{
IEnumerator Start()
{
while (true)
{
yield return _wait;

OnTick();
}
}

internal Action OnTick;
WaitForEndOfFrame _wait = new WaitForEndOfFrame();
}

Scheduler _scheduler;
}
}
#endif

+ 132
- 18
ECS/GenericEntityDescriptor.cs View File

@@ -1,6 +1,6 @@
namespace Svelto.ECS
{
class GenericEntityDescriptor<T> : EntityDescriptor
public class GenericEntityDescriptor<T> : EntityDescriptor
where T : NodeWithID, new()
{
static GenericEntityDescriptor()
@@ -10,10 +10,10 @@
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{}

static INodeBuilder[] _nodesToBuild;
static readonly INodeBuilder[] _nodesToBuild;
}

class GenericEntityDescriptor<T, U> : EntityDescriptor
public class GenericEntityDescriptor<T, U> : EntityDescriptor
where T : NodeWithID, new()
where U : NodeWithID, new()
{
@@ -29,10 +29,10 @@
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{}

static INodeBuilder[] _nodesToBuild;
static readonly INodeBuilder[] _nodesToBuild;
}

class GenericEntityDescriptor<T, U, V> : EntityDescriptor
public class GenericEntityDescriptor<T, U, V> : EntityDescriptor
where T : NodeWithID, new()
where U : NodeWithID, new()
where V : NodeWithID, new()
@@ -47,12 +47,12 @@
};
}
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{
}
static INodeBuilder[] _nodesToBuild;
{}
static readonly INodeBuilder[] _nodesToBuild;
}

class GenericEntityDescriptor<T, U, V, W> : EntityDescriptor
public class GenericEntityDescriptor<T, U, V, W> : EntityDescriptor
where T : NodeWithID, new()
where U : NodeWithID, new()
where V : NodeWithID, new()
@@ -69,12 +69,12 @@
};
}
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{
}
static INodeBuilder[] _nodesToBuild;
{}
static readonly INodeBuilder[] _nodesToBuild;
}

class GenericEntityDescriptor<T, U, V, W, X> : EntityDescriptor
public class GenericEntityDescriptor<T, U, V, W, X> : EntityDescriptor
where T : NodeWithID, new()
where U : NodeWithID, new()
where V : NodeWithID, new()
@@ -93,11 +93,12 @@
};
}
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{
}
static INodeBuilder[] _nodesToBuild;
{}
static readonly INodeBuilder[] _nodesToBuild;
}
class GenericEntityDescriptor<T, U, V, W, X, Y> : EntityDescriptor

public class GenericEntityDescriptor<T, U, V, W, X, Y> : EntityDescriptor
where T : NodeWithID, new()
where U : NodeWithID, new()
where V : NodeWithID, new()
@@ -118,8 +119,121 @@
};
}
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor)
{}

static readonly INodeBuilder[] _nodesToBuild;
}

public class GenericMixedEntityDescriptor<T> : EntityDescriptor
where T : INodeBuilder, new()
{
static GenericMixedEntityDescriptor()
{
_nodesToBuild = new INodeBuilder[]
{
new T(),
};
}
public GenericMixedEntityDescriptor(params object[] componentsImplementor) :
base(_nodesToBuild, componentsImplementor)
{ }

static readonly INodeBuilder[] _nodesToBuild;
}

public class GenericMixedEntityDescriptor<T, U, V> : EntityDescriptor
where T : INodeBuilder, new()
where U : INodeBuilder, new()
where V : INodeBuilder, new()
{
static GenericMixedEntityDescriptor()
{
_nodesToBuild = new INodeBuilder[]
{
new T(),
new U(),
new V()
};
}
public GenericMixedEntityDescriptor(params object[] componentsImplementor) :
base(_nodesToBuild, componentsImplementor)
{ }

static readonly INodeBuilder[] _nodesToBuild;
}

public class GenericMixedEntityDescriptor<T, U, V, W> : EntityDescriptor
where T : INodeBuilder, new()
where U : INodeBuilder, new()
where V : INodeBuilder, new()
where W : INodeBuilder, new()
{
static GenericMixedEntityDescriptor()
{
_nodesToBuild = new INodeBuilder[]
{
new T(),
new U(),
new V(),
new W()
};
}
static INodeBuilder[] _nodesToBuild;
public GenericMixedEntityDescriptor(params object[] componentsImplementor) :
base(_nodesToBuild, componentsImplementor)
{ }

static readonly INodeBuilder[] _nodesToBuild;
}

public class GenericMixedEntityDescriptor<T, U, V, W, X> : EntityDescriptor
where T : INodeBuilder, new()
where U : INodeBuilder, new()
where V : INodeBuilder, new()
where W : INodeBuilder, new()
where X : INodeBuilder, new()
{
static GenericMixedEntityDescriptor()
{
_nodesToBuild = new INodeBuilder[]
{
new T(),
new U(),
new V(),
new W(),
new X()
};
}
public GenericMixedEntityDescriptor(params object[] componentsImplementor) :
base(_nodesToBuild, componentsImplementor)
{ }

static readonly INodeBuilder[] _nodesToBuild;
}

public class GenericMixedEntityDescriptor<T, U, V, W, X, Y> : EntityDescriptor
where T : INodeBuilder, new()
where U : INodeBuilder, new()
where V : INodeBuilder, new()
where W : INodeBuilder, new()
where X : INodeBuilder, new()
where Y : INodeBuilder, new()
{
static GenericMixedEntityDescriptor()
{
_nodesToBuild = new INodeBuilder[]
{
new T(),
new U(),
new V(),
new W(),
new X(),
new Y()
};
}
public GenericMixedEntityDescriptor(params object[] componentsImplementor) :
base(_nodesToBuild, componentsImplementor)
{ }

static readonly INodeBuilder[] _nodesToBuild;
}
}

+ 0
- 12
ECS/GenericEntityDescriptor.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: fd70d1b3107162f4790b1b71a129818f
timeCreated: 1484485852
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/GenericEntityDescriptorHolder.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: f2bc0783e8d4a7b49a84705c55d8b255
timeCreated: 1498225965
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 2
- 2
ECS/ICallBackOnAddEngine.cs View File

@@ -1,7 +1,7 @@
namespace Svelto.ECS
{
interface ICallBackOnAddEngine
public interface ICallBackOnAddEngine
{
void Ready();
}
}
}

+ 0
- 12
ECS/ICallBackOnAddEngine.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 3928de9a08e5b534ab857ea8b5bebdaf
timeCreated: 1497524074
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 48
- 7
ECS/IEngine.cs View File

@@ -1,21 +1,62 @@
namespace Svelto.ECS
using Svelto.ECS.Internal;

namespace Svelto.ECS.Internal
{
public interface IEngine
{}
public interface IStructNodeEngine : IEngine
{
void CreateStructNodes(SharedStructNodeLists sharedStructNodeLists);
}

public interface IGroupedStructNodesEngine : IEngine
{
void CreateStructNodes(SharedGroupedStructNodesLists sharedStructNodeLists);
}

public interface IActivableNodeEngine : IEngine
{
void Enable(INode obj);
void Disable(INode obj);
}

public interface INodeEngine<in TNodeType>:IEngine where TNodeType:INode
public interface INodeEngine : IEngine
{
void Add(TNodeType obj);
void Remove(TNodeType obj);
void Add(INode obj);
void Remove(INode obj);
}

public interface INodesEngine : INodeEngine<INode>
public interface INodesEngine : INodeEngine
{
System.Type[] AcceptedNodes();
}
}

namespace Svelto.ECS
{
public interface IEngine
{}

public interface IActivableNodeEngine<in TNodeType> : IActivableNodeEngine where TNodeType : INode
{ }

public interface IQueryableNodeEngine:IEngine
{
IEngineNodeDB nodesDB { set; }
}

/// <summary>
/// The engines can receive and store INodes structs
/// Unboxing will happen during the Add, but the
/// data will then be stored and processed as stucts
/// </summary>
public interface IStructNodeEngine<T> : IStructNodeEngine where T:struct, IStructNodeWithID
{ }

/// <summary>
/// same as above, but the nodes are grouped by ID
/// usually the ID is the owner of the nodes of that
/// group
/// </summary>
public interface IGroupedStructNodesEngine<T> : IGroupedStructNodesEngine where T:struct, IGroupedStructNodeWithID
{ }
}


+ 0
- 8
ECS/IEngine.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 26f6a5fa5638d86448dd3f2d11d62f5c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 4
- 4
ECS/IEngineNodeDB.cs View File

@@ -6,14 +6,14 @@ namespace Svelto.ECS
{
ReadOnlyDictionary<int, INode> QueryIndexableNodes<T>() where T:INode;
bool QueryNode<T>(int ID, out T node) where T:INode;
bool TryQueryNode<T>(int ID, out T node) where T:INode;
T QueryNode<T>(int ID) where T:INode;
FasterReadOnlyListCast<INode, T> QueryNodes<T>() where T:INode;

bool QueryNodeFromGroup<T>(int ID, out T node) where T : INode;
T QueryNodeFromGroup<T>(int ID) where T : INode;
FasterReadOnlyListCast<INode, T> QueryNodesFromGroups<T>() where T : INode;
bool TryQueryMetaNode<T>(int metaEntityID, out T node) where T : INode;
T QueryMetaNode<T>(int metaEntityID) where T : INode;
FasterReadOnlyListCast<INode, T> QueryMetaNodes<T>() where T : INode;
}
}


+ 0
- 12
ECS/IEngineNodeDB.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 44c24b91989f46048abc15039fd070bc
timeCreated: 1459422024
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 5
- 1
ECS/IEnginesRoot.cs View File

@@ -1,3 +1,5 @@
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public interface IEnginesRoot
@@ -9,6 +11,8 @@ namespace Svelto.ECS
{
void BuildEntity(int ID, EntityDescriptor ED);

void BuildEntityGroup(int ID, EntityDescriptor ED);
void BuildMetaEntity(int metaEntityID, EntityDescriptor ED);

void BuildEntityInGroup(short entityID, short groupID, EntityDescriptor ED);
}
}

+ 0
- 8
ECS/IEnginesRoot.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b0078c1edf75425478b89366d5fe3bae
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 12
ECS/IEntityDescriptorHolder.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 0badb413a22f42a4b9f68e356e88b07f
timeCreated: 1463438461
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 16
- 1
ECS/INode.cs View File

@@ -3,7 +3,22 @@ namespace Svelto.ECS
public interface INode
{}

public class NodeWithID: INode
public interface INodeWithID:INode
{
int ID { get; }
}

public interface IStructNodeWithID : INode
{
short ID { get; set; }
}

public interface IGroupedStructNodeWithID : IStructNodeWithID
{
short groupID { get; set; }
}

public class NodeWithID: INodeWithID
{
public static TNodeType BuildNode<TNodeType>(int ID) where TNodeType: NodeWithID, new()
{


+ 0
- 8
ECS/INode.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: fc6bea8c56bd7284693db26502c6b65b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 10
- 0
ECS/IRemoveEntityComponent.cs View File

@@ -6,4 +6,14 @@ namespace Svelto.ECS
{
Action removeEntity { get; set; }
}

public interface IDisableEntityComponent
{
Action disableEntity { get; set; }
}

public interface IEnableEntityComponent
{
Action enableEntity { get; set; }
}
}

+ 0
- 12
ECS/IRemoveEntityComponent.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: bb9e778a1f85b0d46a065bbd5b549acd
timeCreated: 1462977663
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 47
- 0
ECS/MultiNodesEngine.cs View File

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

namespace Svelto.ECS.Internal
{
public abstract class MultiNodesEngine<T>
where T : INode
{
protected abstract void AddNode(T node);
protected abstract void RemoveNode(T node);
}
}

namespace Svelto.ECS
{
public abstract class MultiNodesEngine : INodesEngine
{
public abstract System.Type[] AcceptedNodes();

public abstract void Add(INode node);
public abstract void Remove(INode node);
}

public abstract class MultiNodesEngine<T, U> : MultiNodesEngine<T>,
INodeEngine
where T : INode
where U : INode
{
protected abstract void AddNode(U node);
protected abstract void RemoveNode(U node);

public void Add(INode node)
{
if (node is T)
AddNode((T)node);
else
AddNode((U)node);
}

public void Remove(INode node)
{
if (node is T)
RemoveNode((T)node);
else
RemoveNode((U)node);
}
}
}

+ 9
- 0
ECS/NodeSubmissionScheduler.cs View File

@@ -0,0 +1,9 @@
using System;

namespace Svelto.ECS.NodeSchedulers
{
public abstract class NodeSubmissionScheduler
{
abstract public void Schedule(Action submitNodes);
}
}

+ 0
- 9
ECS/Profiler.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 8d07544bb8b417f4a9eaefe0d4771d89
folderAsset: yes
timeCreated: 1462355668
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
ECS/Profiler/Editor.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 71a4fc836cd9bde4bbb936a073804ec5
folderAsset: yes
timeCreated: 1480683133
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
ECS/Profiler/Editor/EngineProfiler.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 777a9420fd80746428f9d2c5b718fd2f
folderAsset: yes
timeCreated: 1462351213
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: a2202d1747b86dc428310091a9c1a7ef
timeCreated: 1462469401
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 1
- 1
ECS/Profiler/Editor/EngineProfiler/EngineProfilerMenuItem.cs View File

@@ -5,7 +5,7 @@ using UnityEditor;

namespace Svelto.ECS.Profiler
{
internal class EngineProfilerMenuItem
class EngineProfilerMenuItem
{
[MenuItem("Engines/Enable Profiler")]
public static void EnableProfiler()


+ 0
- 12
ECS/Profiler/Editor/EngineProfiler/EngineProfilerMenuItem.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: e7b6bbeaaa16ab84aaa99c3311199efa
timeCreated: 1462351229
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/Profiler/Editor/EngineProfiler/EnginesMonitor.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 30f9f7f6468a96d4da2525c65ecfe637
timeCreated: 1467633311
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/Profiler/Editor/EngineProfiler/ProfilerEditorLayout.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: de0de03babf2e9d4db95c2be94eb8c95
timeCreated: 1462527509
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/Profiler/EngineInfo.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 93c5ba48b51186e44b7094eef7028c90
timeCreated: 1462357591
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Svelto.ECS.Internal;

//This profiler is based on the Entitas Visual Debugging tool
//https://github.com/sschmid/Entitas-CSharp
@@ -11,7 +12,7 @@ namespace Svelto.ECS.Profiler
{
static readonly Stopwatch _stopwatch = new Stopwatch();

public static void MonitorAddDuration(Action<INodeEngine<INode>, INode> addingFunc, INodeEngine<INode> engine, INode node)
public static void MonitorAddDuration(Action<INodeEngine, INode> addingFunc, INodeEngine engine, INode node)
{
EngineInfo info;
if (engineInfos.TryGetValue(engine.GetType(), out info))
@@ -25,7 +26,7 @@ namespace Svelto.ECS.Profiler
}
}

public static void MonitorRemoveDuration(Action<INodeEngine<INode>, INode> removeFunc, INodeEngine<INode> engine, INode node)
public static void MonitorRemoveDuration(Action<INodeEngine, INode> removeFunc, INodeEngine engine, INode node)
{
EngineInfo info;
if (engineInfos.TryGetValue(engine.GetType(), out info))


+ 0
- 12
ECS/Profiler/EngineProfiler.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 74b59045fe5033b4b98facadd4d6b114
timeCreated: 1462355668
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 1
- 1
ECS/Profiler/EngineProfilerBehaviour.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using UnityEngine;



+ 0
- 12
ECS/Profiler/EngineProfilerBehaviour.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 688f5cf68b171ef4fa0f6aab49644c48
timeCreated: 1462469401
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 12
ECS/Sequencer.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 4e1f40937ca5027428ed7193729be1a5
timeCreated: 1484487023
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 9
- 6
ECS/SingleNodeEngine.cs View File

@@ -1,15 +1,18 @@
namespace Svelto.ECS
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public abstract class SingleNodeEngine<TNodeType> : INodeEngine<INode> where TNodeType : class, INode
public abstract class SingleNodeEngine<TNodeType> : INodeEngine
where TNodeType : INode
{
void INodeEngine<INode>.Add(INode obj)
public void Add(INode obj)
{
Add(obj as TNodeType);
Add((TNodeType) obj);
}

void INodeEngine<INode>.Remove(INode obj)
public void Remove(INode obj)
{
Remove(obj as TNodeType);
Remove((TNodeType) obj);
}

protected abstract void Add(TNodeType node);


+ 0
- 12
ECS/SingleNodeEngine.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 406a5e818b179b743b582c8fec087ac1
timeCreated: 1469806920
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 134
- 0
ECS/StructNodes.cs View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public class StructNodes<T> where T:struct, IStructNodeWithID
{
public T[] GetList(out int numberOfItems)
{
numberOfItems = _internalList.Count;
return _internalList.ToArrayFast();
}

public StructNodes(SharedStructNodeLists container)
{
_internalList = container.GetList<T>();
}

public void Add(T node)
{
T convert = (T)node;

_internalList.Add(convert);
}

readonly FasterList<T> _internalList;
}

public class StructGroupNodes<T>
where T : struct, IGroupedStructNodeWithID
{
public StructGroupNodes(SharedGroupedStructNodesLists container)
{
_container = container;
}

public void Add(int groupID, T node)
{
T convert = (T)node;

var fasterList = (_container.GetList<T>(groupID) as FasterList<T>);
indices[node.ID] = fasterList.Count;

fasterList.Add(convert);
}

public void Remove(int groupID, T node)
{
var fasterList = (_container.GetList<T>(groupID) as FasterList<T>);
var index = indices[node.ID];
indices.Remove(node.ID);

if (fasterList.UnorderedRemoveAt(index))
indices[fasterList[index].ID] = index;
}

public T[] GetList(int groupID, out int numberOfItems)
{
var fasterList = (_container.GetList<T>(groupID) as FasterList<T>);
numberOfItems = fasterList.Count;
return fasterList.ToArrayFast();
}

readonly SharedGroupedStructNodesLists _container;
readonly Dictionary<int, int> indices = new Dictionary<int, int>();
}

public class SharedStructNodeLists
{
readonly Dictionary<Type, IFasterList> _collection;

internal SharedStructNodeLists()
{
_collection = new Dictionary<Type, IFasterList>();
}

internal FasterList<T> GetList<T>() where T:struct
{
IFasterList list;
if (_collection.TryGetValue(typeof (T), out list))
{
return list as FasterList<T>;
}

list = new FasterList<T>();

_collection.Add(typeof (T), list);

return (FasterList<T>) list;
}
}

public class SharedGroupedStructNodesLists
{
internal SharedGroupedStructNodesLists()
{
_collection = new Dictionary<Type, Dictionary<int, IFasterList>>();
}

internal IFasterList GetList<T>(int groupID) where T : struct
{
Dictionary<int, IFasterList> dic = GetGroup<T>();
IFasterList localList;

if (dic.TryGetValue(groupID, out localList))
return localList;

localList = new FasterList<T>();
dic.Add(groupID, localList);

return localList;
}

internal Dictionary<int, IFasterList> GetGroup<T>() where T : struct
{
Dictionary<int, IFasterList> dic;

if (_collection.TryGetValue(typeof(T), out dic))
{
return dic;
}

dic = new Dictionary<int, IFasterList>();

_collection.Add(typeof(T), dic);

return dic;
}

readonly Dictionary<Type, Dictionary<int, IFasterList>> _collection;
}
}

+ 0
- 4
ECS/note.txt.meta View File

@@ -1,4 +0,0 @@
fileFormatVersion: 2
guid: 11a3defaf51bc2147904eb737af5efb7
TextScriptImporter:
userData:

+ 0
- 9
Factories.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 7f7896118ef3c4949898b5c30aea0c47
folderAsset: yes
timeCreated: 1484044925
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 8
Factories/IGameObjectFactory.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: f3720a403a14c51489b5250365b7185c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
Factories/IMonoBehaviourFactory.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 22ba598cf1fd5124dbb4b999af89a0c5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 0
- 8
LICENSE.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ab819523a7b1394499edac4ffa37556b
timeCreated: 1440946962
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 8
README.md.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e772c63482a119748ba160ed807765a3
timeCreated: 1440946962
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
Utilities.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: b7374ca2eb247d44c8783d7d23f9b89e
folderAsset: yes
timeCreated: 1484394896
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 3
- 3
Utilities/DesignByContract.cs View File

@@ -26,10 +26,10 @@
//
// Alternatively, you can define these in the project properties dialog.

#if UNITY_EDITOR || ROBO_TEST_BUILD
#define DBC_CHECK_ALL
#if DEBUG && !PROFILER
#define DBC_CHECK_ALL
#endif
using System;
using System.Diagnostics;



+ 0
- 10
Utilities/DesignByContract.cs.meta View File

@@ -1,10 +0,0 @@
fileFormatVersion: 2
guid: 5a6942e14a8d33d46a05b33d50392652
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 3
- 6
Utilities/Print.cs View File

@@ -7,7 +7,7 @@ public static class FastConcatUtility
{
static readonly StringBuilder _stringBuilder = new StringBuilder(256);

public static string FastConcat(this string str1, string str2)
public static string FastConcat<T>(this string str1, T str2)
{
lock (_stringBuilder)
{
@@ -136,7 +136,7 @@ namespace Utility
logger.Log(txt);
}

public static void LogError(string txt, bool showCurrentStack = true)
public static void LogError(string txt)
{
string toPrint;
@@ -148,11 +148,8 @@ namespace Utility

toPrint = _stringBuilder.ToString();
}
#if !NETFX_CORE
logger.Log(toPrint, showCurrentStack == true ? new StackTrace().ToString() : null, LogType.Error);
#else

logger.Log(toPrint, null, LogType.Error);
#endif
}

public static void LogError(string txt, string stack)


+ 0
- 8
Utilities/Print.cs.meta View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 1f5eede659a66c64a9af2ec703db2691
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

+ 1
- 1
Utilities/WeakActionStruct.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;


+ 0
- 12
Utilities/WeakActionStruct.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 1662357721652524593d7b0f731aef45
timeCreated: 1484483913
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 4
- 3
Utilities/WeakEvent.cs View File

@@ -1,5 +1,6 @@
using Svelto.DataStructures;
using System;
using System.Collections.Generic;

namespace BetterWeakEvents
{
@@ -13,7 +14,7 @@ namespace BetterWeakEvents

public static WeakEvent<T1, T2> operator-(WeakEvent<T1, T2> c1, Action<T1, T2> x)
{
c1._subscribers.UnorderredRemove(new WeakAction<T1, T2>(x));
c1._subscribers.UnorderedRemove(new WeakAction<T1, T2>(x));
return c1;
}

@@ -21,7 +22,7 @@ namespace BetterWeakEvents
{
for (int i = 0; i < _subscribers.Count; i++)
if (_subscribers[i].Invoke(arg1, arg2) == false)
_subscribers.UnorderredRemoveAt(i--);
_subscribers.UnorderedRemoveAt(i--);
}

~WeakEvent()
@@ -32,4 +33,4 @@ namespace BetterWeakEvents

protected FasterList<WeakAction<T1, T2>> _subscribers = new FasterList<WeakAction<T1, T2>>();
}
}
}

+ 0
- 12
Utilities/WeakEvent.cs.meta View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: e2ee3763e7dffd4459c588eda6867ddd
timeCreated: 1484480295
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Loading…
Cancel
Save