|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/signature/system.h>
- #include <ecs/context/defer_proxy.h>
- #include <ecs/core/utils/bitset.h>
- #include <ecs/core/utils/fixed_function.h>
- #include <ecs/core/utils/ordered_vector.h>
-
- namespace ecs {
- namespace core {
- namespace system {
-
- template<typename T_settings>
- struct deferred_function_vector
- {
- private:
- using settings_type = T_settings;
- using deferred_proxy_type = context::detail::defer_proxy_t<settings_type>;
- 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>
- constexpr decltype(auto) get_scheduler_instance_meta_data_type(T_settings&&) noexcept
- {
- using settings_type = T_settings;
- using context_type = ::ecs::context::type<settings_type>;
- using scheduler_type = decltype((settings_type { }).scheduler()(settings_type { }, std::declval<context_type&>()));
- using instance_meta_data_type = typename scheduler_type::instance_meta_data_type;
-
- return hana::type_c<instance_meta_data_type>;
- }
-
- template<typename T_settings, typename T_system_signature, typename T_entity_handle>
- struct instance
- : private mp::unwrap_t<mp::decay_t<decltype(get_scheduler_instance_meta_data_type(T_settings { }))>>
- {
- 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())>>;
- using scheduler_meta_data_type = mp::unwrap_t<mp::decay_t<decltype(get_scheduler_instance_meta_data_type(T_settings { }))>>;
-
- 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 = utils::ordered_vector<entity_handle_type>;
-
- struct state_t
- : 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_t>;
-
- private:
- bitset_type _bitset;
- system_type _system;
- executor_type _executor;
- entity_handle_set_type _subscribed;
- state_vector _states;
-
- public:
- instance()
- : _bitset (bitset_type::from_system_signature(mp::unwrap(system_signature_type { })))
- , _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:
- inline void prepare_states(size_t n)
- {
- assert(n > 0);
- clear_and_prepare(n);
- }
-
- template<typename T_context, typename T_func>
- inline void execute(T_context& context, T_func&& func)
- { _executor(context, *this, std::forward<T_func>(func)); }
-
- public: /* misc */
- constexpr decltype(auto) scheduler_meta_data() noexcept
- { return static_cast<scheduler_meta_data_type&>(*this); }
-
- constexpr decltype(auto) signature() const noexcept
- { return mp::unwrap(system_signature_type { }); }
-
- 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 bool subscribe(const entity_handle_type& handle)
- { return _subscribed.insert(handle).second; }
-
- inline bool unsubscribe(const entity_handle_type& handle)
- {
- auto it = _subscribed.find(handle);
- if (it != _subscribed.end())
- {
- _subscribed.erase(it);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- 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);
- }
- }
-
- };
-
- } } }
|