Brenta Engine 1.2
Loading...
Searching...
No Matches
engine.cpp
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#include <brenta/engine.hpp>
7#include <brenta/logger.hpp>
8
9#include <stdexcept>
10
11using namespace brenta;
12
13//
14// Static variables
15//
16
17tenno::vector<tenno::reference_wrapper<Subsystem>> Engine::subsystems;
18const std::string Engine::subsystem_name = "engine";
19bool Engine::initialized = false;
20
21//
22// Subsystem interface
23//
24
25std::expected<void, Subsystem::Error> Engine::initialize()
26{
27 if (this->is_initialized()) return {};
28
29 for (auto& s : this->subsystems)
30 {
31 auto ret = s.get().initialize();
32 if (!ret.has_value())
33 return std::unexpected(Engine::subsystem_name + ": failed to initialize "
34 + s.get().name() + ": " + ret.error());
35 }
36
37 Engine::initialized = true;
38 INFO("{}: initialized", Engine::subsystem_name);
39 return {};
40}
41
42std::expected<void, Subsystem::Error> Engine::terminate()
43{
44 if (!this->is_initialized()) return {};
45
46 for (auto it = this->subsystems.rbegin();
47 it != this->subsystems.rend(); ++it)
48 {
49 auto& s = *it;
50
51 auto ret = s.get().terminate();
52 if (!ret.has_value())
53 return std::unexpected(Engine::subsystem_name + "failed to terminate "
54 + s.get().name() + ": " + ret.error());
55 }
56
57 Engine::initialized = false;
58 INFO("{}: terminated", Engine::subsystem_name);
59 return {};
60}
61
62std::string Engine::name()
63{
64 return Engine::subsystem_name;
65}
66
67bool Engine::is_initialized()
68{
69 return Engine::initialized;
70}
71
72//
73// Member functions
74//
75
76Engine &Engine::instance()
77{
78 static brenta::Engine _instance;
79 return _instance;
80}
81
82Engine::Manager Engine::managed()
83{
84 return Engine::Manager();
85}
86
87std::expected<void, std::string>
88Engine::with(Subsystem::Builder &&builder)
89{
90 tenno::reference_wrapper<brenta::Subsystem> s = builder.build();
91 if (!s.get().initialize().has_value())
92 return std::unexpected(s.get().name());
93 Engine::subsystems.push_back(s);
94 return {};
95}
96
97Engine::Manager::Manager()
98{
99 auto ret = Engine::instance().initialize();
100 if (!ret.has_value())
101 {
102 ERROR("Engine::Manager: failed to initialize subsystem, {}", ret.error());
103 throw std::runtime_error("Engine::Manager: failed to initialize subsystem,"
104 + ret.error());
105 }
106 return;
107}
108
109Engine::Manager::~Manager()
110{
111 auto ret = Engine::instance().terminate();
112 if (!ret.has_value())
113 {
114 ERROR("Engine::Manager: failed to terminate subsystem, {}", ret.error());
115 }
116 return;
117}
118
119//
120// Builder
121//
122
124Engine::Builder::with(Subsystem::Builder &builder)
125{
126 this->subsystems.push_back(builder.build());
127 return *this;
128}
129
131Engine::Builder::with(Subsystem::Builder &&builder)
132{
133 this->subsystems.push_back(builder.build());
134 return *this;
135}
136
137Subsystem &Engine::Builder::build()
138{
139 Engine::subsystems = this->subsystems;
140 return Engine::instance();
141}