CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
application.cppm
Go to the documentation of this file.
1// Copyright (c) 2024, Víctor Castillo Agüero.
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4module;
5#include <tracy/Tracy.hpp>
6#define SDL_MAIN_HANDLED
7#include <SDL3/SDL.h>
8#include <SDL3/SDL_main.h>
9
10export module cydui.application;
11
12export import std;
13
14export import fabric.async;
15export import fabric.logging;
16
17export import cydui.window_events;
18
19export namespace cydui {
20 class Application: public fabric::async::async_bus_t {
21 private:
22 Application()
23 : stop_application_listener_(on_event([&](const StopApplicationEvent&) -> fabric::task<> {
24 if (this->window_map_.empty()) {
25 this->emit<fabric::async::StopBusEvent>();
26 }
27 this->stop_application_flag_.test_and_set();
28 this->stop_application_flag_.notify_all();
29 co_return;
30 })) {
31 ZoneScopedN("Application{}");
32 using namespace std::chrono_literals;
33 LOG::print{INFO}("Initializing application...");
34
35 get_executor()
36 ->schedule([] -> fabric::task<> {
37 tracy::SetThreadNameWithHint("Application", 1);
38 ZoneScopedN("Application Init");
39 SDL_SetMainReady();
40 if (not SDL_Init(SDL_INIT_VIDEO)) {
41 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
42 LOG::print{ERROR}("Couldn't initialize SDL3: {}", SDL_GetError());
43 }
44 LOG::print{INFO}("SDL3 initialized.");
45 co_return;
46 })
47 .wait();
48
49 get_executor()->schedule([&] -> fabric::task<> {
50 while (true) { // will be stopped at the co_await when the executor is destroyed
51 {
52 std::scoped_lock lk{get_instance().window_map_mtx_};
53 window_events::poll_events(this, &get_instance().window_map_);
54 }
55 co_await 16ms;
56 }
57 co_return;
58 });
59 LOG::print{INFO}("Application initialized...");
60 }
61
62 public:
64 ZoneScopedN("~Application");
65 }
66
67 public:
68 static Application& get_instance() {
69 static Application instance;
70 return instance;
71 }
72
73 template <typename... Args>
74 static auto run_async(auto&& fun, Args&&... args) {
75 ZoneScopedN("Application:run_async");
76 return get_instance()->schedule(
77 [=](Args... argss) -> fabric::task<decltype(fun(std::forward<Args>(argss)...))> {
78 ZoneScopedN("Application:run_async:()");
79 co_return fun(std::forward<Args>(argss)...);
80 },
81 std::forward<Args>(args)...
82 );
83 }
84
85 template <typename... Args>
86 static auto run(auto&& fun, Args&&... args) {
87 ZoneScopedN("Application:run");
88 return run_async(fun, std::forward<Args>(args)...).get();
89 }
90
91 template <typename... Args>
92 static auto schedule(auto&& fun, Args&&... args) {
93 ZoneScopedN("Application:run_async");
94 return get_instance()->schedule(fun, std::forward<Args>(args)...);
95 }
96
97 template <typename... Args>
98 static auto schedule(fabric::tasks::time_point tp, auto&& fun, Args&&... args) {
99 ZoneScopedN("Application:run_async");
100 return get_instance()->schedule(tp, fun, std::forward<Args>(args)...);
101 }
102
103 template <typename... Args>
104 static auto schedule(fabric::tasks::duration duration, auto&& fun, Args&&... args) {
105 ZoneScopedN("Application:run_async");
106 return get_instance()->schedule(duration, fun, std::forward<Args>(args)...);
107 }
108
109 static void register_window(std::size_t id, fabric::async::async_bus_t* window) {
110 ZoneScopedN("Application:register_window");
111 std::scoped_lock lk{get_instance().window_map_mtx_};
112 get_instance().window_map_[id] = window;
113 LOG::print{INFO}("Window registered ID={}", id);
114 }
115 static void unregister_window(std::size_t id) {
116 ZoneScopedN("Application:unregister_window");
117 Application& instance = get_instance();
118 std::scoped_lock lk{instance.window_map_mtx_};
119 instance.window_map_.erase(id);
120 if (instance.window_map_.empty() and instance.stop_application_flag_.test()) {
121 instance.stop_application_flag_.clear();
122 instance.emit<fabric::async::StopBusEvent>();
123 }
124 LOG::print{INFO}("Window unregistered ID={}", id);
125 }
126
127 static void terminate() {
128 get_instance()->request_stop();
129 }
130
131 private:
132 TracyLockable(std::mutex, window_map_mtx_);
133 std::map<std::size_t, fabric::async::async_bus_t*> window_map_{};
134 fabric::async::listener<StopApplicationEvent> stop_application_listener_;
135 std::atomic_flag stop_application_flag_{false};
136 };
137} // namespace cydui
138
139// using cyd::fabric::async::async;
static auto schedule(fabric::tasks::duration duration, auto &&fun, Args &&... args)
static auto schedule(auto &&fun, Args &&... args)
static auto run(auto &&fun, Args &&... args)
static void register_window(std::size_t id, fabric::async::async_bus_t *window)
static void unregister_window(std::size_t id)
static void terminate()
static auto schedule(fabric::tasks::time_point tp, auto &&fun, Args &&... args)
static auto run_async(auto &&fun, Args &&... args)
static Application & get_instance()
void poll_events(fabric::async::async_bus_t *app_bus, window_map *busses)