LiteFX 0.3.1.2022
Computer Graphics Engine
app.hpp
1#pragma once
2
3#include <litefx/app_api.hpp>
4#include <litefx/app_formatters.hpp>
5
6namespace LiteFX {
7 using namespace LiteFX::Logging;
8
18 class LITEFX_APPMODEL_API IBackend {
19 friend class App;
20
21 private:
22 BackendState m_state = BackendState::Inactive;
23
24 public:
25 virtual ~IBackend() noexcept = default;
26
27 public:
33 virtual BackendType type() const noexcept = 0;
34
40 const BackendState& state() const noexcept { return m_state; }
41
46 virtual String name() const noexcept = 0;
47
48 protected:
53 BackendState& state() noexcept { return m_state; }
54
58 virtual void activate() = 0;
59
63 virtual void deactivate() = 0;
64
65 private:
66 std::type_index typeId() const noexcept { return typeid(*this); }
67 };
68
74 class LITEFX_APPMODEL_API App {
75 LITEFX_IMPLEMENTATION(AppImpl);
76 LITEFX_BUILDER(AppBuilder);
77
78 public:
82 App();
83 App(const App&) = delete;
84 App(App&&) = delete;
85
86 virtual ~App() noexcept;
87
88 public:
93 virtual String name() const noexcept = 0;
94
99 virtual AppVersion version() const noexcept = 0;
100
105 Platform platform() const noexcept;
106
112 virtual const IBackend* operator[](std::type_index type) const;
113
119 virtual const IBackend* getBackend(std::type_index type) const;
120
126 virtual Array<const IBackend*> getBackends(const BackendType type) const noexcept;
127
128 protected:
134 virtual IBackend* getBackend(std::type_index type);
135
141 template <typename TBackend> requires
142 rtti::implements<TBackend, IBackend>
143 TBackend* findBackend() {
144 return dynamic_cast<TBackend*>(this->getBackend(typeid(TBackend)));
145 }
146
157 virtual void startBackend(std::type_index type) const;
158
168 virtual void stopBackend(std::type_index type) const;
169
175 virtual void stopActiveBackends(const BackendType& type) const;
176
182 virtual IBackend* activeBackend(const BackendType& type) const;
183
189 virtual std::type_index activeBackendType(const BackendType& type) const;
190
191 private:
197 void registerStartCallback(std::type_index type, const std::function<bool()>& callback);
198
204 void registerStopCallback(std::type_index type, const std::function<void()>& callback);
205
206 public:
218 template <typename TBackend> requires
220 void onBackendStart(const std::function<bool(TBackend*)>& callback) {
221 this->registerStartCallback(typeid(TBackend), [this, callback]() {
222 auto backend = this->findBackend<TBackend>();
223
224 if (backend == nullptr)
225 throw InvalidArgumentException("No backend of type {0} has been registered.", typeid(TBackend).name());
226
227 if (backend->state() == BackendState::Active)
228 return true;
229 else
230 return callback(backend);
231 });
232 }
233
240 template <typename TBackend> requires
242 void onBackendStop(const std::function<void(TBackend*)>& callback) {
243 this->registerStopCallback(typeid(TBackend), [this, callback]() {
244 auto backend = this->findBackend<TBackend>();
245
246 if (backend == nullptr)
247 throw InvalidArgumentException("No backend of type {0} has been registered.", typeid(TBackend).name());
248
249 if (backend->state() != BackendState::Inactive)
250 callback(backend);
251 });
252 }
253
254 public:
260 template <typename TBackend> requires
262 const TBackend* findBackend() const {
263 return dynamic_cast<const TBackend*>(this->getBackend(typeid(TBackend)));
264 }
265
271 template <typename TBackend> requires
274 this->startBackend(typeid(TBackend));
275 }
276
282 template <typename TBackend> requires
284 void stopBackend() {
285 this->stopBackend(typeid(TBackend));
286 }
287
288 public:
294 virtual void use(UniquePtr<IBackend>&& backend);
295
299 virtual void run() = 0;
300
304 virtual void initialize() = 0;
305
306 public:
315 virtual void resize(int& width, int& height);
316
317 public:
321 template <typename TApp, typename ...TArgs>
322 static AppBuilder build(TArgs&&... _args) {
323 return AppBuilder(makeUnique<TApp>(std::forward<TArgs>(_args)...));
324 }
325 };
326
330 class LITEFX_APPMODEL_API AppBuilder : public Builder<AppBuilder, App> {
331 public:
332 using builder_type::Builder;
333
334 protected:
336 virtual void build() override;
337
338 public:
340 void use(UniquePtr<IBackend>&& backend);
341
345 template <typename TSink, typename ...TArgs> requires
346 std::convertible_to<TSink*, ISink*>
347 AppBuilder& logTo(TArgs&&... args) {
348 auto sink = makeUnique<TSink>(std::forward<TArgs>(args)...);
349 Logger::sinkTo(sink.get());
350 return *this;
351 }
352
356 template <typename TBackend, typename ...TArgs> requires
358 AppBuilder& useBackend(TArgs&&... args) {
359 this->use(makeUnique<TBackend>(*this->instance(), std::forward<TArgs>(args)...));
360 return *this;
361 }
362 };
363
367 class LITEFX_APPMODEL_API AppVersion {
368 LITEFX_IMPLEMENTATION(AppVersionImpl);
369
370 public:
378 explicit AppVersion(int major = 1, int minor = 0, int patch = 0, int revision = 0) noexcept;
379 AppVersion(const AppVersion&) = delete;
381
382 virtual ~AppVersion() noexcept;
383
384 public:
389 int major() const noexcept;
390
395 int minor() const noexcept;
396
401 int patch() const noexcept;
402
407 int revision() const noexcept;
408
413 int engineMajor() const noexcept;
414
419 int engineMinor() const noexcept;
420
425 int engineRevision() const noexcept;
426
431 int engineStatus() const noexcept;
432
437 String engineIdentifier() const noexcept;
438
443 String engineVersion() const noexcept;
444 };
445
446}
447
448template <>
449struct fmt::formatter<LiteFX::AppVersion> {
450 bool engineVersion = false;
451
452 constexpr auto parse(format_parse_context& ctx) {
453 auto it = ctx.begin(), end = ctx.end();
454
455 if (it != end && (*it == 'e'))
456 {
457 engineVersion = true;
458 it++;
459 }
460
461 if (it != end && *it != '}')
462 throw format_error("Invalid version format: expected: `}`.");
463
464 return it;
465 }
466
467 template <typename FormatContext>
468 auto format(const LiteFX::AppVersion& app, FormatContext& ctx) {
469 return engineVersion ?
470 fmt::format_to(ctx.out(), "{} Version {}", app.engineIdentifier(), app.engineVersion()) :
471 fmt::format_to(ctx.out(), "{}.{}.{}.{}", app.major(), app.minor(), app.patch(), app.revision());
472 }
473};
Definition: app.cpp:9
Definition: appversion.cpp:9
Creates a new builder for an App.
Definition: app.hpp:330
AppBuilder & logTo(TArgs &&... args)
Registers a sink for logging.
Definition: app.hpp:347
AppBuilder & useBackend(TArgs &&... args)
Registers a new backend.
Definition: app.hpp:358
The base class for an application.
Definition: app.hpp:74
const TBackend * findBackend() const
Returns the registered backend instance for a type index.
Definition: app.hpp:262
App(App &&)=delete
static AppBuilder build(TArgs &&... _args)
Creates a new application builder.
Definition: app.hpp:322
void onBackendStop(const std::function< void(TBackend *)> &callback)
Sets a callback that is called, if a backend is stopped.
Definition: app.hpp:242
void startBackend()
Attempts to start a backend of type TBackend and stops the active backend of the same BackendType,...
Definition: app.hpp:273
App(const App &)=delete
virtual void run()=0
Starts the application.
void onBackendStart(const std::function< bool(TBackend *)> &callback)
Sets a callback that is called, if a backend is started.
Definition: app.hpp:220
void stopBackend()
Stops a backend, if it is currently running.
Definition: app.hpp:284
virtual void initialize()=0
Called to initialize the application state.
Contains the version of an App.
Definition: app.hpp:367
int major() const noexcept
Gets the major version of the app.
Definition: appversion.cpp:34
int patch() const noexcept
Gets the patch number of the app.
Definition: appversion.cpp:44
String engineIdentifier() const noexcept
Gets the identifier of the engine build.
Definition: appversion.cpp:74
int revision() const noexcept
Gets the revision of the app.
Definition: appversion.cpp:49
virtual ~AppVersion() noexcept
AppVersion(const AppVersion &)=delete
int minor() const noexcept
Gets the minor version of the app.
Definition: appversion.cpp:39
String engineVersion() const noexcept
Gets the version string of the engine build.
Definition: appversion.cpp:79
AppVersion(AppVersion &&)=delete
Describes an generic builder type.
Definition: containers.hpp:509
The base class for an app backend.
Definition: app.hpp:18
virtual ~IBackend() noexcept=default
virtual void deactivate()=0
Called by the parent App, if the backend is stopped.
virtual void activate()=0
Called by the parent App, if the backend is started.
virtual String name() const noexcept=0
Gets the name of the backend.
static void sinkTo(const ISink *sink)
Definition: logger_factory.cpp:32
Definition: traits.hpp:95
Definition: logging.hpp:22
Definition: app.hpp:6
std::string String
Definition: string.hpp:19
std::vector< T > Array
Represents a dynamic array.
Definition: containers.hpp:58
std::unique_ptr< T, TDeleter > UniquePtr
Represents a unique pointer, that expresses exclusive ownership.
Definition: containers.hpp:87
auto format(const LiteFX::AppVersion &app, FormatContext &ctx)
Definition: app.hpp:468
constexpr auto parse(format_parse_context &ctx)
Definition: app.hpp:452
Definition: app_formatters.hpp:6