Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

201 строка
6.2 KiB

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