From 5897f66b2d3d1980cd567d4b3236110290be4b31 Mon Sep 17 00:00:00 2001 From: sebas77 Date: Fri, 8 Dec 2017 18:18:26 +0000 Subject: [PATCH] - INodesEngine is now Legacy. EnginesRoot still support it, but I will probably add a new Legacy Engine Root to support INodesEngine. Best thing would be to transform all the INodesEngine into MultiNodesEngine - Support for grouped nodes (adding and querying them) is almost complete - EngineRoot and EngineNodeDB can now support nodes as struct and class - INodeEngine Add and Remove functions accept only NodeWithID (classes only) - --- ECS/DataStructures/TypeSafeDictionary.cs | 35 +- .../TypeSafeFasterListForECS.cs | 82 ++++ ECS/DataStructures/TypeSafeList.cs | 51 -- ECS/EngineNodeDB.cs | 58 ++- ECS/EnginesRoot.cs | 459 ++++++++++-------- ECS/EntityDescriptor.cs | 162 +++---- ECS/IEngine.cs | 20 +- ECS/IEngineNodeDB.cs | 18 +- ECS/INode.cs | 12 +- ECS/MultiNodesEngine.cs | 101 ++-- ECS/NodeBuilder.cs | 33 +- .../EngineProfiler/EngineProfilerInspector.cs | 4 +- ECS/Profiler/EngineProfiler.cs | 10 +- ECS/Profiler/EngineProfilerBehaviour.cs | 2 +- ECS/SingleNodeEngine.cs | 21 +- ECS/StructNodes.cs | 30 +- 16 files changed, 612 insertions(+), 486 deletions(-) create mode 100644 ECS/DataStructures/TypeSafeFasterListForECS.cs delete mode 100644 ECS/DataStructures/TypeSafeList.cs diff --git a/ECS/DataStructures/TypeSafeDictionary.cs b/ECS/DataStructures/TypeSafeDictionary.cs index 022ebe5..e399ba1 100644 --- a/ECS/DataStructures/TypeSafeDictionary.cs +++ b/ECS/DataStructures/TypeSafeDictionary.cs @@ -1,7 +1,8 @@ using Svelto.DataStructures; using System.Collections.Generic; +using Svelto.ECS.Internal; -namespace Svelto.ECS +namespace Svelto.ECS.Internal { /// /// This is just a place holder at the moment @@ -13,11 +14,37 @@ namespace Svelto.ECS public interface ITypeSafeDictionary { - + void FillWithIndexedNodes(ITypeSafeList nodes); + void Remove(int entityId); + NodeWithID GetIndexedNode(int entityID); } - public class TypeSafeDictionary : Dictionary, ITypeSafeDictionary + class TypeSafeDictionary : Dictionary, ITypeSafeDictionary where TValue:NodeWithID { - internal static readonly ReadOnlyDictionary Default = new ReadOnlyDictionary(new TypeSafeDictionary()); + internal static readonly ReadOnlyDictionary Default = + new ReadOnlyDictionary(new Dictionary()); + + public void FillWithIndexedNodes(ITypeSafeList nodes) + { + int count; + var buffer = FasterList.NoVirt.ToArrayFast((FasterList) nodes, out count); + + for (int i = 0; i < count; i++) + { + var node = buffer[i]; + + Add(node.ID, node); + } + } + + public void Remove(int entityId) + { + throw new System.NotImplementedException(); + } + + public NodeWithID GetIndexedNode(int entityID) + { + return this[entityID]; + } } } diff --git a/ECS/DataStructures/TypeSafeFasterListForECS.cs b/ECS/DataStructures/TypeSafeFasterListForECS.cs new file mode 100644 index 0000000..e6e47a3 --- /dev/null +++ b/ECS/DataStructures/TypeSafeFasterListForECS.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Svelto.DataStructures; + +namespace Svelto.ECS.Internal +{ + public interface ITypeSafeList: IEnumerable + { + void AddRange(ITypeSafeList nodeListValue); + + ITypeSafeList Create(); + bool isQueryiableNode { get; } + void UnorderedRemove(int index); + ITypeSafeDictionary CreateIndexedDictionary(); + } + + class TypeSafeFasterListForECS: FasterList where T:INode + { + protected TypeSafeFasterListForECS() + { + _mappedIndices = new Dictionary(); + } + + public void UnorderedRemove(int mappedIndex) + { + var index = _mappedIndices[mappedIndex]; + _mappedIndices.Remove(mappedIndex); + + if (UnorderedRemoveAt(index)) + _mappedIndices[this[index].ID] = index; + } + + public void AddRange(ITypeSafeList nodeListValue) + { + var index = this.Count; + + AddRange(nodeListValue as FasterList); + + for (int i = index; i < Count; ++i) + _mappedIndices[this[i].ID] = this.Count; + } + + readonly Dictionary _mappedIndices; + } + + class TypeSafeFasterListForECSForStructs : TypeSafeFasterListForECS, ITypeSafeList where T:struct, INode + { + public ITypeSafeList Create() + { + return new TypeSafeFasterListForECSForStructs(); + } + + public bool isQueryiableNode + { + get { return false; } + } + + public ITypeSafeDictionary CreateIndexedDictionary() + { + throw new Exception("Not Allowed"); + } + } + + class TypeSafeFasterListForECSForClasses : TypeSafeFasterListForECS, ITypeSafeList where T:NodeWithID + { + public ITypeSafeList Create() + { + return new TypeSafeFasterListForECSForClasses(); + } + + public bool isQueryiableNode + { + get { return true; } + } + + public ITypeSafeDictionary CreateIndexedDictionary() + { + return new TypeSafeDictionary(); + } + } +} diff --git a/ECS/DataStructures/TypeSafeList.cs b/ECS/DataStructures/TypeSafeList.cs deleted file mode 100644 index cac7c4b..0000000 --- a/ECS/DataStructures/TypeSafeList.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Svelto.DataStructures; -using Svelto.ECS.Internal; - -namespace Svelto.ECS -{ - public interface ITypeSafeList - { - void Clear(); - void AddRange(ITypeSafeList nodeListValue); - - ITypeSafeList Create(); - ITypeSafeDictionary CreateIndexedDictionary(); - void AddToIndexedDictionary(ITypeSafeDictionary nodesDic); - } - - public class TypeSafeFasterList : FasterList, ITypeSafeList - { - public TypeSafeFasterList() - { - } - - public void AddRange(ITypeSafeList nodeListValue) - { - AddRange(nodeListValue as FasterList); - } - - public ITypeSafeList Create() - { - return new TypeSafeFasterList(); - } - - public ITypeSafeDictionary CreateIndexedDictionary() - { - return new TypeSafeDictionary(); - } - - public void AddToIndexedDictionary(ITypeSafeDictionary nodesDic) - { - var dic = nodesDic as TypeSafeDictionary; - - var buffer = NoVirt.ToArrayFast(this); - - for (int i = 0; i < Count; i++) - { - T node = buffer[i]; - - dic[(node as NodeWithID).ID] = node; - } - } - } -} diff --git a/ECS/EngineNodeDB.cs b/ECS/EngineNodeDB.cs index 9e26351..126dd46 100644 --- a/ECS/EngineNodeDB.cs +++ b/ECS/EngineNodeDB.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Svelto.DataStructures; +using Svelto.ECS.Internal; namespace Svelto.ECS { @@ -8,11 +9,13 @@ namespace Svelto.ECS { internal EngineNodeDB( Dictionary nodesDB, Dictionary nodesDBdic, - Dictionary metaNodesDB) + Dictionary metaNodesDB, + Dictionary> groupNodesDB) { _nodesDB = nodesDB; _nodesDBdic = nodesDBdic; _metaNodesDB = metaNodesDB; + _groupNodesDB = groupNodesDB; } public FasterReadOnlyList QueryNodes() @@ -27,24 +30,46 @@ namespace Svelto.ECS return new FasterReadOnlyList((FasterList)nodes); } - public ReadOnlyDictionary QueryIndexableNodes() + public FasterReadOnlyList QueryGroupedNodes(int @group) + { + return new FasterReadOnlyList(_groupNodesDB[group] as FasterList); + } + + public T[] QueryNodesAsArray(out int count) where T : struct + { + var type = typeof(T); + count = 0; + + ITypeSafeList nodes; + + if (_nodesDB.TryGetValue(type, out nodes) == false) + return null; + + var castedNodes = (FasterList)nodes; + + count = castedNodes.Count; + + return castedNodes.ToArrayFast(); + } + + public ReadOnlyDictionary QueryIndexableNodes() where T:NodeWithID { var type = typeof(T); ITypeSafeDictionary nodes; if (_nodesDBdic.TryGetValue(type, out nodes) == false) - return TypeSafeDictionary.Default; + return TypeSafeDictionary.Default; return new ReadOnlyDictionary(nodes as Dictionary); } - public T QueryMetaNode(int metaEntityID) + public T QueryMetaNode(int metaEntityID) where T:NodeWithID { return QueryNode(metaEntityID); } - public bool TryQueryMetaNode(int metaEntityID, out T node) + public bool TryQueryMetaNode(int metaEntityID, out T node) where T:NodeWithID { return TryQueryNode(metaEntityID, out node); } @@ -61,18 +86,22 @@ namespace Svelto.ECS return new FasterReadOnlyList((FasterList)nodes); } - public bool TryQueryNode(int ID, out T node) + public bool TryQueryNode(int ID, out T node) where T:NodeWithID { var type = typeof(T); T internalNode; ITypeSafeDictionary nodes; + TypeSafeDictionary casted; - if (_nodesDBdic.TryGetValue(type, out nodes) && - (nodes as Dictionary).TryGetValue(ID, out internalNode)) + _nodesDBdic.TryGetValue(type, out nodes); + casted = nodes as TypeSafeDictionary; + + if (casted != null && + casted.TryGetValue(ID, out internalNode)) { - node = internalNode; + node = (T) internalNode; return true; } @@ -82,14 +111,18 @@ namespace Svelto.ECS return false; } - public T QueryNode(int ID) + public T QueryNode(int ID) where T:NodeWithID { var type = typeof(T); T internalNode; ITypeSafeDictionary nodes; + TypeSafeDictionary casted; + + _nodesDBdic.TryGetValue(type, out nodes); + casted = nodes as TypeSafeDictionary; - if (_nodesDBdic.TryGetValue(type, out nodes) && - (nodes as Dictionary).TryGetValue(ID, out internalNode)) + if (casted != null && + casted.TryGetValue(ID, out internalNode)) return (T)internalNode; throw new Exception("Node Not Found"); @@ -103,5 +136,6 @@ namespace Svelto.ECS readonly Dictionary _nodesDB; readonly Dictionary _nodesDBdic; readonly Dictionary _metaNodesDB; + readonly Dictionary> _groupNodesDB; } } diff --git a/ECS/EnginesRoot.cs b/ECS/EnginesRoot.cs index 3deadf8..7602238 100644 --- a/ECS/EnginesRoot.cs +++ b/ECS/EnginesRoot.cs @@ -1,12 +1,13 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; using Svelto.DataStructures; using Svelto.ECS.Internal; +using Svelto.ECS.Legacy; using Svelto.ECS.NodeSchedulers; -using System.Reflection; +using Svelto.ECS.Profiler; using Svelto.Utilities; -using UnityEngine.UI; -using UnityEngine.XR.WSA.Persistence; #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR using Svelto.ECS.Profiler; @@ -16,9 +17,9 @@ namespace Svelto.ECS.Internal { struct BuildNodeCallbackStruct { - public Action _internalRemove; - public Action _internalEnable; - public Action _internalDisable; + public Action, int> internalRemove; + public Action, int> internalEnable; + public Action, int> internalDisable; } } @@ -32,22 +33,37 @@ namespace Svelto.ECS _activableEngines = new Dictionary>(); _otherEngines = new FasterList(); - //_engineRootWeakReference = new DataStructures.WeakReference(this); + _engineRootWeakReference = new DataStructures.WeakReference(this); _nodesDB = new Dictionary(); _metaNodesDB = new Dictionary(); + _groupNodesDB = new Dictionary>(); _nodesDBdic = new Dictionary(); + + _sharedStructNodeLists = new SharedStructNodeLists(); + _sharedGroupedStructNodeLists = new SharedGroupedStructNodesLists(); + + _nodesToAdd = new DoubleBufferedNodes>(); + _metaNodesToAdd = new DoubleBufferedNodes>(); + _groupedNodesToAdd = new DoubleBufferedNodes>>(); + + _callBackStructForBuiltGroupedNodes = new BuildNodeCallbackStruct(); - _nodesToAdd = new Dictionary(); - _metaNodesToAdd = new Dictionary(); - _groupedNodesToAdd = new Dictionary>(); + _callBackStructForBuiltGroupedNodes.internalRemove = InternalRemove; + _callBackStructForBuiltGroupedNodes.internalDisable = InternalDisable; + _callBackStructForBuiltGroupedNodes.internalEnable = InternalEnable; - _callBackStruct = new BuildNodeCallbackStruct(); + _callBackStructForBuiltNodes = new BuildNodeCallbackStruct(); - /* _callBackStruct._internalRemove = InternalRemove; - _callBackStruct._internalDisable = InternalDisable; - _callBackStruct._internalEnable = InternalEnable; - _callBackStruct._internalMetaRemove = InternalMetaRemove;*/ + _callBackStructForBuiltNodes.internalRemove = InternalGroupedRemove; + _callBackStructForBuiltNodes.internalDisable = InternalDisable; + _callBackStructForBuiltNodes.internalEnable = InternalEnable; + + _callBackStructForBuiltMetaNodes = new BuildNodeCallbackStruct(); + + _callBackStructForBuiltMetaNodes.internalRemove = InternalMetaRemove; + _callBackStructForBuiltMetaNodes.internalDisable = InternalDisable; + _callBackStructForBuiltMetaNodes.internalEnable = InternalEnable; _scheduler = nodeScheduler; _scheduler.Schedule(SubmitNodes); @@ -58,15 +74,15 @@ namespace Svelto.ECS _implementedInterfaceTypes = new Dictionary(); -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - GameObject debugEngineObject = new GameObject("Engine Debugger"); +#if UNITY_EDITOR + UnityEngine.GameObject debugEngineObject = new UnityEngine.GameObject("Engine Debugger"); debugEngineObject.gameObject.AddComponent(); #endif } public void BuildEntity(int ID, EntityDescriptor ed) { - ed.BuildNodes(ID, _nodesToAdd, ref _callBackStruct); + ed.BuildNodes(ID, _nodesToAdd.other, ref _callBackStructForBuiltNodes); } /// @@ -95,7 +111,7 @@ namespace Svelto.ECS /// public void BuildMetaEntity(int metaEntityID, EntityDescriptor ed) { - ed.BuildNodes(metaEntityID, _metaNodesToAdd, ref _callBackStruct); + ed.BuildNodes(metaEntityID, _metaNodesToAdd.other, ref _callBackStructForBuiltMetaNodes); } /// @@ -110,18 +126,18 @@ namespace Svelto.ECS public void BuildEntityInGroup(int entityID, int groupID, EntityDescriptor ed) { - ed.BuildGroupedNodes(entityID, groupID, _groupedNodesToAdd, ref _callBackStruct); + ed.BuildGroupedNodes(entityID, groupID, _groupedNodesToAdd.other, ref _callBackStructForBuiltGroupedNodes); } public void AddEngine(IEngine engine) { -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR +#if UNITY_EDITOR EngineProfiler.AddEngine(engine); #endif var queryableNodeEngine = engine as IQueryableNodeEngine; if (queryableNodeEngine != null) queryableNodeEngine.nodesDB = - new EngineNodeDB(_nodesDB, _nodesDBdic, _metaNodesDB); + new EngineNodeDB(_nodesDB, _nodesDBdic, _metaNodesDB, _groupNodesDB); var engineType = engine.GetType(); var implementedInterfaces = engineType.GetInterfaces(); @@ -171,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)) @@ -235,36 +263,75 @@ namespace Svelto.ECS } } - static void AddNodesToTheDBAndSuitableEngines(Dictionary nodesToAdd, + static void AddNodesToTheDBAndSuitableEngines(Dictionary nodesToAdd, Dictionary> nodeEngines, Dictionary nodesDBdic, Dictionary nodesDB) { foreach (var nodeList in nodesToAdd) { - ITypeSafeList dbList; + AddNodeToDB(nodesDB, nodeList); - if (nodesDB.TryGetValue(nodeList.Key, out dbList) == false) - dbList = nodesDB[nodeList.Key] = nodeList.Value.Create(); + if (nodeList.Value.isQueryiableNode) + { + AddNodeToNodesDictionary(nodesDBdic, nodeList.Value, nodeList.Key); + + foreach (var node in nodeList.Value) + AddNodeToTheSuitableEngines(nodeEngines, node as NodeWithID, nodeList.Key); + } + } + } - dbList.AddRange(nodeList.Value); + static void AddGroupNodesToTheDBAndSuitableEngines(Dictionary> groupedNodesToAdd, + Dictionary> nodeEngines, + Dictionary nodesDBdic, + Dictionary> groupNodesDB, + Dictionary nodesDB) + { + foreach (var group in groupedNodesToAdd) + { + AddNodesToTheDBAndSuitableEngines(group.Value, nodeEngines, nodesDBdic, nodesDB); - AddNodeToNodesDictionary(nodesDBdic, nodeList.Value, nodeList.Key); - AddNodesToTheSuitableEngines(nodeEngines, nodeList.Value, nodeList.Key); + AddNodesToGroupDB(groupNodesDB, @group); } } + + static void AddNodesToGroupDB(Dictionary> groupNodesDB, + KeyValuePair> @group) + { + Dictionary groupedNodesByType; + + if (groupNodesDB.TryGetValue(@group.Key, out groupedNodesByType) == false) + groupedNodesByType = groupNodesDB[@group.Key] = new Dictionary(); + + foreach (var node in @group.Value) + { + groupedNodesByType.Add(node.Key, node.Value); + } + } + + static void AddNodeToDB(Dictionary nodesDB, KeyValuePair nodeList) + { + ITypeSafeList dbList; + + if (nodesDB.TryGetValue(nodeList.Key, out dbList) == false) + dbList = nodesDB[nodeList.Key] = nodeList.Value.Create(); + + dbList.AddRange(nodeList.Value); + } - static void AddNodeToNodesDictionary(Dictionary nodesDBdic, ITypeSafeList nodes, Type nodeType) + static void AddNodeToNodesDictionary(Dictionary nodesDBdic, + ITypeSafeList nodes, Type nodeType) { ITypeSafeDictionary nodesDic; - + if (nodesDBdic.TryGetValue(nodeType, out nodesDic) == false) nodesDic = nodesDBdic[nodeType] = nodes.CreateIndexedDictionary(); - nodes.AddToIndexedDictionary(nodesDic); + nodesDic.FillWithIndexedNodes(nodes); } - static void AddNodesToTheSuitableEngines(Dictionary> nodeEngines, ITypeSafeList nodes, Type nodeType) + static void AddNodeToTheSuitableEngines(Dictionary> nodeEngines, NodeWithID node, Type nodeType) { FasterList enginesForNode; @@ -273,191 +340,170 @@ namespace Svelto.ECS for (int j = 0; j < enginesForNode.Count; j++) { #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - EngineProfiler.MonitorAddDuration(AddNodeToEngine, enginesForNode[j] as INodeEngine, node); + EngineProfiler.MonitorRemoveDuration(RemoveNodeFromEngine, (enginesForNode[j] as INodeEngine), node); #else - (enginesForNode[j] as INodeEngine).Add(nodes); + (enginesForNode[j] as INodeEngine).Add(node); #endif } } } - /* - void RemoveNodeFromTheDB(T node, Type nodeType) where T : INode - { - FasterList nodes; - if (_nodesDB.TryGetValue(nodeType, out nodes) == true) - nodes.UnorderedRemove(node); //should I remove it from the dictionary if length is zero? - } +/* + void DisableNodeFromEngines(INode node, Type nodeType) + { + ITypeSafeList enginesForNode; - void RemoveNodeFromMetaDB(T node, Type nodeType) where T : INode + if (_activableEngines.TryGetValue(nodeType, out enginesForNode)) + { + for (int j = 0; j < enginesForNode.Count; j++) { - FasterList nodes; - if (_metaNodesDB.TryGetValue(nodeType, out nodes) == true) - nodes.UnorderedRemove(node); //should I remove it from the dictionary if length is zero? + (enginesForNode[j] as IActivableNodeEngine).Disable(node); } + } + } - void RemoveNodeFromNodesDictionary(T node, Type nodeType) where T : INodeWithID - { - Dictionary nodesDic; - - if (_nodesDBdic.TryGetValue(nodeType, out nodesDic)) - nodesDic.Remove(node.ID); - } + void EnableNodeFromEngines(INode node, Type nodeType) + { + ITypeSafeList enginesForNode; - void RemoveNodeFromEngines(T node, Type nodeType) where T : INode + if (_activableEngines.TryGetValue(nodeType, out enginesForNode)) + { + for (int j = 0; j < enginesForNode.Count; j++) { - FasterList 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] as INodeEngine), node); - #else - (enginesForNode[j] as INodeEngine).Remove(node); - #endif - } - } + (enginesForNode[j] as IActivableNodeEngine).Enable(node); } + } + }*/ +#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR + void AddNodeToEngine(IEngine engine, INode node) + { + (engine as INodeEngine).Add(node); + } - void DisableNodeFromEngines(INode node, Type nodeType) - { - FasterList enginesForNode; - - if (_activableEngines.TryGetValue(nodeType, out enginesForNode)) - { - for (int j = 0; j < enginesForNode.Count; j++) - { - (enginesForNode[j] as IActivableNodeEngine).Disable(node); - } - } - } + void RemoveNodeFromEngine(IEngine engine, INode node) + { + (engine as INodeEngine).Remove(node); + } +#endif - void EnableNodeFromEngines(INode node, Type nodeType) - { - FasterList 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(IEngine engine, INode node) - { - (engine as INodeEngine).Add(node); - } + void InternalDisable(FasterList nodeBuilders, int entityID) + { +/* if (_engineRootWeakReference.IsValid == false) + return; - void RemoveNodeFromEngine(IEngine engine, INode node) - { - (engine as INodeEngine).Remove(node); - } - #endif - /* - void InternalDisable(FasterList 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); - } - } + for (int i = 0; i < nodes.Count; i++) + { + var node = nodes[i]; + Type nodeType = node.GetType(); + + DisableNodeFromEngines(node, nodeType); + }*/ + } - void InternalEnable(FasterList 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 InternalEnable(FasterList nodeBuilders, int entityID) + {/* + if (_engineRootWeakReference.IsValid == false) + return; - void InternalRemove(IFasterList 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); + }*/ + } - for (int i = 0; i < nodes.Count; i++) - { - var node = nodes[i]; - Type nodeType = node.GetType(); + void InternalRemove(FasterList nodeBuilders, int entityID) + { + if (_engineRootWeakReference.IsValid == false) + return; - RemoveNodeFromEngines(node, nodeType); - RemoveNodeFromTheDB(node, node.GetType()); + int nodeBuildersCount = nodeBuilders.Count; + for (int i = 0; i < nodeBuildersCount; i++) + { + Type nodeType = nodeBuilders[i].GetType(); - var nodeWithId = node as INodeWithID; - if (nodeWithId != null) - RemoveNodeFromNodesDictionary(nodeWithId, nodeType); - } - } + ITypeSafeList nodes; + if (_nodesDB.TryGetValue(nodeType, out nodes) == true) + nodes.UnorderedRemove(entityID); - void InternalMetaRemove(FasterList nodes) + if (nodes.isQueryiableNode) { - for (int i = 0; i < nodes.Count; i++) - { - var node = nodes[i]; - Type nodeType = node.GetType(); - - RemoveNodeFromEngines(node, nodeType); - RemoveNodeFromMetaDB(node, nodeType); - - var nodeWithId = node as INodeWithID; - if (nodeWithId != null) - RemoveNodeFromNodesDictionary(nodeWithId, nodeType); - } + var node = _nodesDBdic[nodeType].GetIndexedNode(entityID); + + _nodesDBdic[nodeType].Remove(entityID); + + RemoveNodeFromEngines(_nodeEngines, node, nodeType); } + } + } + + void InternalGroupedRemove(FasterList nodeBuilders, int entityID) + { + } - readonly DataStructures.WeakReference _engineRootWeakReference; + void InternalMetaRemove(FasterList nodeBuilders, int entityID) + { + } + + static void RemoveNodeFromEngines(Dictionary> nodeEngines, NodeWithID node, Type nodeType) + { + FasterList 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] as INodeEngine), node); +#else + (enginesForNode[j] as INodeEngine).Remove(node); +#endif + } + } + } void SubmitNodes() { - int metaNodesCount = _metaNodesToAdd.Count; - int nodesCount = _nodesToAdd.Count; - - if (metaNodesCount + nodesCount == 0) return; + _nodesToAdd.Swap(); + _metaNodesToAdd.Swap(); + _groupedNodesToAdd.Swap(); + + bool newNodesHaveBeenAddedWhileIterating = + _metaNodesToAdd.Count > 0 + || _nodesToAdd.Count > 0 + || _groupedNodesToAdd.Count > 0; - bool newNodesHaveBeenAddedWhileIterating; - int startNodes = 0; - int startMetaNodes = 0; int numberOfReenteringLoops = 0; - do + while (newNodesHaveBeenAddedWhileIterating) { - AddNodesToTheDBAndSuitableEngines(_nodesToAdd, _nodeEngines, _nodesDBdic, _nodesDB); - AddNodesToTheDBAndSuitableEngines(_metaNodesToAdd, _nodeEngines, _nodesDBdic, _metaNodesDB); - + if ( _nodesToAdd.Count > 0) + AddNodesToTheDBAndSuitableEngines(_nodesToAdd.current, _nodeEngines, _nodesDBdic, _nodesDB); + + if ( _metaNodesToAdd.Count > 0) + AddNodesToTheDBAndSuitableEngines(_metaNodesToAdd.current, _nodeEngines, _nodesDBdic, _metaNodesDB); + + if (_groupedNodesToAdd.Count > 0) + AddGroupNodesToTheDBAndSuitableEngines(_groupedNodesToAdd.current, _nodeEngines, _nodesDBdic, _groupNodesDB, _nodesDB); + + _nodesToAdd.Clear(); + _metaNodesToAdd.Clear(); + _groupedNodesToAdd.Clear(); + + _nodesToAdd.Swap(); + _metaNodesToAdd.Swap(); + _groupedNodesToAdd.Swap(); + newNodesHaveBeenAddedWhileIterating = - _metaNodesToAdd.Count > metaNodesCount || - _nodesToAdd.Count > nodesCount; - - startNodes = nodesCount; - startMetaNodes = metaNodesCount; + _metaNodesToAdd.Count > 0 + || _nodesToAdd.Count > 0 + || _groupedNodesToAdd.Count > 0; 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++; - - metaNodesCount = _metaNodesToAdd.Count; - nodesCount = _nodesToAdd.Count; - - } while (newNodesHaveBeenAddedWhileIterating); - - _nodesToAdd.Clear(); - _metaNodesToAdd.Clear(); + } } readonly Dictionary> _nodeEngines; @@ -467,25 +513,60 @@ namespace Svelto.ECS readonly Dictionary _nodesDB; readonly Dictionary _metaNodesDB; - readonly Dictionary> _groupNodesDB; + readonly Dictionary> _groupNodesDB; readonly Dictionary _nodesDBdic; - /// - /// Need to think about how to make BuildEntity thread safe as well - /// - readonly Dictionary _nodesToAdd; - readonly Dictionary _metaNodesToAdd; - readonly Dictionary> _groupedNodesToAdd; + readonly DoubleBufferedNodes> _nodesToAdd; + readonly DoubleBufferedNodes> _metaNodesToAdd; + readonly DoubleBufferedNodes>> _groupedNodesToAdd; readonly NodeSubmissionScheduler _scheduler; readonly Type _structNodeEngineType; readonly Type _groupedStructNodesEngineType; readonly Type _activableNodeEngineType; + + readonly SharedStructNodeLists _sharedStructNodeLists; + readonly SharedGroupedStructNodesLists _sharedGroupedStructNodeLists; - readonly Dictionary _implementedInterfaceTypes; + readonly Dictionary _implementedInterfaceTypes; + readonly DataStructures.WeakReference _engineRootWeakReference; - BuildNodeCallbackStruct _callBackStruct; + BuildNodeCallbackStruct _callBackStructForBuiltNodes; + BuildNodeCallbackStruct _callBackStructForBuiltGroupedNodes; + BuildNodeCallbackStruct _callBackStructForBuiltMetaNodes; + + class DoubleBufferedNodes where T : class, IDictionary, new() + { + readonly T _nodesToAddBufferA = new T(); + readonly T _nodesToAddBufferB = new T(); + + public DoubleBufferedNodes() + { + this.other = _nodesToAddBufferA; + this.current = _nodesToAddBufferB; + } + + public T other { get; private set; } + public T current { get; private set; } + + public int Count + { + get { return current.Count; } + } + + public void Clear() + { + current.Clear(); + } + + public void Swap() + { + var toSwap = other; + other = current; + current = toSwap; + } + } } } \ No newline at end of file diff --git a/ECS/EntityDescriptor.cs b/ECS/EntityDescriptor.cs index 6c96c06..6202eac 100644 --- a/ECS/EntityDescriptor.cs +++ b/ECS/EntityDescriptor.cs @@ -8,24 +8,6 @@ namespace Svelto.ECS { public class EntityDescriptor { - protected EntityDescriptor() - {} - - /// - /// if you want to avoid allocation in run-time, you can prebuild - /// EntityDescriptors and use them to build entities at different - /// times - /// - protected EntityDescriptor(INodeBuilder[] nodesToBuild) - { - _nodesToBuild = new FasterList(nodesToBuild); - } - protected EntityDescriptor(INodeBuilder[] nodesToBuild, - params object[] componentsImplementor):this(nodesToBuild) - { - ProcessImplementors(componentsImplementor); - } - public void AddImplementors(params object[] componentsImplementor) { ProcessImplementors(componentsImplementor); @@ -38,7 +20,7 @@ namespace Svelto.ECS internal void BuildGroupedNodes (int entityID, int groupID, - Dictionary> groupNodes, + Dictionary> groupNodesByType, ref BuildNodeCallbackStruct callBackstruct) { for (int index = 0; index < _nodesToBuild.Count; index++) @@ -46,62 +28,68 @@ namespace Svelto.ECS var nodeBuilder = _nodesToBuild[index]; var nodeType = nodeBuilder.GetNodeType(); - Dictionary groupedNodesTyped; + Dictionary groupedNodesTyped; - if (groupNodes.TryGetValue(nodeType, out groupedNodesTyped) == false) + if (groupNodesByType.TryGetValue(groupID, out groupedNodesTyped) == false) { - groupedNodesTyped = new Dictionary(); + groupedNodesTyped = new Dictionary(); - groupNodes.Add(nodeType, groupedNodesTyped); + groupNodesByType.Add(groupID, groupedNodesTyped); }; - - ITypeSafeList nodes; - - var mustAdd = groupedNodesTyped.TryGetValue(groupID, out nodes) == false; - - var node = nodeBuilder.BuildAndAddToList(ref nodes, entityID); - - if (mustAdd) - groupedNodesTyped[groupID] = nodes; - - if (node != null && nodeBuilder.reflects != FillNodeMode.None) - { - node = FillNode(node, nodeBuilder.reflects); - - SetupImplementors(ref callBackstruct, nodes); - } - - /* var groupNode = node as IGroupedNode; - if (groupNode != null) - groupNode.groupID = groupID;*/ + + BuildAndFillNode(entityID, groupedNodesTyped, nodeType, nodeBuilder); } + + SetupImplementors(ref callBackstruct, entityID); } internal void BuildNodes(int entityID, - Dictionary nodesToAdd, + Dictionary nodesByType, ref BuildNodeCallbackStruct callBackstruct) { - for (int index = 0; index < _nodesToBuild.Count; index++) + int count = _nodesToBuild.Count; + + for (int index = 0; index < count; index++) { var nodeBuilder = _nodesToBuild[index]; var nodeType = nodeBuilder.GetNodeType(); + + BuildAndFillNode(entityID, nodesByType, nodeType, nodeBuilder); + } + + SetupImplementors(ref callBackstruct, entityID); + } + + void BuildAndFillNode(int entityID, Dictionary groupedNodesTyped, Type nodeType, INodeBuilder nodeBuilder) + { + ITypeSafeList nodes; - ITypeSafeList nodes; - - var mustAdd = nodesToAdd.TryGetValue(nodeType, out nodes) == false; - - var node = nodeBuilder.BuildAndAddToList(ref nodes, entityID); + var nodesPoolWillBeCreated = groupedNodesTyped.TryGetValue(nodeType, out nodes) == false; + var nodeObjectToFill = nodeBuilder.BuildNodeAndAddToList(ref nodes, entityID); - if (mustAdd) - nodesToAdd[nodeType] = nodes; + if (nodesPoolWillBeCreated) + groupedNodesTyped.Add(nodeType, nodes); - if (node != null && nodeBuilder.reflects != FillNodeMode.None) - { - FillNode(node, nodeBuilder.reflects); - - SetupImplementors(ref callBackstruct, nodes); - } - } + //the semantic of this code must still be improved + //but only classes can be filled, so I am aware + //it's a NodeWithID + if (nodeObjectToFill != null) + FillNode(nodeObjectToFill as NodeWithID); + } + + /// + /// if you want to avoid allocation in run-time, you can prebuild + /// EntityDescriptors and use them to build entities at different + /// times + /// + protected EntityDescriptor(INodeBuilder[] nodesToBuild) + { + _nodesToBuild = new FasterList(nodesToBuild); + } + protected EntityDescriptor(INodeBuilder[] nodesToBuild, + params object[] componentsImplementor):this(nodesToBuild) + { + ProcessImplementors(componentsImplementor); } void ProcessImplementors(object[] implementors) @@ -144,30 +132,41 @@ namespace Svelto.ECS void SetupImplementors( ref BuildNodeCallbackStruct callBackstruct, - ITypeSafeList nodes) + int entityID) { - var RemoveEntity = callBackstruct._internalRemove; - var DisableEntity = callBackstruct._internalDisable; - var EnableEntity = callBackstruct._internalEnable; + var RemoveEntity = callBackstruct.internalRemove; + var DisableEntity = callBackstruct.internalDisable; + var EnableEntity = callBackstruct.internalEnable; - Action removeEntityAction = () => { RemoveEntity(nodes); nodes.Clear(); }; - Action disableEntityAction = () => DisableEntity(nodes); - Action enableEntityAction = () => EnableEntity(nodes); - int removingImplementorsCount = _removingImplementors.Count; - for (int index = 0; index < removingImplementorsCount; index++) - _removingImplementors[index].Target.removeEntity = removeEntityAction; - + if (removingImplementorsCount > 0) + { + Action removeEntityAction = () => RemoveEntity(_nodesToBuild, entityID); + + for (int index = 0; index < removingImplementorsCount; index++) + _removingImplementors[index].Target.removeEntity = removeEntityAction; + } + int disablingImplementorsCount = _disablingImplementors.Count; - for (int index = 0; index < disablingImplementorsCount; index++) - _disablingImplementors[index].Target.disableEntity = disableEntityAction; - + if (disablingImplementorsCount > 0) + { + Action disableEntityAction = () => DisableEntity(_nodesToBuild, entityID); + + for (int index = 0; index < disablingImplementorsCount; index++) + _disablingImplementors[index].Target.disableEntity = disableEntityAction; + } + int enablingImplementorsCount = _enablingImplementors.Count; - for (int index = 0; index < enablingImplementorsCount; index++) - _enablingImplementors[index].Target.enableEntity = enableEntityAction; + if (enablingImplementorsCount > 0) + { + Action enableEntityAction = () => EnableEntity(_nodesToBuild, entityID); + + for (int index = 0; index < enablingImplementorsCount; index++) + _enablingImplementors[index].Target.enableEntity = enableEntityAction; + } } - TNode FillNode(TNode node, FillNodeMode mode) where TNode : INode + void FillNode(TNode node) where TNode : NodeWithID { var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); @@ -180,15 +179,12 @@ namespace Svelto.ECS if (_implementorsByType.TryGetValue(fieldType, out component) == false) { - if (mode == FillNodeMode.Strict) - { Exception e = new Exception(NOT_FOUND_EXCEPTION + field.FieldType.Name + " - Node: " + node.GetType().Name + " - EntityDescriptor " + this); throw e; - } } else field.SetValue(node, component.Target); @@ -205,10 +201,8 @@ namespace Svelto.ECS #endif } - - return node; } - + readonly FasterList> _disablingImplementors = new FasterList>(); readonly FasterList> _removingImplementors = new FasterList>(); readonly FasterList> _enablingImplementors = new FasterList>(); @@ -217,8 +211,8 @@ namespace Svelto.ECS #if DEBUG && !PROFILER readonly Dictionary _implementorCounterByType = new Dictionary(); #endif - readonly FasterList _nodesToBuild; - + readonly FasterList _nodesToBuild; + const string DUPLICATE_IMPLEMENTOR_ERROR = "the same component is implemented with more than one implementor. This is considered an error and MUST be fixed. "; const string NULL_IMPLEMENTOR_ERROR = "Null implementor, are you using a wild GetComponents to fetch it? "; const string NOT_FOUND_EXCEPTION = "Svelto.ECS: Implementor not found for a Node. Implementor Type: "; diff --git a/ECS/IEngine.cs b/ECS/IEngine.cs index 0a4629a..bb4c012 100644 --- a/ECS/IEngine.cs +++ b/ECS/IEngine.cs @@ -1,4 +1,4 @@ -using Svelto.DataStructures; +using Rewired.Utils; using Svelto.ECS.Internal; namespace Svelto.ECS.Internal @@ -15,16 +15,19 @@ namespace Svelto.ECS.Internal public interface IActivableNodeEngine : IEngine { - void Enable(ITypeSafeList nodes); - void Disable(ITypeSafeList nodes); + void Enable(NodeWithID node); + void Disable(NodeWithID node); } public interface INodeEngine : IEngine { - void Add(ITypeSafeList nodes); - void Remove(ITypeSafeList nodes); + void Add(NodeWithID node); + void Remove(NodeWithID node); } +} +namespace Svelto.ECS.Legacy +{ public interface INodesEngine : INodeEngine { System.Type[] AcceptedNodes(); @@ -57,7 +60,10 @@ namespace Svelto.ECS /// usually the ID is the owner of the nodes of that /// group /// - public interface IGroupedStructNodesEngine : IGroupedStructNodesEngine where T:struct, IGroupedNode - { } + public interface IGroupedStructNodesEngine : IGroupedStructNodesEngine where T : struct, IGroupedNode + { + void Add(ref T node); + void Remove(ref T node); + } } diff --git a/ECS/IEngineNodeDB.cs b/ECS/IEngineNodeDB.cs index 3906d79..05a2c6f 100644 --- a/ECS/IEngineNodeDB.cs +++ b/ECS/IEngineNodeDB.cs @@ -4,15 +4,19 @@ namespace Svelto.ECS { public interface IEngineNodeDB { - ReadOnlyDictionary QueryIndexableNodes(); - - bool TryQueryNode(int ID, out T node); - T QueryNode(int ID); FasterReadOnlyList QueryNodes(); - - bool TryQueryMetaNode(int metaEntityID, out T node); - T QueryMetaNode(int metaEntityID); FasterReadOnlyList QueryMetaNodes(); + FasterReadOnlyList QueryGroupedNodes(int group); + + T[] QueryNodesAsArray(out int count) where T:struct; + + ReadOnlyDictionary QueryIndexableNodes() where T:NodeWithID; + + bool TryQueryNode(int ID, out T node) where T:NodeWithID; + T QueryNode(int ID) where T:NodeWithID; + + bool TryQueryMetaNode(int metaEntityID, out T node) where T:NodeWithID; + T QueryMetaNode(int metaEntityID) where T:NodeWithID; } } diff --git a/ECS/INode.cs b/ECS/INode.cs index fc53c55..4876a86 100644 --- a/ECS/INode.cs +++ b/ECS/INode.cs @@ -1,17 +1,19 @@ namespace Svelto.ECS { public interface INode - {} - - public interface IStructNodeWithID : INode { - int ID { get; set; } + int ID { get; } } - + public interface IGroupedNode { int groupID { get; set; } } + + public interface IStructNodeWithID : INode + { + new int ID { get; set; } + } public class NodeWithID: INode { diff --git a/ECS/MultiNodesEngine.cs b/ECS/MultiNodesEngine.cs index 97cb3ac..3559310 100644 --- a/ECS/MultiNodesEngine.cs +++ b/ECS/MultiNodesEngine.cs @@ -3,102 +3,83 @@ using Svelto.ECS.Internal; namespace Svelto.ECS.Internal { - public abstract class MultiNodesEngine where T:class + public abstract class MultiNodesEngine:INodeEngine where T:NodeWithID { - protected abstract void AddNode(T node); - protected abstract void RemoveNode(T node); + protected abstract void Add(T node); + protected abstract void Remove(T node); + + public virtual void Add(NodeWithID node) + { + Add((T) node); + } + + public virtual void Remove(NodeWithID node) + { + Remove((T) node); + } } } namespace Svelto.ECS { - public abstract class MultiNodesEngine : INodesEngine - { - public abstract System.Type[] AcceptedNodes(); - - public abstract void Add(ITypeSafeList nodeWrapper); - public abstract void Remove(ITypeSafeList nodeWrapper); - } - - public abstract class MultiNodesEngine : MultiNodesEngine, - INodeEngine where T:class where U:class + public abstract class MultiNodesEngine : MultiNodesEngine + where T:NodeWithID where U:NodeWithID { - protected abstract void AddNode(U node); - protected abstract void RemoveNode(U node); + protected abstract void Add(U node); + protected abstract void Remove(U node); - public virtual void Add(ITypeSafeList nodes) + public override void Add(NodeWithID node) { - if (nodes is FasterList) + var castedNode = node as U; + if (castedNode != null) { - var strongTypeNodes = (FasterList)nodes; - - for (int i = 0; i < strongTypeNodes.Count; i++) - { - AddNode(strongTypeNodes[i]); - } + Add(castedNode); } else - if (nodes is FasterList) { - var strongTypeNodes = (FasterList)nodes; - - for (int i = 0; i < strongTypeNodes.Count; i++) - { - AddNode(strongTypeNodes[i]); - } + base.Add(node); } } - public virtual void Remove(ITypeSafeList nodeWrapper) + public override void Remove(NodeWithID node) { - /* if (nodeWrapper is NodeWrapper) + if (node is U) { - T node; - nodeWrapper.GetNode(out node); - - RemoveNode(ref node); + Remove((U) node); } else { - U node; - nodeWrapper.GetNode(out node); - - RemoveNode(ref node); - }*/ + base.Remove(node); + } } } - public abstract class MultiNodesEngine : MultiNodesEngine where T: class where U : class + public abstract class MultiNodesEngine : MultiNodesEngine + where T: NodeWithID where U : NodeWithID where V:NodeWithID { - protected abstract void AddNode(V node); - protected abstract void RemoveNode(V node); + protected abstract void Add(V node); + protected abstract void Remove(V node); - public override void Add(ITypeSafeList nodes) + public override void Add(NodeWithID node) { - if (nodes is FasterList) + var castedNode = node as V; + if (castedNode != null) { - var strongTypeNodes = (FasterList)nodes; - - for (int i = 0; i < strongTypeNodes.Count; i++) - { - AddNode(strongTypeNodes[i]); - } + Add(castedNode); } else - base.Add(nodes); + base.Add(node); } - public override void Remove(ITypeSafeList nodeWrapper) + public override void Remove(NodeWithID node) { - /* if (nodeWrapper is V) + var castedNode = node as V; + if (castedNode != null) { - V node; - nodeWrapper.GetNode(out node); - - RemoveNode(ref node); + Remove(castedNode); } else - base.Remove(nodeWrapper);*/ + base.Remove(node); } } } \ No newline at end of file diff --git a/ECS/NodeBuilder.cs b/ECS/NodeBuilder.cs index 17b9c34..70deb96 100644 --- a/ECS/NodeBuilder.cs +++ b/ECS/NodeBuilder.cs @@ -6,21 +6,19 @@ namespace Svelto.ECS { public interface INodeBuilder { - INode BuildAndAddToList(ref ITypeSafeList list, int entityID); + INode BuildNodeAndAddToList(ref ITypeSafeList list, int entityID); Type GetNodeType(); - - FillNodeMode reflects { get; } } public class NodeBuilder : INodeBuilder where NodeType : NodeWithID, new() { - public INode BuildAndAddToList(ref ITypeSafeList list, int entityID) + public INode BuildNodeAndAddToList(ref ITypeSafeList list, int entityID) { if (list == null) - list = new TypeSafeFasterList(); + list = new TypeSafeFasterListForECSForClasses(); - var castedList = list as FasterList; + var castedList = list as TypeSafeFasterListForECSForClasses; var node = NodeWithID.BuildNode(entityID); @@ -29,11 +27,6 @@ namespace Svelto.ECS return node; } - public FillNodeMode reflects - { - get { return FillNodeMode.Strict; } - } - public Type GetNodeType() { return typeof(NodeType); @@ -42,15 +35,15 @@ namespace Svelto.ECS public class StructNodeBuilder : INodeBuilder where NodeType : struct, IStructNodeWithID { - public INode BuildAndAddToList(ref ITypeSafeList list, int entityID) + public INode BuildNodeAndAddToList(ref ITypeSafeList list, int entityID) { var node = default(NodeType); node.ID = entityID; if (list == null) - list = new TypeSafeFasterList(); + list = new TypeSafeFasterListForECSForStructs(); - var castedList = list as FasterList; + var castedList = list as TypeSafeFasterListForECSForStructs; castedList.Add(node); @@ -61,17 +54,5 @@ namespace Svelto.ECS { return typeof(NodeType); } - - public virtual FillNodeMode reflects - { - get { return FillNodeMode.None; } - } - } - - public enum FillNodeMode - { - Strict, - - None } } \ No newline at end of file diff --git a/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs b/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs index d774c2b..0947e8a 100644 --- a/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs +++ b/ECS/Profiler/Editor/EngineProfiler/EngineProfilerInspector.cs @@ -1,6 +1,6 @@ -#if asdUNITY_EDITOR +#if UNITY_EDITOR + using System; -using System.Collections.Generic; using UnityEditor; using UnityEngine; diff --git a/ECS/Profiler/EngineProfiler.cs b/ECS/Profiler/EngineProfiler.cs index c659c87..14ed4c7 100644 --- a/ECS/Profiler/EngineProfiler.cs +++ b/ECS/Profiler/EngineProfiler.cs @@ -1,4 +1,3 @@ -#if asdDEBUG using System; using System.Collections.Generic; using System.Diagnostics; @@ -13,10 +12,9 @@ namespace Svelto.ECS.Profiler { static readonly Stopwatch _stopwatch = new Stopwatch(); - public static void MonitorAddDuration(Action addingFunc, INodeEngine engine, INodeWrapper node) + public static void MonitorAddDuration(Action addingFunc, INodeEngine engine, INode node) { EngineInfo info; - if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); @@ -27,15 +25,14 @@ namespace Svelto.ECS.Profiler } } - public static void MonitorRemoveDuration(Action removeFunc, INodeEngine engine, INodeWrapper node) + public static void MonitorRemoveDuration(Action removeFunc, INodeEngine engine, NodeWithID node) { EngineInfo info; - if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); removeFunc(engine, node); - // engine.Remove(node); + engine.Remove(node); _stopwatch.Reset(); info.AddRemoveDuration(_stopwatch.Elapsed.TotalMilliseconds); @@ -61,4 +58,3 @@ namespace Svelto.ECS.Profiler public static readonly Dictionary engineInfos = new Dictionary(); } } -#endif \ No newline at end of file diff --git a/ECS/Profiler/EngineProfilerBehaviour.cs b/ECS/Profiler/EngineProfilerBehaviour.cs index bb046bb..a350ae7 100644 --- a/ECS/Profiler/EngineProfilerBehaviour.cs +++ b/ECS/Profiler/EngineProfilerBehaviour.cs @@ -1,4 +1,4 @@ -#if asdUNITY_EDITOR +#if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEngine; diff --git a/ECS/SingleNodeEngine.cs b/ECS/SingleNodeEngine.cs index 85ad0d9..82b6727 100644 --- a/ECS/SingleNodeEngine.cs +++ b/ECS/SingleNodeEngine.cs @@ -1,28 +1,17 @@ -using Svelto.DataStructures; using Svelto.ECS.Internal; namespace Svelto.ECS { - public abstract class SingleNodeEngine : INodeEngine where T:class + public abstract class SingleNodeEngine : INodeEngine where T:NodeWithID { - public void Add(ITypeSafeList nodes) + public void Add(NodeWithID node) { - var strongTypeNodes = (FasterList)nodes; - - for (int i = 0; i < strongTypeNodes.Count; i++) - { - Add(strongTypeNodes[i]); //when byref returns will be vailable, this should be passed by reference, not copy! - } + Add((T)node); //when byref returns will be vailable, this should be passed by reference, not copy! } - public void Remove(ITypeSafeList nodes) + public void Remove(NodeWithID node) { - /* - T node; - - nodeWrapper.GetNode(out node); - - Remove(node);*/ + Remove((T)node); } protected abstract void Add(T node); diff --git a/ECS/StructNodes.cs b/ECS/StructNodes.cs index 6a6a60a..0ccaf94 100644 --- a/ECS/StructNodes.cs +++ b/ECS/StructNodes.cs @@ -60,8 +60,8 @@ namespace Svelto.ECS public T[] GetList(int groupID, out int numberOfItems) { var fasterList = (SharedGroupedStructNodesLists.NoVirt.GetList(_container, groupID) as FasterList); - numberOfItems = FasterList.NoVirt.Count(fasterList); - return FasterList.NoVirt.ToArrayFast(fasterList); + + return FasterList.NoVirt.ToArrayFast(fasterList, out numberOfItems); } readonly SharedGroupedStructNodesLists _container; @@ -72,20 +72,20 @@ namespace Svelto.ECS { internal SharedStructNodeLists() { - _collection = new Dictionary(); + _collection = new Dictionary(); } internal static class NoVirt { internal static FasterList GetList(SharedStructNodeLists obj) where T : struct { - ITypeSafeList list; + IFasterList list; if (obj._collection.TryGetValue(typeof(T), out list)) { return list as FasterList; } - list = new TypeSafeFasterList(); + list = new FasterList(); obj._collection.Add(typeof(T), list); @@ -93,42 +93,42 @@ namespace Svelto.ECS } } - readonly Dictionary _collection; + readonly Dictionary _collection; } public class SharedGroupedStructNodesLists { internal SharedGroupedStructNodesLists() { - _collection = new Dictionary>(); + _collection = new Dictionary>(); } internal static class NoVirt { - internal static ITypeSafeList GetList(SharedGroupedStructNodesLists list, int groupID) where T : struct + internal static IFasterList GetList(SharedGroupedStructNodesLists list, int groupID) where T : struct { - Dictionary dic = GetGroup(list); - ITypeSafeList localList; + Dictionary dic = GetGroup(list); + IFasterList localList; if (dic.TryGetValue(groupID, out localList)) return localList; - localList = new TypeSafeFasterList(); + localList = new FasterList(); dic.Add(groupID, localList); return localList; } - internal static Dictionary GetGroup(SharedGroupedStructNodesLists list) where T : struct + internal static Dictionary GetGroup(SharedGroupedStructNodesLists list) where T : struct { - Dictionary dic; + Dictionary dic; if (list._collection.TryGetValue(typeof(T), out dic)) { return dic; } - dic = new Dictionary(); + dic = new Dictionary(); list._collection.Add(typeof(T), dic); @@ -136,6 +136,6 @@ namespace Svelto.ECS } } - readonly Dictionary> _collection; + readonly Dictionary> _collection; } } \ No newline at end of file