From 97f7c8224dbadbc6d35c50c9765483095f8ae31b Mon Sep 17 00:00:00 2001 From: bergmann Date: Tue, 3 Jul 2018 14:48:25 +0200 Subject: [PATCH] * implemented part of the system code --- include/ecs/core/entity/storage/base.h | 2 +- include/ecs/core/system.h | 1 + include/ecs/core/system/instance.h | 181 +++++++++++++++++- include/ecs/core/system/parallelism.h | 4 + .../parallelism/composer/fixed_threshold.h | 2 +- .../core/system/parallelism/strategy/none.h | 2 +- .../parallelism/strategy/split_evenly.h | 4 +- include/ecs/core/utils/bitset.h | 2 +- .../parallelism/composer/fixed_threshold.h | 2 +- .../composer/none_below_threshold.h | 2 +- include/ecs/signature/system/signature.h | 23 ++- include/ecs/signature_list/system.h | 18 +- 12 files changed, 223 insertions(+), 20 deletions(-) create mode 100644 include/ecs/core/system/parallelism.h diff --git a/include/ecs/core/entity/storage/base.h b/include/ecs/core/entity/storage/base.h index 5862834..e620bfa 100644 --- a/include/ecs/core/entity/storage/base.h +++ b/include/ecs/core/entity/storage/base.h @@ -135,7 +135,7 @@ beg_namespace_ecs_core_entity_storage auto index = handle.index(); return _container.at(index); } - + }; } diff --git a/include/ecs/core/system.h b/include/ecs/core/system.h index c95efc0..485d51a 100644 --- a/include/ecs/core/system.h +++ b/include/ecs/core/system.h @@ -1,4 +1,5 @@ #pragma once #include "./system/instance.h" +#include "./system/parallelism.h" #include "./system/storage.h" \ No newline at end of file diff --git a/include/ecs/core/system/instance.h b/include/ecs/core/system/instance.h index 6a8b57a..ae4fa8a 100644 --- a/include/ecs/core/system/instance.h +++ b/include/ecs/core/system/instance.h @@ -3,37 +3,198 @@ #include #include #include +#include beg_namespace_ecs_core_system { + template + struct deferred_function_vector + { + private: + using deferred_proxy_type = int; + using function_type = utils::fixed_function; + using function_vector_type = std::vector; + + private: + function_vector_type _functions; + + public: + inline void clear() noexcept + { _functions.clear(); } + + template + inline void add(T_func&& func) + { _functions.emplace_back(std::forward(func)); } + + template + inline void execute_all(T_proxy& proxy) const + { + for (auto& f : _functions) + { + f(proxy); + } + } + }; + template struct instance { static_assert(decltype(signature::system::is_valid(mp::unwrap_t { })) { }); public: - using settings_type = T_settings; - using system_signature_type = T_system_signature; - using this_type = instance; - using system_tag_type = mp::decay_t; - using system_type = mp::unwrap_t; + using settings_type = T_settings; + using system_signature_type = T_system_signature; + using this_type = instance; + using system_tag_type = mp::decay_t; + using system_type = mp::unwrap_t; + using output_type = mp::unwrap_t>; private: - using bitset_type = utils::bitset; - using entity_handle_type = T_entity_handle; + using signature_list_type = decltype((settings_type { }).system_signatures()); + using bitset_type = utils::bitset; + using entity_handle_type = T_entity_handle; + using executor_type = decltype(mp::unwrap(system_signature_type { }).parallelism()()); + using entity_handle_set_type = std::set; + + struct state + : public output_type + { + private: + using deferred_function_type = deferred_function_vector; + using entity_handles_type = std::vector; + + 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(*this); } + }; + + using state_vector = std::vector; private: - bitset_type _bitset; - system_type _system; - std::set _subscribed; + 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 + 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(); } + + 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 + inline void for_states(T_func&& func) + { + for (auto& state : _states) + { + func(state); + } + } + + template + inline void for_outputs(T_func&& func) + { + for (auto& state : _states) + { + func(state.as_output()); + } + } + + template + inline void execute_deferred_functions(T_proxy& proxy) + { + for (auto& state : _states) + { + state.deferred_functions.execute_all(proxy); + } + } + }; } diff --git a/include/ecs/core/system/parallelism.h b/include/ecs/core/system/parallelism.h new file mode 100644 index 0000000..d1d32bf --- /dev/null +++ b/include/ecs/core/system/parallelism.h @@ -0,0 +1,4 @@ +#pragma once + +#include "./parallelism/composer.h" +#include "./parallelism/strategy.h" \ No newline at end of file diff --git a/include/ecs/core/system/parallelism/composer/fixed_threshold.h b/include/ecs/core/system/parallelism/composer/fixed_threshold.h index bed71dc..a1b764e 100644 --- a/include/ecs/core/system/parallelism/composer/fixed_threshold.h +++ b/include/ecs/core/system/parallelism/composer/fixed_threshold.h @@ -6,7 +6,7 @@ beg_namespace_ecs_core_parallelism { template - struct fixed_threshold + struct fixed_threshold { using parameters_type = T_parameters; using strategy_lower_type = typename parameters_type::strategy_lower_type; diff --git a/include/ecs/core/system/parallelism/strategy/none.h b/include/ecs/core/system/parallelism/strategy/none.h index 9951009..29f2974 100644 --- a/include/ecs/core/system/parallelism/strategy/none.h +++ b/include/ecs/core/system/parallelism/strategy/none.h @@ -5,7 +5,7 @@ beg_namespace_ecs_core_parallelism { - struct none + struct none { template inline void operator()(T_instance& instance, T_context& context, T_func&& func) const diff --git a/include/ecs/core/system/parallelism/strategy/split_evenly.h b/include/ecs/core/system/parallelism/strategy/split_evenly.h index 47008e0..c584f38 100644 --- a/include/ecs/core/system/parallelism/strategy/split_evenly.h +++ b/include/ecs/core/system/parallelism/strategy/split_evenly.h @@ -6,7 +6,7 @@ beg_namespace_ecs_core_parallelism { template - struct split_evenly + struct split_evenly { using parameters_type = T_parameters; @@ -14,7 +14,7 @@ beg_namespace_ecs_core_parallelism inline void operator()(T_context& context, T_instance& instance, T_func&& func) const { // auto split_count = parameters_type::get_split_count(); - // TODO + // TODO } }; diff --git a/include/ecs/core/utils/bitset.h b/include/ecs/core/utils/bitset.h index 83f6904..42d3bdf 100644 --- a/include/ecs/core/utils/bitset.h +++ b/include/ecs/core/utils/bitset.h @@ -14,7 +14,7 @@ beg_namespace_ecs_core_utils static constexpr decltype(auto) csl() noexcept { return (T_settings { }).component_signatures(); } - static constexpr decltype(auto) all_components() noexcept + static constexpr decltype(auto) all_components() noexcept { return csl().all_components(); } public: diff --git a/include/ecs/signature/system/parallelism/composer/fixed_threshold.h b/include/ecs/signature/system/parallelism/composer/fixed_threshold.h index 4268277..4f836eb 100644 --- a/include/ecs/signature/system/parallelism/composer/fixed_threshold.h +++ b/include/ecs/signature/system/parallelism/composer/fixed_threshold.h @@ -25,7 +25,7 @@ beg_namespace_ecs_signature_system_parallelism { return ::ecs::core::system::parallelism::fixed_threshold { }; } }; - struct fixed_threshold_t + struct fixed_threshold_t { template constexpr decltype(auto) operator()(T_threshold, T_lower_strategy, T_greater_strategy) const noexcept diff --git a/include/ecs/signature/system/parallelism/composer/none_below_threshold.h b/include/ecs/signature/system/parallelism/composer/none_below_threshold.h index 5a929f8..04e1e6b 100644 --- a/include/ecs/signature/system/parallelism/composer/none_below_threshold.h +++ b/include/ecs/signature/system/parallelism/composer/none_below_threshold.h @@ -13,7 +13,7 @@ beg_namespace_ecs_signature_system_parallelism struct none_below_threshold_t { template - constexpr decltype(auto) operator()(T_threshold th, T_strategy s) const noexcept + constexpr decltype(auto) operator()(T_threshold th, T_strategy s) const noexcept { return fixed_threshold(th, none, s); } }; } diff --git a/include/ecs/signature/system/signature.h b/include/ecs/signature/system/signature.h index d22d2ee..ce00c21 100644 --- a/include/ecs/signature/system/signature.h +++ b/include/ecs/signature/system/signature.h @@ -38,10 +38,31 @@ beg_namespace_ecs_signature_system return impl_type { }; } - public: + template + constexpr decltype(auto) get(const T_key& key) const noexcept + { return T_options { }.at(key); } + + public: /* misc */ constexpr decltype(auto) tag() const noexcept { return T_system_tag { }; } + public: /* getter */ + constexpr decltype(auto) parallelism() const noexcept + { return get(keys::parallelism); } + + constexpr decltype(auto) dependencies() const noexcept + { return get(keys::dependencies); } + + constexpr decltype(auto) read() const noexcept + { return get(keys::read_components); } + + constexpr decltype(auto) write() const noexcept + { return get(keys::write_components); } + + constexpr decltype(auto) output() const noexcept + { return get(keys::output); } + + public: /* setter */ template constexpr decltype(auto) parallelism(T_parallelism parallelism) const noexcept { return change(keys::parallelism, parallelism); } diff --git a/include/ecs/signature_list/system.h b/include/ecs/signature_list/system.h index a470ea3..28b00e8 100644 --- a/include/ecs/signature_list/system.h +++ b/include/ecs/signature_list/system.h @@ -12,11 +12,14 @@ beg_namespace_ecs_signature_list_system template struct signature_list_t { + public: core::mp::list::type items; + public: /* misc */ constexpr decltype(auto) size() const noexcept { return hana::size(items); } + public: /* get */ template constexpr decltype(auto) get_by_tag(T_system_tag st) const noexcept { @@ -44,6 +47,19 @@ beg_namespace_ecs_signature_list_system template constexpr decltype(auto) get_by_index(T_index index) const noexcept { return hana::at(items, index); } + + public: /* id */ + template + constexpr decltype(auto) id_by_signature(T_system_signature ssig) const noexcept + { return core::mp::list::index_of(items, ssig); } + + template + constexpr decltype(auto) id_by_type() const noexcept + { return id_by_signature(get_by_type()); } + + template + constexpr decltype(auto) id_by_tag(T_system_tag st) const noexcept + { return id_by_signature(signature_by_tag(st)); } }; struct make_t @@ -55,7 +71,7 @@ beg_namespace_ecs_signature_list_system static_assert( decltype(signature::system::is_valid(sss...)) { }, "system::signature_list::make() needs a list of system signatures"); - return signature_list_t...> { }; + return signature_list_t>...> { }; } };