Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EntityDescriptor.cs 6.4KB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using Svelto.DataStructures;
  5. #if NETFX_CORE
  6. using BindingFlags = System.Reflection.BindingFlags;
  7. #endif
  8. namespace Svelto.ECS
  9. {
  10. public class EntityDescriptor
  11. {
  12. protected EntityDescriptor()
  13. {
  14. }
  15. protected EntityDescriptor(INodeBuilder[] nodesToBuild)
  16. {
  17. _nodesToBuild = new FasterList<INodeBuilder>(nodesToBuild);
  18. }
  19. protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor):this(nodesToBuild)
  20. {
  21. ProcessImplementors(componentsImplementor);
  22. }
  23. public void AddImplementors(params object[] componentsImplementor)
  24. {
  25. ProcessImplementors(componentsImplementor);
  26. }
  27. void ProcessImplementors(object[] implementors)
  28. {
  29. for (int index = 0; index < implementors.Length; index++)
  30. {
  31. var implementor = implementors[index];
  32. if (implementor == null) continue;
  33. if (implementor is IRemoveEntityComponent)
  34. _removingImplementors.Add(implementor as IRemoveEntityComponent);
  35. if (implementor is IDisableEntityComponent)
  36. _disablingImplementors.Add(implementor as IDisableEntityComponent);
  37. if (implementor is IEnableEntityComponent)
  38. _enablingImplementors.Add(implementor as IEnableEntityComponent);
  39. var interfaces = implementor.GetType().GetInterfaces();
  40. for (int iindex = 0; iindex < interfaces.Length; iindex++)
  41. {
  42. _implementorsByType[interfaces[iindex]] = implementor;
  43. }
  44. }
  45. }
  46. public void AddNodes(params INodeBuilder[] nodesWithID)
  47. {
  48. _nodesToBuild.AddRange(nodesWithID);
  49. }
  50. public virtual FasterList<INode> BuildNodes(int ID)
  51. {
  52. var nodes = new FasterList<INode>();
  53. for (int index = 0; index < _nodesToBuild.Count; index++)
  54. {
  55. var nodeBuilder = _nodesToBuild[index];
  56. var node = nodeBuilder.Build(ID);
  57. if (nodeBuilder.reflects != FillNodeMode.None)
  58. node = FillNode(node, nodeBuilder.reflects);
  59. nodes.Add(node);
  60. }
  61. return nodes;
  62. }
  63. internal FasterList<INode> BuildNodes(int ID,
  64. Action<FasterList<INode>> removeEntity,
  65. Action<FasterList<INode>> enableEntity,
  66. Action<FasterList<INode>> disableEntity)
  67. {
  68. var nodes = BuildNodes(ID);
  69. SetupImplementors(removeEntity, enableEntity, disableEntity, nodes);
  70. return nodes;
  71. }
  72. void SetupImplementors(
  73. Action<FasterList<INode>> removeEntity,
  74. Action<FasterList<INode>> enableEntity,
  75. Action<FasterList<INode>> disableEntity,
  76. FasterList<INode> nodes)
  77. {
  78. Action removeEntityAction = () => { removeEntity(nodes); nodes.Clear(); };
  79. Action disableEntityAction = () => disableEntity(nodes);
  80. Action enableEntityAction = () => enableEntity(nodes);
  81. for (int index = 0; index < _removingImplementors.Count; index++)
  82. _removingImplementors[index].removeEntity = removeEntityAction;
  83. for (int index = 0; index < _disablingImplementors.Count; index++)
  84. _disablingImplementors[index].disableEntity = disableEntityAction;
  85. for (int index = 0; index < _enablingImplementors.Count; index++)
  86. _enablingImplementors[index].enableEntity = enableEntityAction;
  87. }
  88. TNode FillNode<TNode>(TNode node, FillNodeMode mode) where TNode : INode
  89. {
  90. var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
  91. for (int i = fields.Length - 1; i >= 0; --i)
  92. {
  93. var field = fields[i];
  94. Type fieldType = field.FieldType;
  95. object component;
  96. if ((_implementorsByType.TryGetValue(fieldType, out component)) == false)
  97. {
  98. if (mode == FillNodeMode.Strict)
  99. {
  100. Exception e =
  101. new Exception("Svelto.ECS: Implementor not found for a Node. " + "Implementor Type: " +
  102. field.FieldType.Name + " - Node: " + node.GetType().Name +
  103. " - EntityDescriptor " + this);
  104. throw e;
  105. }
  106. }
  107. else
  108. field.SetValue(node, component);
  109. }
  110. return node;
  111. }
  112. readonly FasterList<IDisableEntityComponent> _disablingImplementors = new FasterList<IDisableEntityComponent>();
  113. readonly FasterList<IRemoveEntityComponent> _removingImplementors = new FasterList<IRemoveEntityComponent>();
  114. readonly FasterList<IEnableEntityComponent> _enablingImplementors = new FasterList<IEnableEntityComponent>();
  115. readonly Dictionary<Type, object> _implementorsByType = new Dictionary<Type, object>();
  116. readonly FasterList<INodeBuilder> _nodesToBuild;
  117. }
  118. public interface INodeBuilder
  119. {
  120. INode Build(int ID);
  121. FillNodeMode reflects { get; }
  122. }
  123. public class NodeBuilder<NodeType> : INodeBuilder where NodeType : NodeWithID, new()
  124. {
  125. public INode Build(int ID)
  126. {
  127. NodeWithID node = NodeWithID.BuildNode<NodeType>(ID);
  128. return (NodeType)node;
  129. }
  130. public FillNodeMode reflects { get { return FillNodeMode.Strict; } }
  131. }
  132. public class StructNodeBuilder<NodeType> : INodeBuilder
  133. where NodeType : struct, IStructNodeWithID
  134. {
  135. public INode Build(int ID)
  136. {
  137. var shortID = (short)ID;
  138. IStructNodeWithID node = default(NodeType);
  139. node.ID = shortID;
  140. return node;
  141. }
  142. public virtual FillNodeMode reflects { get { return FillNodeMode.Relaxed; } }
  143. }
  144. public class FastStructNodeBuilder<NodeType> : StructNodeBuilder<NodeType>
  145. where NodeType : struct, IStructNodeWithID
  146. {
  147. public override FillNodeMode reflects { get { return FillNodeMode.None; } }
  148. }
  149. public enum FillNodeMode
  150. {
  151. Strict,
  152. Relaxed,
  153. None
  154. }
  155. }