1#ifndef LIBSBX_CORE_MODULE_HPP_
2#define LIBSBX_CORE_MODULE_HPP_
5#include <unordered_set>
6#include <unordered_map>
13#include <libsbx/utility/noncopyable.hpp>
17template<
typename Derived,
typename Base>
18concept derived_from = std::is_base_of_v<Base, Derived>;
35 enum class stage : std::uint8_t {
43 template<
typename... Types>
45 auto get()
const noexcept -> std::unordered_set<std::type_index> {
46 auto types = std::unordered_set<std::type_index>{};
47 (types.insert(std::type_index{
typeid(Types)}), ...);
53 virtual ~module_base() =
default;
54 virtual auto update() ->
void = 0;
57 struct module_factory {
58 module_manager::stage stage{};
59 std::unordered_set<std::type_index> dependencies{};
60 std::function<module_base*()> create{};
61 std::function<void(module_base*)> destroy{};
64 static auto _factories() -> std::unordered_map<std::type_index, module_factory>& {
65 static auto instance = std::unordered_map<std::type_index, module_factory>{};
71template<
typename Derived>
77 static_assert(!std::is_abstract_v<Derived>,
"Class may not be abstract.");
78 static_assert(std::is_base_of_v<module<Derived>, Derived>,
"Class must inherit from module<Class>.");
83 using base_type = module_manager::module_base;
85 template<
typename... Dependencies>
86 using dependencies = module_manager::dependencies<Dependencies...>;
88 using stage = module_manager::stage;
90 template<derived_from<base_type>... Dependencies>
91 static auto register_module(stage stage, dependencies<Dependencies...>&& dependencies = {}) ->
bool {
92 module_manager::_factories().insert({std::type_index{
typeid(Derived)}, module_manager::module_factory{
94 .dependencies = dependencies.get(),
96 auto* instance =
reinterpret_cast<Derived*
>(std::malloc(
sizeof(Derived)));
99 throw std::bad_alloc{};
102 std::construct_at(instance);
106 .destroy = [](module_base* instance){
107 std::destroy_at(
reinterpret_cast<Derived*
>(instance));
Definition: engine.hpp:27
Definition: module.hpp:20
Definition: module.hpp:72
Definition: noncopyable.hpp:6