Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

221 wiersze
7.2 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/signature/system.h>
  4. #include <ecs/context/defer_proxy.h>
  5. #include <ecs/core/utils/bitset.h>
  6. #include <ecs/core/utils/fixed_function.h>
  7. #include <ecs/core/utils/ordered_vector.h>
  8. namespace ecs {
  9. namespace core {
  10. namespace system {
  11. template<typename T_settings>
  12. struct deferred_function_vector
  13. {
  14. private:
  15. using settings_type = T_settings;
  16. using deferred_proxy_type = context::detail::defer_proxy_t<settings_type>;
  17. using function_type = utils::fixed_function<void(deferred_proxy_type&)>;
  18. using function_vector_type = std::vector<function_type>;
  19. private:
  20. function_vector_type _functions;
  21. public:
  22. inline void clear() noexcept
  23. { _functions.clear(); }
  24. template<typename T_func>
  25. inline void add(T_func&& func)
  26. { _functions.emplace_back(std::forward<T_func>(func)); }
  27. template<typename T_proxy>
  28. inline void execute_all(T_proxy& proxy) const
  29. {
  30. for (auto& f : _functions)
  31. {
  32. f(proxy);
  33. }
  34. }
  35. };
  36. template<typename T_settings>
  37. constexpr decltype(auto) get_scheduler_instance_meta_data_type(T_settings&&) noexcept
  38. {
  39. using settings_type = T_settings;
  40. using context_type = ::ecs::context::type<settings_type>;
  41. using scheduler_type = decltype((settings_type { }).scheduler()(settings_type { }, std::declval<context_type&>()));
  42. using instance_meta_data_type = typename scheduler_type::instance_meta_data_type;
  43. return hana::type_c<instance_meta_data_type>;
  44. }
  45. template<typename T_settings, typename T_system_signature, typename T_entity_handle>
  46. struct instance
  47. : private mp::unwrap_t<mp::decay_t<decltype(get_scheduler_instance_meta_data_type(T_settings { }))>>
  48. {
  49. static_assert(decltype(signature::system::is_valid(mp::unwrap_t<T_system_signature> { })) { });
  50. public:
  51. using settings_type = T_settings;
  52. using system_signature_type = T_system_signature;
  53. using this_type = instance<settings_type, system_signature_type, T_entity_handle>;
  54. using system_tag_type = mp::decay_t<decltype(core::mp::unwrap(system_signature_type { }).tag())>;
  55. using system_type = mp::unwrap_t<system_tag_type>;
  56. using output_type = mp::unwrap_t<mp::decay_t<decltype(mp::unwrap(system_signature_type { }).output())>>;
  57. using scheduler_meta_data_type = mp::unwrap_t<mp::decay_t<decltype(get_scheduler_instance_meta_data_type(T_settings { }))>>;
  58. private:
  59. using signature_list_type = decltype((settings_type { }).system_signatures());
  60. using bitset_type = utils::bitset<settings_type>;
  61. using entity_handle_type = T_entity_handle;
  62. using executor_type = decltype(mp::unwrap(system_signature_type { }).parallelism()());
  63. using entity_handle_set_type = utils::ordered_vector<entity_handle_type>;
  64. struct state_t
  65. : public output_type
  66. {
  67. private:
  68. using deferred_function_type = deferred_function_vector<settings_type>;
  69. using entity_handles_type = std::vector<entity_handle_type>;
  70. public:
  71. deferred_function_type deferred_functions;
  72. entity_handles_type to_kill;
  73. public:
  74. inline void clear()
  75. {
  76. deferred_functions.clear();
  77. to_kill.clear();
  78. }
  79. inline decltype(auto) as_output()
  80. { return static_cast<output_type&>(*this); }
  81. };
  82. using state_vector = std::vector<state_t>;
  83. private:
  84. bitset_type _bitset;
  85. system_type _system;
  86. executor_type _executor;
  87. entity_handle_set_type _subscribed;
  88. state_vector _states;
  89. public:
  90. instance()
  91. : _bitset (bitset_type::from_system_signature(mp::unwrap(system_signature_type { })))
  92. , _system ()
  93. , _executor (mp::unwrap(system_signature_type { }).parallelism()())
  94. , _subscribed()
  95. , _states ()
  96. { }
  97. instance(const instance&) = delete;
  98. instance& operator=(const instance&) = delete;
  99. instance(instance&&) = default;
  100. instance& operator=(instance&&) = default;
  101. private:
  102. inline void clear_and_prepare(size_t size)
  103. {
  104. _states.resize(size);
  105. for (auto& state : _states)
  106. {
  107. state.clear();
  108. }
  109. }
  110. public:
  111. inline void prepare_states(size_t n)
  112. {
  113. assert(n > 0);
  114. clear_and_prepare(n);
  115. }
  116. template<typename T_context, typename T_func>
  117. inline void execute(T_context& context, T_func&& func)
  118. { _executor(context, *this, std::forward<T_func>(func)); }
  119. public: /* misc */
  120. constexpr decltype(auto) scheduler_meta_data() noexcept
  121. { return static_cast<scheduler_meta_data_type&>(*this); }
  122. constexpr decltype(auto) signature() const noexcept
  123. { return mp::unwrap(system_signature_type { }); }
  124. inline const auto& bitset() const noexcept
  125. { return _bitset; }
  126. public: /* system */
  127. inline auto& system() noexcept
  128. { return _system; }
  129. inline const auto& system() const noexcept
  130. { return _system; }
  131. constexpr decltype(auto) system_id() const noexcept
  132. { return (signature_list_type { }).template id_by_type<system_type>(); }
  133. public: /* subscribed */
  134. inline auto subscribed_count() const noexcept
  135. { return _subscribed.size(); }
  136. inline auto& subscribed() noexcept
  137. { return _subscribed; }
  138. inline bool is_subscribed(const entity_handle_type& handle) const
  139. { return (_subscribed.find(handle) != _subscribed.end()); }
  140. inline bool subscribe(const entity_handle_type& handle)
  141. { return _subscribed.insert(handle).second; }
  142. inline bool unsubscribe(const entity_handle_type& handle)
  143. {
  144. auto it = _subscribed.find(handle);
  145. if (it != _subscribed.end())
  146. {
  147. _subscribed.erase(it);
  148. return true;
  149. }
  150. else
  151. {
  152. return false;
  153. }
  154. }
  155. public: /* states */
  156. template<typename T_func>
  157. inline void for_states(T_func&& func)
  158. {
  159. for (auto& state : _states)
  160. {
  161. func(state);
  162. }
  163. }
  164. template<typename T_func>
  165. inline void for_outputs(T_func&& func)
  166. {
  167. for (auto& state : _states)
  168. {
  169. func(state.as_output());
  170. }
  171. }
  172. template<typename T_proxy>
  173. inline void execute_deferred_functions(T_proxy& proxy)
  174. {
  175. for (auto& state : _states)
  176. {
  177. state.deferred_functions.execute_all(proxy);
  178. }
  179. }
  180. };
  181. } } }