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.7KB

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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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)
  33. Utility.Console.LogWarning(
  34. "Null implementor, are you using a wild GetComponents<Monobehaviour> to fetch it?");
  35. else
  36. {
  37. if (implementor is IRemoveEntityComponent)
  38. _removingImplementors.Add(implementor as IRemoveEntityComponent);
  39. if (implementor is IDisableEntityComponent)
  40. _disablingImplementors.Add(implementor as IDisableEntityComponent);
  41. if (implementor is IEnableEntityComponent)
  42. _enablingImplementors.Add(implementor as IEnableEntityComponent);
  43. var interfaces = implementor.GetType().GetInterfaces();
  44. for (int iindex = 0; iindex < interfaces.Length; iindex++)
  45. {
  46. _implementorsByType[interfaces[iindex]] = implementor;
  47. }
  48. }
  49. }
  50. }
  51. public void AddNodes(params INodeBuilder[] nodesWithID)
  52. {
  53. _nodesToBuild.AddRange(nodesWithID);
  54. }
  55. public virtual FasterList<INode> BuildNodes(int ID)
  56. {
  57. var nodes = new FasterList<INode>();
  58. for (int index = 0; index < _nodesToBuild.Count; index++)
  59. {
  60. var nodeBuilder = _nodesToBuild[index];
  61. var node = nodeBuilder.Build(ID);
  62. if (nodeBuilder.reflects != FillNodeMode.None)
  63. node = FillNode(node, nodeBuilder.reflects);
  64. nodes.Add(node);
  65. }
  66. return nodes;
  67. }
  68. internal FasterList<INode> BuildNodes(int ID,
  69. Action<FasterList<INode>> removeEntity,
  70. Action<FasterList<INode>> enableEntity,
  71. Action<FasterList<INode>> disableEntity)
  72. {
  73. var nodes = BuildNodes(ID);
  74. SetupImplementors(removeEntity, enableEntity, disableEntity, nodes);
  75. return nodes;
  76. }
  77. void SetupImplementors(
  78. Action<FasterList<INode>> removeEntity,
  79. Action<FasterList<INode>> enableEntity,
  80. Action<FasterList<INode>> disableEntity,
  81. FasterList<INode> nodes)
  82. {
  83. Action removeEntityAction = () => { removeEntity(nodes); nodes.Clear(); };
  84. Action disableEntityAction = () => disableEntity(nodes);
  85. Action enableEntityAction = () => enableEntity(nodes);
  86. for (int index = 0; index < _removingImplementors.Count; index++)
  87. _removingImplementors[index].removeEntity = removeEntityAction;
  88. for (int index = 0; index < _disablingImplementors.Count; index++)
  89. _disablingImplementors[index].disableEntity = disableEntityAction;
  90. for (int index = 0; index < _enablingImplementors.Count; index++)
  91. _enablingImplementors[index].enableEntity = enableEntityAction;
  92. }
  93. TNode FillNode<TNode>(TNode node, FillNodeMode mode) where TNode : INode
  94. {
  95. var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
  96. for (int i = fields.Length - 1; i >= 0; --i)
  97. {
  98. var field = fields[i];
  99. Type fieldType = field.FieldType;
  100. object component;
  101. if ((_implementorsByType.TryGetValue(fieldType, out component)) == false)
  102. {
  103. if (mode == FillNodeMode.Strict)
  104. {
  105. Exception e =
  106. new Exception("Svelto.ECS: Implementor not found for a Node. " + "Implementor Type: " +
  107. field.FieldType.Name + " - Node: " + node.GetType().Name +
  108. " - EntityDescriptor " + this);
  109. throw e;
  110. }
  111. }
  112. else
  113. field.SetValue(node, component);
  114. }
  115. return node;
  116. }
  117. readonly FasterList<IDisableEntityComponent> _disablingImplementors = new FasterList<IDisableEntityComponent>();
  118. readonly FasterList<IRemoveEntityComponent> _removingImplementors = new FasterList<IRemoveEntityComponent>();
  119. readonly FasterList<IEnableEntityComponent> _enablingImplementors = new FasterList<IEnableEntityComponent>();
  120. readonly Dictionary<Type, object> _implementorsByType = new Dictionary<Type, object>();
  121. readonly FasterList<INodeBuilder> _nodesToBuild;
  122. }
  123. public interface INodeBuilder
  124. {
  125. INode Build(int ID);
  126. FillNodeMode reflects { get; }
  127. }
  128. public class NodeBuilder<NodeType> : INodeBuilder where NodeType : NodeWithID, new()
  129. {
  130. public INode Build(int ID)
  131. {
  132. NodeWithID node = NodeWithID.BuildNode<NodeType>(ID);
  133. return (NodeType)node;
  134. }
  135. public FillNodeMode reflects { get { return FillNodeMode.Strict; } }
  136. }
  137. public class StructNodeBuilder<NodeType> : INodeBuilder
  138. where NodeType : struct, IStructNodeWithID
  139. {
  140. public INode Build(int ID)
  141. {
  142. var shortID = (short)ID;
  143. IStructNodeWithID node = default(NodeType);
  144. node.ID = shortID;
  145. return node;
  146. }
  147. public virtual FillNodeMode reflects { get { return FillNodeMode.Relaxed; } }
  148. }
  149. public class FastStructNodeBuilder<NodeType> : StructNodeBuilder<NodeType>
  150. where NodeType : struct, IStructNodeWithID
  151. {
  152. public override FillNodeMode reflects { get { return FillNodeMode.None; } }
  153. }
  154. public enum FillNodeMode
  155. {
  156. Strict,
  157. Relaxed,
  158. None
  159. }
  160. }