|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/core/utils/thread_pool.h>
- #include <ecs/core/utils/counter_blocker.h>
- #include <ecs/core/utils/ordered_vector.h>
- #include <ecs/core/component/manager.h>
-
- #include "./context.fwd.h"
-
- #define ecs_context_proxy_func(self, name) \
- template<typename... T_args> \
- inline decltype(auto) name(T_args&&... args) \
- noexcept(noexcept(std::declval<self&>() \
- ._##name(std::forward<T_args>(args)...))) \
- { return this->_##name(std::forward<T_args>(args)...); }
-
- namespace ecs {
- namespace context {
-
- namespace detail
- {
-
- /**
- * the base ecs context implementation
- *
- * @tparam T_settings settings type the environment is configured with
- */
- template<typename T_settings>
- struct base_t
- {
- public:
- using settings_type = T_settings;
-
- protected:
- using context_type = ::ecs::context::type<settings_type>;
- using component_manager_type = core::component::manager<settings_type>;
- using storage_meta_data_type = typename component_manager_type::storage_meta_data_type;
- using entity_storage_type = decltype((settings_type { }).entity_storage()(settings_type { }, hana::type_c<storage_meta_data_type>));
- using entity_handle_type = typename entity_storage_type::entity_handle_type;
- using system_storage_type = decltype((settings_type { }).system_storage()(settings_type { }, hana::type_c<entity_handle_type>));
- using scheduler_type = decltype((settings_type { }).scheduler()(settings_type { }, std::declval<context_type&>()));
-
- public:
- using handle_type = entity_handle_type;
-
- private:
- using handle_set_type = core::utils::ordered_vector<handle_type>;
-
- protected:
- context_type& _context; //!< reference to its own child class
-
- component_manager_type _components; //!< object to store and manage all components
- entity_storage_type _entities; //!< object to store and manage all entities
- system_storage_type _systems; //!< object to store and manage all systems
- scheduler_type _scheduler; //!< scheduler to execute the systems
-
- core::utils::thread_pool _thread_pool; //!< thread pool to execute tasks parallel
-
- handle_set_type _to_match; //!< handles of entities that were created in the last tick
- handle_set_type _to_kill; //!< handles of entities that were destroyed in the last tick
-
- public:
-
- /**
- * constructor
- *
- * @param p_context reference to its own child class
- */
- inline base_t(context_type& p_context);
-
- protected: /* misc */
-
- /**
- * execute the given function in the thread pool
- *
- * @tparam T_func type of the function to execute
- *
- * @param func function to execute
- * @param thread_id ID of the thread to add task to
- */
- template<typename T_func>
- inline void _post_in_thread_pool(T_func&& func, ssize_t thread_id = -1);
-
- protected: /* entity */
-
- /**
- * create a new entity
- *
- * @tparam T_args argument types to pass to the entity manager
- *
- * @param args arguments to pass to the entity manager
- *
- * @return handle of the created entity
- */
- template<typename... T_args>
- inline decltype(auto) _create_entity(T_args&&... args);
-
- /**
- * kill an entity
- *
- * @param handle handle of the entity to kill
- */
- inline void _kill_entity(const handle_type& handle);
-
- /**
- * check if an entity is alive
- *
- * @param handle handle of the entity to check
- *
- * @retval TRUE if the entity is alive
- * @retval FALSE if the entity is not alive
- */
- inline bool _is_alive(const handle_type& handle) const;
-
- /**
- * destroy the passed entity
- *
- * @param handle handle of the entity to destroy
- */
- inline void _destroy_entity(const handle_type& handle);
-
- /**
- * get the meta data for the passed entity
- *
- * @param handle handle to get meta data for
- *
- * @return meta data of the passed entity
- */
- inline const auto& _entity_meta_data(const handle_type& handle);
-
- protected: /* component */
-
- /**
- * add a new component to an entity
- *
- * @tparam T_component_tag component tag type to add to the entity
- *
- * @param handle handle of the entity
- * @param ct tag of component to add
- *
- * @return reference to the created component
- */
- template<typename T_component_tag>
- inline decltype(auto) _add_component(const handle_type& handle, T_component_tag ct);
-
- /**
- * check if an entity has an specific component
- *
- * @tparam T_component_tag component tag type to check for
- *
- * @param handle handle of entity to check
- * @param ct component tag to check
- *
- * @retval TRUE if given entity has the requested component
- * @retval FALSE if the given entity does not have the requested component
- */
- template<typename T_component_tag>
- inline decltype(auto) _has_component(const handle_type& handle, T_component_tag ct);
-
- /**
- * get a reference to the requested component
- *
- * @tparam T_component_tag component tag type to get
- *
- * @param handle handle of the entity to get the component for
- * @param ct component tag to get the component for
- *
- * @return reference to the requested component
- */
- template<typename T_component_tag>
- inline decltype(auto) _get_component(const handle_type& handle, T_component_tag ct);
-
- /**
- * remove a component from an entity
- *
- * @tparam T_component_tag component tag type to remove
- *
- * @param handle handle of the entity to remove component at
- * @param ct component tag to remove component for
- */
- template<typename T_component_tag>
- inline void _remove_component(const handle_type& handle, T_component_tag ct);
-
- protected: /* systems */
-
- /**
- * get the reference to a system instance by the system tag
- *
- * @tparam T_system_tag system tag type to get system instance for
- *
- * @param st system tag to get system instance for
- *
- * @return reference to the system instance
- */
- template<typename T_system_tag>
- inline auto& _instance_by_tag(T_system_tag st);
-
- /**
- * get the reference to a system instance by it's index
- *
- * @tparam T_index index type to get system instance for
- *
- * @param index index to get system instance for
- *
- * @return reference to the system instance
- */
- template<typename T_index>
- inline auto& _instance_by_index(T_index index);
-
- /**
- * get the reference of a system by the system tag
- *
- * @tparam T_system_tag system tag type to get system for
- *
- * @param st system tag to get system for
- *
- * @return reference to the system
- */
- template<typename T_system_tag>
- inline auto& _system_by_tag(T_system_tag st);
-
- /**
- * get the reference to a system by it's index
- *
- * @tparam T_index index type to get system for
- *
- * @param index index to get system for
- *
- * @return reference to the system
- */
- template<typename T_index>
- inline auto& _system_by_index(T_index index);
-
- /**
- * execute the given function for each system sequential
- *
- * @tparam T_func function type to execute for each system
- *
- * @param func function to execute for each system
- */
- template<typename T_func>
- inline void _for_systems_sequential(T_func&& func);
-
- /**
- * execute the given function for each system in parallel
- *
- * @tparam T_func function type to execute for each system
- *
- * @param func function to execute for each system
- */
- template<typename T_func>
- inline void _for_systems_parallel(T_func&& func);
-
- /**
- * Execute function for each system, depending on the refresh_parallelism option of the settings object
- * it will be executed sequentially or in parallel.
- *
- * @tparam T_func function type to execute for each system
- *
- * @param func function to execute for each system
- */
- template<typename T_func>
- inline void _for_systems_dispatch(T_func&& func);
-
- protected: /* execute */
-
- /**
- * run the scheduler for the passed system tags (if no tags are passed, all systems are executed)
- *
- * @tparam T_system_tags system tag types to execute scheduler for
- *
- * @param sts system tags to execute scheduler for
- *
- * @return functor to run system execution adapter with
- */
- template<typename... T_system_tags>
- inline decltype(auto) _execute_systems(T_system_tags&&... sts) noexcept;
-
- private: /* static */
-
- /**
- * create a list of system tags from the passed tags (if no tag is passed all system tags are returned)
- *
- * @tparam T_system_tags system tag types to create list for
- *
- * @param tags system tags to create list for
- *
- * @return list of system tags
- */
- template<typename... T_system_tags>
- static constexpr decltype(auto) make_system_tag_list(T_system_tags&&... tags) noexcept;
-
- };
- }
-
- } }
|