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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using System;
  2. using System.Reflection;
  3. using Svelto.DataStructures;
  4. #if NETFX_CORE
  5. using BindingFlags = System.Reflection.BindingFlags;
  6. #endif
  7. namespace Svelto.ECS
  8. {
  9. public class EntityDescriptor
  10. {
  11. protected EntityDescriptor(INodeBuilder[] nodesToBuild, params object[] componentsImplementor)
  12. {
  13. _implementors = componentsImplementor;
  14. _nodesToBuild = nodesToBuild;
  15. }
  16. public void AddImplementors(params object[] componentsImplementor)
  17. {
  18. var implementors = new object[componentsImplementor.Length + _implementors.Length];
  19. Array.Copy(_implementors, implementors, _implementors.Length);
  20. Array.Copy(componentsImplementor, 0, implementors, _implementors.Length, componentsImplementor.Length);
  21. _implementors = implementors;
  22. }
  23. public virtual FasterList<INode> BuildNodes(int ID, Action<INode> removeAction)
  24. {
  25. var nodes = new FasterList<INode>();
  26. for (int index = 0; index < _nodesToBuild.Length; index++)
  27. {
  28. var nodeBuilder = _nodesToBuild[index];
  29. var node = FillNode(nodeBuilder.Build(ID), () =>
  30. {
  31. for (int i = 0; i < nodes.Count; i++)
  32. removeAction(nodes[i]);
  33. nodes.Clear();
  34. }
  35. );
  36. nodes.Add (node);
  37. }
  38. return nodes;
  39. }
  40. TNode FillNode<TNode>(TNode node, Action removeAction) where TNode: INode
  41. {
  42. var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
  43. for (int i = fields.Length - 1; i >=0 ; --i)
  44. {
  45. var field = fields[i];
  46. Type fieldType = field.FieldType;
  47. object component = null;
  48. for (int j = 0; j < _implementors.Length; j++)
  49. {
  50. var implementor = _implementors[j];
  51. if (implementor != null && fieldType.IsAssignableFrom(implementor.GetType()))
  52. {
  53. component = implementor;
  54. if (fieldType.IsAssignableFrom(typeof(IRemoveEntityComponent)))
  55. (component as IRemoveEntityComponent).removeEntity = removeAction;
  56. break;
  57. }
  58. }
  59. if (component == null)
  60. {
  61. Exception e = new Exception("Svelto.ECS: Implementor not found for a Node. " +
  62. "Implementor Type: " + field.FieldType.Name + " - Node: " + node.GetType().Name + " - EntityDescriptor " + this);
  63. throw e;
  64. }
  65. field.SetValue(node, component);
  66. }
  67. return node;
  68. }
  69. object[] _implementors;
  70. readonly INodeBuilder[] _nodesToBuild;
  71. }
  72. public interface INodeBuilder
  73. {
  74. NodeWithID Build(int ID);
  75. }
  76. public class NodeBuilder<NodeType> : INodeBuilder where NodeType:NodeWithID, new()
  77. {
  78. public NodeWithID Build(int ID)
  79. {
  80. NodeWithID node = NodeWithID.BuildNode<NodeType>(ID);
  81. return (NodeType)node;
  82. }
  83. }
  84. }