sandbox
Loading...
Searching...
No Matches
engine.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_CORE_ENGINE_HPP_
3#define LIBSBX_CORE_ENGINE_HPP_
4
5#include <map>
6#include <vector>
7#include <typeindex>
8#include <memory>
9#include <span>
10#include <string_view>
11#include <cmath>
12#include <chrono>
13#include <ranges>
14
15#include <libsbx/utility/concepts.hpp>
16#include <libsbx/utility/noncopyable.hpp>
17#include <libsbx/utility/assert.hpp>
18#include <libsbx/utility/type_name.hpp>
19#include <libsbx/utility/timer.hpp>
20#include <libsbx/utility/logger.hpp>
21
22#include <libsbx/units/time.hpp>
23
24#include <libsbx/core/module.hpp>
25#include <libsbx/core/application.hpp>
26#include <libsbx/core/cli.hpp>
27#include <libsbx/core/profiler.hpp>
28#include <libsbx/core/settings.hpp>
29
30namespace sbx::core {
31
33
34 using stage = module_manager::stage;
35 using module_base = module_manager::module_base;
36 using module_factory = module_manager::module_factory;
37
38public:
39
40 engine(std::span<std::string_view> args);
41
42 ~engine();
43
44 static auto delta_time() -> units::second;
45
46 static auto fixed_delta_time() -> units::second;
47
48 static auto time() -> units::second;
49
50 static auto quit() -> void;
51
52 static auto cli() noexcept -> core::cli&;
53
54 static auto settings() noexcept -> core::settings&;
55
56 template<typename Module>
57 requires (std::is_base_of_v<module_base, Module>)
58 [[nodiscard]] static auto get_module() -> Module& {
59 const auto type = type_id<Module>::value();
60
61 auto& modules = _instance->_modules;
62
63 if (type >= modules.size() || !modules[type]) {
64 throw std::runtime_error{fmt::format("Failed to find module '{}'", utility::type_name<Module>())};
65 }
66
67 return *static_cast<Module*>(modules[type]);
68 }
69
70 template<typename Application = core::application>
71 requires (std::is_same_v<core::application, Application> || std::is_base_of_v<core::application, Application>)
72 [[nodiscard]] static auto get_application() -> Application& {
73 utility::assert_that(_instance != nullptr, "Engine instance does not exist");
74 utility::assert_that(_instance->_application != nullptr, "Engine has no application running");
75
76 return *static_cast<Application*>(_instance->_application.get());
77 }
78
79 template<typename Application, typename... Args>
80 requires (std::is_base_of_v<core::application, Application> && std::is_constructible_v<Application, Args...>)
81 auto run(Args&&... args) -> void {
82 utility::assert_that(_instance != nullptr, "Engine instance does not exist");
83 utility::assert_that(!_is_running, "Engine instance is already running");
84
85 _application = std::make_unique<Application>(std::forward<Args>(args)...);
86
87 _run_main_loop();
88 }
89
90private:
91
92 auto _run_main_loop() -> void;
93
94 auto _create_module(const std::uint32_t type, const module_factory& factory) -> void;
95
96 auto _destroy_module(const std::uint32_t type) -> void;
97
98 auto _update_stage(stage stage) -> void;
99
100 static engine* _instance;
101
102 units::second _delta_time;
103 units::second _time;
104
105 bool _is_running{};
106 // std::vector<std::string_view> _args{};
107 core::cli _cli;
108 // core::profiler _profiler;
109 core::settings _settings;
110
111 std::unique_ptr<application> _application;
112
113 std::vector<module_base*> _modules{};
114 std::map<stage, std::vector<std::uint32_t>> _module_by_stage{};
115
116}; // class engine
117
118} // namespace sbx::core
119
120#endif // LIBSBX_CORE_ENGINE_HPP_
Definition: cli.hpp:24
Definition: engine.hpp:32
Definition: settings.hpp:84
Definition: quantity.hpp:66
Definition: noncopyable.hpp:7
static auto value() noexcept -> std::uint32_t
Generates a unique ID for the type.
Definition: type_id.hpp:41