您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

297 行
11 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/core/utils/thread_pool.h>
  4. #include <ecs/core/utils/counter_blocker.h>
  5. #include <ecs/core/utils/ordered_vector.h>
  6. #include <ecs/core/component/manager.h>
  7. #include "./context.fwd.h"
  8. #define ecs_context_proxy_func(self, name) \
  9. template<typename... T_args> \
  10. inline decltype(auto) name(T_args&&... args) \
  11. noexcept(noexcept(std::declval<self&>() \
  12. ._##name(std::forward<T_args>(args)...))) \
  13. { return this->_##name(std::forward<T_args>(args)...); }
  14. namespace ecs {
  15. namespace context {
  16. namespace detail
  17. {
  18. /**
  19. * the base ecs context implementation
  20. *
  21. * @tparam T_settings settings type the environment is configured with
  22. */
  23. template<typename T_settings>
  24. struct base_t
  25. {
  26. public:
  27. using settings_type = T_settings;
  28. protected:
  29. using context_type = ::ecs::context::type<settings_type>;
  30. using component_manager_type = core::component::manager<settings_type>;
  31. using storage_meta_data_type = typename component_manager_type::storage_meta_data_type;
  32. using entity_storage_type = decltype((settings_type { }).entity_storage()(settings_type { }, hana::type_c<storage_meta_data_type>));
  33. using entity_handle_type = typename entity_storage_type::entity_handle_type;
  34. using system_storage_type = decltype((settings_type { }).system_storage()(settings_type { }, hana::type_c<entity_handle_type>));
  35. using scheduler_type = decltype((settings_type { }).scheduler()(settings_type { }, std::declval<context_type&>()));
  36. public:
  37. using handle_type = entity_handle_type;
  38. private:
  39. using handle_set_type = core::utils::ordered_vector<handle_type>;
  40. protected:
  41. context_type& _context; //!< reference to its own child class
  42. component_manager_type _components; //!< object to store and manage all components
  43. entity_storage_type _entities; //!< object to store and manage all entities
  44. system_storage_type _systems; //!< object to store and manage all systems
  45. scheduler_type _scheduler; //!< scheduler to execute the systems
  46. core::utils::thread_pool _thread_pool; //!< thread pool to execute tasks parallel
  47. handle_set_type _to_match; //!< handles of entities that were created in the last tick
  48. handle_set_type _to_kill; //!< handles of entities that were destroyed in the last tick
  49. public:
  50. /**
  51. * constructor
  52. *
  53. * @param p_context reference to its own child class
  54. */
  55. inline base_t(context_type& p_context);
  56. protected: /* misc */
  57. /**
  58. * execute the given function in the thread pool
  59. *
  60. * @tparam T_func type of the function to execute
  61. *
  62. * @param func function to execute
  63. * @param thread_id ID of the thread to add task to
  64. */
  65. template<typename T_func>
  66. inline void _post_in_thread_pool(T_func&& func, ssize_t thread_id = -1);
  67. protected: /* entity */
  68. /**
  69. * create a new entity
  70. *
  71. * @tparam T_args argument types to pass to the entity manager
  72. *
  73. * @param args arguments to pass to the entity manager
  74. *
  75. * @return handle of the created entity
  76. */
  77. template<typename... T_args>
  78. inline decltype(auto) _create_entity(T_args&&... args);
  79. /**
  80. * kill an entity
  81. *
  82. * @param handle handle of the entity to kill
  83. */
  84. inline void _kill_entity(const handle_type& handle);
  85. /**
  86. * check if an entity is alive
  87. *
  88. * @param handle handle of the entity to check
  89. *
  90. * @retval TRUE if the entity is alive
  91. * @retval FALSE if the entity is not alive
  92. */
  93. inline bool _is_alive(const handle_type& handle) const;
  94. /**
  95. * destroy the passed entity
  96. *
  97. * @param handle handle of the entity to destroy
  98. */
  99. inline void _destroy_entity(const handle_type& handle);
  100. /**
  101. * get the meta data for the passed entity
  102. *
  103. * @param handle handle to get meta data for
  104. *
  105. * @return meta data of the passed entity
  106. */
  107. inline const auto& _entity_meta_data(const handle_type& handle);
  108. protected: /* component */
  109. /**
  110. * add a new component to an entity
  111. *
  112. * @tparam T_component_tag component tag type to add to the entity
  113. *
  114. * @param handle handle of the entity
  115. * @param ct tag of component to add
  116. *
  117. * @return reference to the created component
  118. */
  119. template<typename T_component_tag>
  120. inline decltype(auto) _add_component(const handle_type& handle, T_component_tag ct);
  121. /**
  122. * check if an entity has an specific component
  123. *
  124. * @tparam T_component_tag component tag type to check for
  125. *
  126. * @param handle handle of entity to check
  127. * @param ct component tag to check
  128. *
  129. * @retval TRUE if given entity has the requested component
  130. * @retval FALSE if the given entity does not have the requested component
  131. */
  132. template<typename T_component_tag>
  133. inline decltype(auto) _has_component(const handle_type& handle, T_component_tag ct);
  134. /**
  135. * get a reference to the requested component
  136. *
  137. * @tparam T_component_tag component tag type to get
  138. *
  139. * @param handle handle of the entity to get the component for
  140. * @param ct component tag to get the component for
  141. *
  142. * @return reference to the requested component
  143. */
  144. template<typename T_component_tag>
  145. inline decltype(auto) _get_component(const handle_type& handle, T_component_tag ct);
  146. /**
  147. * remove a component from an entity
  148. *
  149. * @tparam T_component_tag component tag type to remove
  150. *
  151. * @param handle handle of the entity to remove component at
  152. * @param ct component tag to remove component for
  153. */
  154. template<typename T_component_tag>
  155. inline void _remove_component(const handle_type& handle, T_component_tag ct);
  156. protected: /* systems */
  157. /**
  158. * get the reference to a system instance by the system tag
  159. *
  160. * @tparam T_system_tag system tag type to get system instance for
  161. *
  162. * @param st system tag to get system instance for
  163. *
  164. * @return reference to the system instance
  165. */
  166. template<typename T_system_tag>
  167. inline auto& _instance_by_tag(T_system_tag st);
  168. /**
  169. * get the reference to a system instance by it's index
  170. *
  171. * @tparam T_index index type to get system instance for
  172. *
  173. * @param index index to get system instance for
  174. *
  175. * @return reference to the system instance
  176. */
  177. template<typename T_index>
  178. inline auto& _instance_by_index(T_index index);
  179. /**
  180. * get the reference of a system by the system tag
  181. *
  182. * @tparam T_system_tag system tag type to get system for
  183. *
  184. * @param st system tag to get system for
  185. *
  186. * @return reference to the system
  187. */
  188. template<typename T_system_tag>
  189. inline auto& _system_by_tag(T_system_tag st);
  190. /**
  191. * get the reference to a system by it's index
  192. *
  193. * @tparam T_index index type to get system for
  194. *
  195. * @param index index to get system for
  196. *
  197. * @return reference to the system
  198. */
  199. template<typename T_index>
  200. inline auto& _system_by_index(T_index index);
  201. /**
  202. * execute the given function for each system sequential
  203. *
  204. * @tparam T_func function type to execute for each system
  205. *
  206. * @param func function to execute for each system
  207. */
  208. template<typename T_func>
  209. inline void _for_systems_sequential(T_func&& func);
  210. /**
  211. * execute the given function for each system in parallel
  212. *
  213. * @tparam T_func function type to execute for each system
  214. *
  215. * @param func function to execute for each system
  216. */
  217. template<typename T_func>
  218. inline void _for_systems_parallel(T_func&& func);
  219. /**
  220. * Execute function for each system, depending on the refresh_parallelism option of the settings object
  221. * it will be executed sequentially or in parallel.
  222. *
  223. * @tparam T_func function type to execute for each system
  224. *
  225. * @param func function to execute for each system
  226. */
  227. template<typename T_func>
  228. inline void _for_systems_dispatch(T_func&& func);
  229. protected: /* execute */
  230. /**
  231. * run the scheduler for the passed system tags (if no tags are passed, all systems are executed)
  232. *
  233. * @tparam T_system_tags system tag types to execute scheduler for
  234. *
  235. * @param sts system tags to execute scheduler for
  236. *
  237. * @return functor to run system execution adapter with
  238. */
  239. template<typename... T_system_tags>
  240. inline decltype(auto) _execute_systems(T_system_tags&&... sts) noexcept;
  241. private: /* static */
  242. /**
  243. * create a list of system tags from the passed tags (if no tag is passed all system tags are returned)
  244. *
  245. * @tparam T_system_tags system tag types to create list for
  246. *
  247. * @param tags system tags to create list for
  248. *
  249. * @return list of system tags
  250. */
  251. template<typename... T_system_tags>
  252. static constexpr decltype(auto) make_system_tag_list(T_system_tags&&... tags) noexcept;
  253. };
  254. }
  255. } }