2#ifndef LIBSBX_CORE_MODULE_HPP_
3#define LIBSBX_CORE_MODULE_HPP_
6#include <unordered_set>
7#include <unordered_map>
15#include <libsbx/utility/noncopyable.hpp>
16#include <libsbx/utility/type_id.hpp>
17#include <libsbx/memory/tracking_allocator.hpp>
32template<
typename Type>
35template<
typename Derived,
typename Base>
36concept derived_from = std::is_base_of_v<Base, Derived>;
53 enum class stage : std::uint8_t {
63 template<
typename... Types>
65 auto get()
const noexcept -> std::unordered_set<std::uint32_t> {
66 auto types = std::unordered_set<std::uint32_t>{};
73 virtual ~module_base() =
default;
74 virtual auto update() ->
void = 0;
77 struct module_factory {
78 module_manager::stage stage{};
79 std::unordered_set<std::uint32_t> dependencies{};
80 std::function<module_base*()> create{};
81 std::function<void(module_base*)> destroy{};
84 static auto _factories() -> std::vector<std::optional<module_factory>>& {
85 static auto instance = std::vector<std::optional<module_factory>>{};
91template<
typename Derived>
97 static_assert(!std::is_abstract_v<Derived>,
"Class may not be abstract.");
98 static_assert(std::is_base_of_v<module<Derived>, Derived>,
"Class must inherit from module<Class>.");
103 using base_type = module_manager::module_base;
105 template<
typename... Dependencies>
106 using dependencies = module_manager::dependencies<Dependencies...>;
108 using stage = module_manager::stage;
110 template<derived_from<base_type>... Dependencies>
111 static auto register_module(stage stage, dependencies<Dependencies...>&& dependencies = {}) ->
bool {
114 auto& factories = module_manager::_factories();
116 factories.resize(std::max(factories.size(),
static_cast<std::size_t
>(type + 1u)));
118 factories[type] = module_manager::module_factory{
120 .dependencies = dependencies.get(),
121 .create = []() -> module_base* {
123 auto* instance = allocator.allocate(1u);
126 throw std::bad_alloc{};
130 std::construct_at(instance);
132 allocator.deallocate(instance, 1u);
138 .destroy = [](module_base* instance){
143 auto* derived =
static_cast<Derived*
>(instance);
145 std::destroy_at(derived);
148 allocator.deallocate(derived, 1u);
Definition: engine.hpp:32
Definition: module.hpp:38
Definition: module.hpp:92
Definition: tracking_allocator.hpp:320
Definition: module.hpp:23
Definition: noncopyable.hpp:7
A scoped type ID generator. Allows for generating unique IDs for types within a specific scope.
Definition: type_id.hpp:31
static auto value() noexcept -> std::uint32_t
Generates a unique ID for the type.
Definition: type_id.hpp:41