Components.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef CORE_COMPONENTS_H
  2. #define CORE_COMPONENTS_H
  3. #include "core/HashMap.h"
  4. #include "core/List.h"
  5. LIST(size_t, Size)
  6. typedef size_t Entity;
  7. #define COMPONENTS(T, N) \
  8. typedef struct { \
  9. CoreHashMap entityToIndex; \
  10. ListSize indexToEntity; \
  11. List##N components; \
  12. } Components; \
  13. \
  14. typedef struct { \
  15. Entity entity; \
  16. T* component; \
  17. } ComponentNode; \
  18. \
  19. typedef struct { \
  20. const Entity* indexToEntity; \
  21. const Entity* indexToEntityEnd; \
  22. T* component; \
  23. T* componentEnd; \
  24. ComponentNode node; \
  25. } ComponentIterator; \
  26. \
  27. void initComponents(Components* c); \
  28. void destroyComponents(Components* c); \
  29. T* getOrAddComponent(Components* c, Entity e); \
  30. T* searchComponent(Components* c, Entity e); \
  31. bool removeComponent(Components* c, Entity e); \
  32. void initComponentIterator(ComponentIterator* ci, Components* c); \
  33. bool hasNextComponentNode(ComponentIterator* ci); \
  34. ComponentNode* nextComponentNode(ComponentIterator* ci); \
  35. T* getComponentsStart(Components* c); \
  36. T* getComponentsEnd(Components* c);
  37. #define COMPONENTS_SOURCE(T, N) \
  38. void initComponents(Components* c) { \
  39. coreInitHashMap(&c->entityToIndex, sizeof(Entity), sizeof(size_t)); \
  40. initListSize(&c->indexToEntity); \
  41. initList##N(&c->components); \
  42. } \
  43. \
  44. void destroyComponents(Components* c) { \
  45. coreDestroyHashMap(&c->entityToIndex); \
  46. destroyListSize(&c->indexToEntity); \
  47. destroyList##N(&c->components); \
  48. } \
  49. \
  50. T* getOrAddComponent(Components* c, Entity e) { \
  51. void* component = searchComponent(c, e); \
  52. if(component != nullptr) { \
  53. return component; \
  54. } \
  55. size_t index = c->components.length; \
  56. corePutHashMapPair(&c->entityToIndex, &e, &index); \
  57. addListDataSize(&c->indexToEntity, e); \
  58. return addEmptyListData##N(&c->components); \
  59. } \
  60. \
  61. T* searchComponent(Components* c, Entity e) { \
  62. size_t* index = coreSearchHashMapKey(&c->entityToIndex, &e); \
  63. if(index == nullptr) { \
  64. return nullptr; \
  65. } \
  66. return getListIndex##N(&c->components, *index); \
  67. } \
  68. \
  69. bool removeComponent(Components* c, Entity e) { \
  70. size_t* indexP = coreSearchHashMapKey(&c->entityToIndex, &e); \
  71. if(indexP == nullptr) { \
  72. return false; \
  73. } \
  74. size_t lastIndex = c->components.length - 1; \
  75. size_t index = *indexP; \
  76. coreRemoveHashMapKey(&c->entityToIndex, &e); \
  77. removeListIndexBySwap##N(&c->components, index); \
  78. if(index == lastIndex) { \
  79. removeListIndexBySwapSize(&c->indexToEntity, index); \
  80. return true; \
  81. } \
  82. Entity other = *getListIndexSize(&c->indexToEntity, lastIndex); \
  83. removeListIndexBySwapSize(&c->indexToEntity, index); \
  84. corePutHashMapPair(&c->entityToIndex, &other, &index); \
  85. return true; \
  86. } \
  87. \
  88. void initComponentIterator(ComponentIterator* ci, Components* c) { \
  89. ci->indexToEntity = getListStartSize(&c->indexToEntity); \
  90. ci->indexToEntityEnd = getListEndSize(&c->indexToEntity); \
  91. ci->component = getListStart##N(&c->components); \
  92. ci->componentEnd = getListEnd##N(&c->components); \
  93. ci->node = (ComponentNode){0}; \
  94. } \
  95. \
  96. bool hasNextComponentNode(ComponentIterator* ci) { \
  97. return ci->indexToEntity != ci->indexToEntityEnd; \
  98. } \
  99. \
  100. ComponentNode* nextComponentNode(ComponentIterator* ci) { \
  101. ci->node.component = ci->component; \
  102. ci->node.entity = *ci->indexToEntity; \
  103. ci->indexToEntity++; \
  104. ci->component++; \
  105. return &ci->node; \
  106. } \
  107. \
  108. T* getComponentsStart(Components* c) { \
  109. return getListStart##N(&c->components); \
  110. } \
  111. \
  112. T* getComponentsEnd(Components* c) { \
  113. return getListEnd##N(&c->components); \
  114. }
  115. #endif