Browse Source

- Added new features to be able to handle nodes as pure structs

- FasterList Clear has been renamed to FastClear. The standard Clear will clean the array like the normal List does
- An engine can now receive callback for when nodes are disabled and enabled
-
tags/Rel1
sebas77 7 years ago
parent
commit
345392dff5
14 changed files with 353 additions and 115 deletions
  1. +24
    -6
      DataStructures/FasterList.cs
  2. +142
    -0
      DataStructures/LockFreeQueue.cs
  3. +1
    -1
      DataStructures/Priority Queue/HeapPriorityQueue.cs
  4. +0
    -2
      DataStructures/ThreadSafeDictionary.cs
  5. +2
    -6
      ECS/EngineNodeDB.cs
  6. +34
    -40
      ECS/EnginesRoot.cs
  7. +21
    -17
      ECS/EntityDescriptor.cs
  8. +26
    -0
      ECS/IEngine.cs
  9. +1
    -1
      ECS/IEnginesRoot.cs
  10. +3
    -3
      ECS/INode.cs
  11. +10
    -10
      ECS/MultiNodesEngine.cs
  12. +1
    -1
      ECS/SingleNodeEngine.cs
  13. +85
    -25
      ECS/StructNodes.cs
  14. +3
    -3
      Utilities/DesignByContract.cs

+ 24
- 6
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; } }

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

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

public bool Contains(T item)
{
_lockQ.EnterReadLock();
@@ -382,6 +397,8 @@ namespace Svelto.DataStructures

public struct FasterReadOnlyListCast<T, U> : IList<U> where U: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; } }

@@ -455,7 +472,6 @@ namespace Svelto.DataStructures

public class FasterList<T> : IList<T>, IFasterList
{
public static FasterList<T> DefaultList = new FasterList<T>();
const int MIN_SIZE = 4;

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

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

return list;
}
@@ -583,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);

@@ -727,11 +743,13 @@ namespace Svelto.DataStructures
DesignByContract.Check.Require(index < _count && _count > 0, "out of bound index");

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

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

return true;
}


+ 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;
}
}
}

+ 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
- 2
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>


+ 2
- 6
ECS/EngineNodeDB.cs View File

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

namespace Svelto.ECS
{
@@ -9,13 +8,11 @@ namespace Svelto.ECS
{
internal EngineNodeDB( Dictionary<Type, FasterList<INode>> nodesDB,
Dictionary<Type, Dictionary<int, INode>> nodesDBdic,
Dictionary<Type, FasterList<INode>> metaNodesDB,
Dictionary<Type, IStructGroupNodes> structNodesDB)
Dictionary<Type, FasterList<INode>> metaNodesDB)
{
_nodesDB = nodesDB;
_nodesDBdic = nodesDBdic;
_metaNodesDB = metaNodesDB;
_structNodesDB = structNodesDB;
}

public FasterReadOnlyListCast<INode, T> QueryNodes<T>() where T:INode
@@ -102,13 +99,12 @@ namespace Svelto.ECS

static FasterReadOnlyListCast<INode, T> RetrieveEmptyNodeList<T>() where T : INode
{
return new FasterReadOnlyListCast<INode, T>(FasterList<INode>.DefaultList);
return FasterReadOnlyListCast<INode, T>.DefaultList;
}

readonly Dictionary<Type, FasterList<INode>> _nodesDB;
readonly Dictionary<Type, Dictionary<int, INode>> _nodesDBdic;
readonly Dictionary<Type, FasterList<INode>> _metaNodesDB;
readonly Dictionary<Type, IStructGroupNodes> _structNodesDB;

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


+ 34
- 40
ECS/EnginesRoot.cs View File

@@ -16,23 +16,6 @@ using System.Reflection;

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

OnTick();
}
}

internal Action OnTick;

readonly WaitForEndOfFrame _waitForEndOfFrame = new WaitForEndOfFrame();
}

public sealed class EnginesRoot : IEnginesRoot, IEntityFactory
{
public EnginesRoot(NodeSubmissionScheduler nodeScheduler)
@@ -50,7 +33,8 @@ namespace Svelto.ECS
_metaNodesToAdd = new FasterList<INode>();

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

_internalRemove = InternalRemove;
_internalDisable = InternalDisable;
@@ -60,6 +44,8 @@ namespace Svelto.ECS
_scheduler = nodeScheduler;
_scheduler.Schedule(SubmitNodes);

_structNodeEngineType = typeof(IStructNodeEngine<>);
_groupedStructNodesEngineType = typeof(IGroupedStructNodesEngine<>);
_activableNodeEngineType = typeof(IActivableNodeEngine<>);
_implementedInterfaceTypes = new Dictionary<Type, Type[]>();
@@ -84,9 +70,11 @@ namespace Svelto.ECS

do
{
var nodesToAdd = _nodesToAdd.ToArrayFast();

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

AddNodeToTheDB(node, nodeType);
@@ -95,9 +83,11 @@ namespace Svelto.ECS
AddNodeToNodesDictionary(nodeWithId, nodeType);
}

var metaNodesToAdd = _metaNodesToAdd.ToArrayFast();

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

AddNodeToMetaDB(node, nodeType);
@@ -108,13 +98,13 @@ namespace Svelto.ECS

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

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

@@ -147,7 +137,7 @@ namespace Svelto.ECS
var queryableNodeEngine = engine as IQueryableNodeEngine;
if (queryableNodeEngine != null)
queryableNodeEngine.nodesDB =
new EngineNodeDB(_nodesDB, _nodesDBdic, _metaNodesDB, _structNodesDB);
new EngineNodeDB(_nodesDB, _nodesDBdic, _metaNodesDB);

var engineType = engine.GetType();
var implementedInterfaces = engineType.GetInterfaces();
@@ -185,8 +175,6 @@ namespace Svelto.ECS
}

var genericTypeDefinition = interfaceType.GetGenericTypeDefinition();
var a = interfaceType.GetGenericArguments();
var b = genericTypeDefinition.GetGenericArguments();

_implementedInterfaceTypes.Add(genericTypeDefinition,
interfaceType.GetGenericArguments());
@@ -199,6 +187,18 @@ namespace Svelto.ECS

bool engineAdded = false;

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

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

Type[] arguments;
if (_implementedInterfaceTypes.TryGetValue(_activableNodeEngineType,
out arguments))
@@ -298,7 +298,7 @@ namespace Svelto.ECS
/// <param name="entityID"></param>
/// <param name="groupID"></param>
/// <param name="ed"></param>
public void BuildEntityInGroup(int entityID, int groupID,
public void BuildEntityInGroup(short entityID, short groupID,
EntityDescriptor ed)
{
var entityNodes = ed.BuildNodes(entityID,
@@ -349,19 +349,10 @@ namespace Svelto.ECS
void AddNodeToTheDB<T>(T node, Type nodeType) where T : INode
{
FasterList<INode> nodes;
if (_nodesDB.TryGetValue(nodeType, out nodes) == false)
nodes = _nodesDB[nodeType] = new FasterList<INode>();

if (node is IStructNodeWithID == false)
{
if (_nodesDB.TryGetValue(nodeType, out nodes) == false)
nodes = _nodesDB[nodeType] = new FasterList<INode>();

nodes.Add(node);
}
else
{
if (_nodesDB.TryGetValue(nodeType, out nodes) == false)
nodes = _nodesDB[nodeType] = new FasterList<INode>();
}
nodes.Add(node);
}

void AddNodeToNodesDictionary<T>(T node, Type nodeType) where T : INodeWithID
@@ -535,14 +526,15 @@ namespace Svelto.ECS

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

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

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

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

readonly NodeSubmissionScheduler _scheduler;

@@ -551,6 +543,8 @@ namespace Svelto.ECS
readonly Action<FasterList<INode>> _internalDisable;
readonly Action<FasterList<INode>> _internalMetaRemove;

readonly Type _structNodeEngineType;
readonly Type _groupedStructNodesEngineType;
readonly Type _activableNodeEngineType;

readonly Dictionary<Type, Type[]> _implementedInterfaceTypes;


+ 21
- 17
ECS/EntityDescriptor.cs View File

@@ -10,10 +10,12 @@ namespace Svelto.ECS
{
public class EntityDescriptor
{
protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor)
protected EntityDescriptor(INodeBuilder[] nodesToBuild)
{
_nodesToBuild = new FasterList<INodeBuilder>(nodesToBuild);

}
protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor):this(nodesToBuild)
{
ProcessImplementors(componentsImplementor);
}

@@ -84,12 +86,9 @@ namespace Svelto.ECS
Action<FasterList<INode>> disableEntity,
FasterList<INode> nodes)
{
Action removeEntityAction = () =>
{ removeEntity(nodes); nodes.Clear(); };
Action disableEntityAction = () =>
{ disableEntity(nodes); };
Action enableEntityAction = () =>
{ enableEntity(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;
@@ -99,7 +98,7 @@ namespace Svelto.ECS
_enablingImplementors[index].enableEntity = enableEntityAction;
}

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

@@ -131,21 +130,21 @@ namespace Svelto.ECS
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 FasterList<INodeBuilder> _nodesToBuild;
}

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

FillNodeMode reflects { get; }
}

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

@@ -155,20 +154,25 @@ namespace Svelto.ECS
public FillNodeMode reflects { get { return FillNodeMode.Strict; } }
}

//To Do: Probably I will need to add an
//FastStructNodeBuilder where reflects is false
public class StructNodeBuilder<NodeType> : INodeBuilder
where NodeType : struct, IStructNodeWithID
{
public INodeWithID Build(int ID)
public INode Build(int ID)
{
var shortID = (short)ID;
IStructNodeWithID node = default(NodeType);
node.ID = ID;
node.ID = shortID;

return node;
}

public FillNodeMode reflects { get { return FillNodeMode.Relaxed; } }
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


+ 26
- 0
ECS/IEngine.cs View File

@@ -2,6 +2,16 @@ using Svelto.ECS.Internal;

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

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

public interface IActivableNodeEngine : IEngine
{
void Enable(INode obj);
@@ -32,5 +42,21 @@ namespace Svelto.ECS
{
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
{ }
}


+ 1
- 1
ECS/IEnginesRoot.cs View File

@@ -13,6 +13,6 @@ namespace Svelto.ECS

void BuildMetaEntity(int metaEntityID, EntityDescriptor ED);

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

+ 3
- 3
ECS/INode.cs View File

@@ -8,14 +8,14 @@ namespace Svelto.ECS
int ID { get; }
}

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

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

public class NodeWithID: INodeWithID


ECS/MultipleNodesEngine.cs → ECS/MultiNodesEngine.cs View File

@@ -5,8 +5,8 @@ namespace Svelto.ECS.Internal
public abstract class MultiNodesEngine<T>
where T : INode
{
protected internal abstract void Add(T node);
protected internal abstract void Remove(T node);
protected abstract void AddNode(T node);
protected abstract void RemoveNode(T node);
}
}

@@ -20,28 +20,28 @@ namespace Svelto.ECS
public abstract void Remove(INode node);
}

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

public void Add(INode node)
{
if (node is T)
Add((T) node);
AddNode((T)node);
else
((MultiNodesEngine<U>)(this)).Add((U)node);
AddNode((U)node);
}

public void Remove(INode node)
{
if (node is T)
Remove((T)node);
RemoveNode((T)node);
else
((MultiNodesEngine<U>)(this)).Remove((U)node);
RemoveNode((U)node);
}
}
}

+ 1
- 1
ECS/SingleNodeEngine.cs View File

@@ -3,7 +3,7 @@
namespace Svelto.ECS
{
public abstract class SingleNodeEngine<TNodeType> : INodeEngine
where TNodeType : class, INode
where TNodeType : INode
{
public void Add(INode obj)
{


+ 85
- 25
ECS/StructNodes.cs View File

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

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

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

public void Add(T node)
@@ -29,46 +28,107 @@ namespace Svelto.ECS
readonly FasterList<T> _internalList;
}

public class StructGroupNodes<T>: IStructGroupNodes
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 = GetList(groupID);
_indices[node.ID] = fasterList.Count;
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 = GetList(groupID);
var index = _indices[node.ID];
_indices.Remove(node.ID);
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;
indices[fasterList[index].ID] = index;
}

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

readonly Dictionary<int, int> _indices = new Dictionary<int, int>();
Dictionary<int, FasterList<T>> _nodes = new Dictionary<int, FasterList<T>>();
readonly SharedGroupedStructNodesLists _container;
readonly Dictionary<int, int> indices = new Dictionary<int, int>();
}
}

namespace Svelto.ECS.Internal
{
public interface IStructGroupNodes
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 interface IStructNodes
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;
}
}

+ 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;



Loading…
Cancel
Save