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.

95 lines
2.8KB

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