|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/signature/system.h>
- #include <ecs/core/utils/bitset.h>
- #include <ecs/core/utils/fixed_function.h>
-
- beg_namespace_ecs_core_system
- {
-
- template<typename T_settings>
- struct deferred_function_vector
- {
- private:
- using deferred_proxy_type = int;
- using function_type = utils::fixed_function<void(deferred_proxy_type&)>;
- using function_vector_type = std::vector<function_type>;
-
- private:
- function_vector_type _functions;
-
- public:
- inline void clear() noexcept
- { _functions.clear(); }
-
- template<typename T_func>
- inline void add(T_func&& func)
- { _functions.emplace_back(std::forward<T_func>(func)); }
-
- template<typename T_proxy>
- inline void execute_all(T_proxy& proxy) const
- {
- for (auto& f : _functions)
- {
- f(proxy);
- }
- }
- };
-
- template<typename T_settings, typename T_system_signature, typename T_entity_handle>
- struct instance
- {
- static_assert(decltype(signature::system::is_valid(mp::unwrap_t<T_system_signature> { })) { });
-
- public:
- using settings_type = T_settings;
- using system_signature_type = T_system_signature;
- using this_type = instance<settings_type, system_signature_type, T_entity_handle>;
- using system_tag_type = mp::decay_t<decltype(core::mp::unwrap(system_signature_type { }).tag())>;
- using system_type = mp::unwrap_t<system_tag_type>;
- using output_type = mp::unwrap_t<mp::decay_t<decltype(mp::unwrap(system_signature_type { }).output())>>;
-
- private:
- using signature_list_type = decltype((settings_type { }).system_signatures());
- using bitset_type = utils::bitset<settings_type>;
- using entity_handle_type = T_entity_handle;
- using executor_type = decltype(mp::unwrap(system_signature_type { }).parallelism()());
- using entity_handle_set_type = std::set<entity_handle_type>;
-
- struct state
- : public output_type
- {
- private:
- using deferred_function_type = deferred_function_vector<settings_type>;
- using entity_handles_type = std::vector<entity_handle_type>;
-
- public:
- deferred_function_type deferred_functions;
- entity_handles_type to_kill;
-
- public:
- inline void clear()
- {
- deferred_functions.clear();
- to_kill.clear();
- }
-
- inline decltype(auto) as_output()
- { return static_cast<output_type&>(*this); }
- };
-
- using state_vector = std::vector<state>;
-
- private:
- bitset_type _bitset;
- system_type _system;
- executor_type _executor;
- entity_handle_set_type _subscribed;
- state_vector _states;
-
- public:
- instance()
- : _bitset ()
- , _system ()
- , _executor (mp::unwrap(system_signature_type { }).parallelism()())
- , _subscribed()
- , _states ()
- { }
-
- instance(const instance&) = delete;
- instance& operator=(const instance&) = delete;
-
- instance(instance&&) = default;
- instance& operator=(instance&&) = default;
-
- private:
- inline void clear_and_prepare(size_t size)
- {
- _states.resize(size);
- for (auto& state : _states)
- {
- state.clear();
- }
- }
-
- public:
- template<typename T_context, typename T_func>
- inline void prepare_and_wait_subtasks(T_context& context, size_t n, T_func& func)
- {
- assert(n > 0);
- clear_and_prepare(n);
- utils::counter_blocker b(n-1);
-
- auto run_in_seperate_thread = [this, &context, &b](auto& f) {
- return [this, &b, &context, &f](auto&&... xs) {
- context.post_in_thread_pool([&f, &b, xs...]() {
- ecs_make_scope_guard([&b](){
- b.decrement_and_notify_one();
- });
- f(xs...);
- });
- };
- };
-
- b.execute_and_wait_until_zero([&func, &run_in_seperate_thread]{
- func(run_in_seperate_thread);
- });
- }
-
- public: /* bitset */
- inline const auto& bitset() const noexcept
- { return _bitset; }
-
- public: /* system */
- inline auto& system() noexcept
- { return _system; }
-
- inline const auto& system() const noexcept
- { return _system; }
-
- constexpr decltype(auto) system_id() const noexcept
- { return (signature_list_type { }).template id_by_type<system_type>(); }
-
- public: /* subscribed */
- inline auto subscribed_count() const noexcept
- { return _subscribed.size(); }
-
- inline auto& subscribed() noexcept
- { return _subscribed; }
-
- inline bool is_subscribed(const entity_handle_type& handle) const
- { return (_subscribed.find(handle) != _subscribed.end()); }
-
- inline void subscribe(const entity_handle_type& handle)
- { _subscribed.emplace(handle); }
-
- inline void unsubscribe(const entity_handle_type& handle)
- { _subscribed.erase(handle); }
-
- public: /* states */
- template<typename T_func>
- inline void for_states(T_func&& func)
- {
- for (auto& state : _states)
- {
- func(state);
- }
- }
-
- template<typename T_func>
- inline void for_outputs(T_func&& func)
- {
- for (auto& state : _states)
- {
- func(state.as_output());
- }
- }
-
- template<typename T_proxy>
- inline void execute_deferred_functions(T_proxy& proxy)
- {
- for (auto& state : _states)
- {
- state.deferred_functions.execute_all(proxy);
- }
- }
-
- };
-
- }
- end_namespace_ecs_core_system
|