|
- #pragma once
-
- #include <ecs/context/base.h>
-
- namespace ecs {
- namespace context {
- namespace detail {
-
- /* constructor */
-
- template<typename T_settings>
- inline base_t<T_settings>
- ::base_t(context_type& p_context)
- : _context (p_context)
- , _components ()
- , _entities ((settings_type { }).entity_storage()(settings_type { }, hana::type_c<storage_meta_data_type>))
- , _systems ((settings_type { }).system_storage()(settings_type { }, hana::type_c<entity_handle_type>))
- , _scheduler ((settings_type { }).scheduler()(settings_type { }, p_context))
- , _thread_pool (std::thread::hardware_concurrency() != 0
- ? std::thread::hardware_concurrency()
- : 8 )
- { }
-
- /* misc */
-
- template<typename T_settings>
- template<typename T_func>
- inline void base_t<T_settings>
- ::_post_in_thread_pool(T_func&& func, ssize_t thread_id)
- {
- _thread_pool.post(std::forward<T_func>(func), thread_id);
- }
-
- /* entity */
-
- template<typename T_settings>
- template<typename... T_args>
- inline decltype(auto) base_t<T_settings>
- ::_create_entity(T_args&&... args)
- {
- auto handle = _entities.claim(std::forward<T_args>(args)...);
- _to_match.insert(handle);
- return handle;
- }
-
- template<typename T_settings>
- inline void base_t<T_settings>
- ::_kill_entity(const handle_type& handle)
- {
- _to_kill.insert(handle);
- }
-
- template<typename T_settings>
- inline bool base_t<T_settings>
- ::_is_alive(const handle_type& handle) const
- {
- return _entities.is_valid(handle);
- }
-
- template<typename T_settings>
- inline void base_t<T_settings>
- ::_destroy_entity(const handle_type& handle)
- {
- _entities.reclaim(handle);
- }
-
- template<typename T_settings>
- inline const auto& base_t<T_settings>
- ::_entity_meta_data(const handle_type& handle)
- {
- return _entities.meta_data(handle);
- }
-
- /* components */
-
- template<typename T_settings>
- template<typename T_component_tag>
- inline decltype(auto) base_t<T_settings>
- ::_add_component(const handle_type& handle, T_component_tag ct)
- {
- _to_match.insert(handle);
- auto& meta = _entities.meta_data(handle);
- auto& cmd = meta.storage_meta_data();
- auto& c = _components.add(ct, handle, cmd);
- auto& bitset = meta.bitset();
- bitset.set_component(ct, true);
- return c;
- }
-
- template<typename T_settings>
- template<typename T_component_tag>
- inline decltype(auto) base_t<T_settings>
- ::_has_component(const handle_type& handle, T_component_tag ct)
- {
- auto& meta = _entities.meta_data(handle);
- auto& bitset = meta.bitset();
- return bitset.has_component(ct);
- }
-
- template<typename T_settings>
- template<typename T_component_tag>
- inline decltype(auto) base_t<T_settings>
- ::_get_component(const handle_type& handle, T_component_tag ct)
- {
- auto& meta = _entities.meta_data(handle);
- auto& bitset = meta.bitset();
- auto& cmd = meta.storage_meta_data();
- if (!bitset.has_component(ct))
- throw std::invalid_argument("entity does not contain the requested component");
- return _components.get(ct, handle, cmd);
- }
-
- template<typename T_settings>
- template<typename T_component_tag>
- inline void base_t<T_settings>
- ::_remove_component(const handle_type& handle, T_component_tag ct)
- {
- _to_match.emplace_back(handle);
- auto& meta = _entities.meta_data(handle);
- auto& bitset = meta.bitset();
- bitset.set_component(ct, false);
- }
-
- /* systems */
-
- template<typename T_settings>
- template<typename T_system_tag>
- inline auto& base_t<T_settings>
- ::_instance_by_tag(T_system_tag st)
- {
- return _systems.instance_by_tag(st);
- }
-
- template<typename T_settings>
- template<typename T_index>
- inline auto& base_t<T_settings>
- ::_instance_by_index(T_index index)
- {
- return _systems.instance_by_index(T_index { });
- }
-
- template<typename T_settings>
- template<typename T_system_tag>
- inline auto& base_t<T_settings>
- ::_system_by_tag(T_system_tag st)
- {
- return _systems.instance_by_tag(st).system();
- }
-
- template<typename T_settings>
- template<typename T_index>
- inline auto& base_t<T_settings>
- ::_system_by_index(T_index)
- {
- return _systems.instance_by_index(T_index { }).system();
- }
-
- template<typename T_settings>
- template<typename T_func>
- inline void base_t<T_settings>
- ::_for_systems_sequential(T_func&& func)
- {
- _systems.for_each(std::forward<T_func>(func));
- }
-
- template<typename T_settings>
- template<typename T_func>
- inline void base_t<T_settings>
- ::_for_systems_parallel(T_func&& func)
- {
- core::utils::counter_blocker counter(_systems.size());
- counter.execute_and_wait([this, &counter, func = std::forward<T_func>(func)]{
- _systems.for_each([this, &counter, &func](auto& instance){
- this->_post_in_thread_pool([&counter, &func, &instance]{
- ecs_make_scope_guard([&counter](){
- counter.decrement();
- });
- func(instance);
- });
- });
- });
- }
-
- template<typename T_settings>
- template<typename T_func>
- inline void base_t<T_settings>
- ::_for_systems_dispatch(T_func&& func)
- {
- hana::eval_if(
- (settings_type { }).refresh_parallelism(),
- [this, func=std::forward<T_func>(func)](auto _) {
- _(this)->_for_systems_parallel(func);
- },
- [this, func=std::forward<T_func>(func)](auto _) {
- _(this)->_for_systems_sequential(func);
- });
- }
-
- template<typename T_settings>
- template<typename... T_system_tags>
- inline decltype(auto) base_t<T_settings>
- ::_execute_systems(T_system_tags&&... sts) noexcept
- {
- auto tags = make_system_tag_list(std::forward<T_system_tags>(sts)...);
- return [tags, this](auto&&... fns) {
- auto os = hana::overload_linearly(std::forward<decltype(fns)>(fns)...);
- this->_scheduler.execute(tags, os);
- };
- }
-
- /* static */
-
- template<typename T_settings>
- template<typename... T_system_tags>
- constexpr decltype(auto) base_t<T_settings>
- ::make_system_tag_list(T_system_tags&&... tags) noexcept
- {
- auto list = core::mp::list::make(std::forward<T_system_tags>(tags)...);
- return hana::if_(
- hana::equal(hana::size(list), hana::size_c<0>),
- (settings_type { }).system_signatures().tags(),
- list);
- }
-
- } } }
|