Skip to content

Commit 289e722

Browse files
committed
sdl
1 parent 3336fb3 commit 289e722

9 files changed

Lines changed: 977 additions & 557 deletions

File tree

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,205 @@
11
#include "application.hxx"
22

3+
#ifdef RUISAPP_RENDER_OPENGL
4+
// # include <GL/glew.h>
5+
# include <ruis/render/opengl/context.hpp>
6+
#elif defined(RUISAPP_RENDER_OPENGLES)
7+
// # include <GLES2/gl2.h>
8+
# include <ruis/render/opengles/context.hpp>
9+
#else
10+
# error "Unknown graphics API"
11+
#endif
12+
13+
using namespace std::string_view_literals;
14+
15+
application_glue::application_glue(const utki::version_duplet& gl_version) :
16+
gl_version(gl_version),
17+
shared_gl_context_native_window( //
18+
utki::make_shared<native_window>(
19+
this->display, //
20+
this->gl_version,
21+
ruisapp::window_parameters{
22+
.dims = {1, 1},
23+
.title = {},
24+
.fullscreen = false
25+
},
26+
nullptr // no shared gl context
27+
)
28+
),
29+
resource_loader_ruis_rendering_context(
30+
#ifdef RUISAPP_RENDER_OPENGL
31+
utki::make_shared<ruis::render::opengl::context>(this->shared_gl_context_native_window)
32+
#elif defined(RUISAPP_RENDER_OPENGLES)
33+
utki::make_shared<ruis::render::opengles::context>(this->shared_gl_context_native_window)
34+
#else
35+
# error "Unknown graphics API"
36+
#endif
37+
),
38+
common_shaders( //
39+
[&]() {
40+
utki::assert(this->resource_loader_ruis_rendering_context.to_shared_ptr(), SL);
41+
return this->resource_loader_ruis_rendering_context.get().make_shaders();
42+
}()
43+
),
44+
common_render_objects( //
45+
utki::make_shared<ruis::render::renderer::objects>(this->resource_loader_ruis_rendering_context)
46+
),
47+
ruis_resource_loader( //
48+
utki::make_shared<ruis::resource_loader>(
49+
this->resource_loader_ruis_rendering_context, //
50+
this->common_render_objects
51+
)
52+
),
53+
ruis_style_provider( //
54+
utki::make_shared<ruis::style_provider>(this->ruis_resource_loader)
55+
)
56+
{}
57+
58+
app_window* application_glue::get_window(native_window::window_id_type id)
59+
{
60+
auto i = this->windows.find(id);
61+
if (i == this->windows.end()) {
62+
return nullptr;
63+
}
64+
return &i->second.get();
65+
}
66+
67+
void application_glue::render()
68+
{
69+
for (auto& w : this->windows) {
70+
w.second.get().render();
71+
}
72+
}
73+
74+
void application_glue::apply_new_win_dims()
75+
{
76+
for (auto& win : this->windows) {
77+
auto& w = win.second.get();
78+
if (w.new_win_dims.is_positive_or_zero()) {
79+
w.gui.set_viewport(ruis::rect(0, w.new_win_dims));
80+
}
81+
w.new_win_dims = {-1, -1};
82+
}
83+
}
84+
85+
ruisapp::window& application_glue::make_window(ruisapp::window_parameters window_params)
86+
{
87+
auto ruis_native_window = utki::make_shared<native_window>(
88+
this->display,
89+
this->gl_version,
90+
window_params,
91+
&this->shared_gl_context_native_window.get()
92+
);
93+
94+
auto ruis_context = utki::make_shared<ruis::context>(ruis::context::parameters{
95+
.post_to_ui_thread_function =
96+
[display = this->display](std::function<void()> procedure) {
97+
SDL_Event e;
98+
SDL_memset(&e, 0, sizeof(e));
99+
e.type = display.get().user_event_type_id;
100+
e.user.code = 0;
101+
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
102+
e.user.data1 = new std::function<void()>(std::move(procedure));
103+
e.user.data2 = nullptr;
104+
SDL_PushEvent(&e);
105+
},
106+
.updater = this->updater,
107+
.renderer = utki::make_shared<ruis::render::renderer>(
108+
#ifdef RUISAPP_RENDER_OPENGL
109+
utki::make_shared<ruis::render::opengl::context>(ruis_native_window),
110+
#elif defined(RUISAPP_RENDER_OPENGLES)
111+
utki::make_shared<ruis::render::opengles::context>(ruis_native_window),
112+
#else
113+
# error "Unknown graphics API"
114+
#endif
115+
this->common_shaders,
116+
this->common_render_objects
117+
),
118+
.style_provider = this->ruis_style_provider,
119+
.units = ruis::units(
120+
ruis_native_window.get().get_dpi(), //
121+
ruis_native_window.get().get_scale_factor()
122+
)
123+
});
124+
125+
auto ruisapp_window = utki::make_shared<app_window>(
126+
std::move(ruis_context), //
127+
std::move(ruis_native_window)
128+
);
129+
130+
ruisapp_window.get().gui.set_viewport( //
131+
ruis::rect({0, 0}, ruisapp_window.get().ruis_native_window.get().get_dims())
132+
);
133+
134+
auto res = this->windows.insert( //
135+
std::make_pair(
136+
ruisapp_window.get().ruis_native_window.get().get_id(), //
137+
std::move(ruisapp_window)
138+
)
139+
);
140+
utki::assert(res.second, SL);
141+
142+
return res.first->second.get();
143+
}
144+
145+
void application_glue::destroy_window(native_window::window_id_type id)
146+
{
147+
auto i = this->windows.find(id);
148+
utki::assert(i != this->windows.end(), SL);
149+
150+
this->windows_to_destroy.push_back(std::move(i->second));
151+
this->windows.erase(i);
152+
}
153+
154+
namespace {
155+
ruisapp::application::directories get_application_directories(std::string_view app_name)
156+
{
157+
char* base_dir = SDL_GetPrefPath("", std::string(app_name).c_str());
158+
utki::scope_exit base_dir_scope_exit([&]() {
159+
SDL_free(base_dir);
160+
});
161+
162+
ruisapp::application::directories dirs;
163+
164+
dirs.cache = utki::cat(base_dir, "cache/"sv);
165+
dirs.config = utki::cat(base_dir, "config/"sv);
166+
dirs.state = utki::cat(base_dir, "state/"sv);
167+
168+
// std::cout << "cache dir = " << dirs.cache << std::endl;
169+
// std::cout << "config dir = " << dirs.config << std::endl;
170+
// std::cout << "state dir = " << dirs.state << std::endl;
171+
172+
return dirs;
173+
}
174+
} // namespace
175+
176+
ruisapp::application::application(parameters params) :
177+
application(
178+
utki::make_unique<application_glue>(params.graphics_api_version), //
179+
get_application_directories(params.name),
180+
std::move(params)
181+
)
182+
{}
183+
184+
void ruisapp::application::quit() noexcept
185+
{
186+
auto& glue = get_glue(*this);
187+
188+
// TODO: send SDL_QUIT event instead of setting the flag?
189+
glue.quit_flag.store(true);
190+
}
191+
192+
ruisapp::window& ruisapp::application::make_window(ruisapp::window_parameters window_params)
193+
{
194+
auto& glue = get_glue(*this);
195+
return glue.make_window(std::move(window_params));
196+
}
197+
198+
void ruisapp::application::destroy_window(ruisapp::window& w)
199+
{
200+
auto& glue = get_glue(*this);
201+
202+
utki::assert(dynamic_cast<app_window*>(&w), SL);
203+
auto& app_win = static_cast<app_window&>(w);
204+
glue.destroy_window(app_win.ruis_native_window.get().get_id());
205+
}
Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,94 @@
11
#pragma once
22

3+
#include <atomic>
4+
35
#include <utki/destructable.hpp>
46

5-
namespace{
6-
class application_glue : public utki::destructable{
7+
#include "../../application.hpp"
8+
9+
#include "display.hxx"
10+
#include "window.hxx"
11+
12+
namespace {
13+
class app_window : public ruisapp::window
14+
{
715
public:
16+
utki::shared_ref<native_window> ruis_native_window;
17+
18+
app_window(
19+
utki::shared_ref<ruis::context> ruis_context, //
20+
utki::shared_ref<native_window> ruis_native_window
21+
) :
22+
ruisapp::window(std::move(ruis_context)),
23+
ruis_native_window(std::move(ruis_native_window))
24+
{
25+
utki::assert(
26+
[&]() {
27+
ruis::render::native_window& w1 = this->ruis_native_window.get();
28+
ruis::render::native_window& w2 = this->gui.context.get().window();
29+
return &w1 == &w2;
30+
},
31+
SL
32+
);
33+
}
34+
35+
ruis::vector2 new_win_dims{-1, -1};
836
};
37+
} // namespace
38+
39+
namespace {
40+
class application_glue : public utki::destructable
41+
{
42+
public:
43+
const utki::shared_ref<display_wrapper> display = utki::make_shared<display_wrapper>();
44+
45+
private:
46+
const utki::version_duplet gl_version;
47+
48+
const utki::shared_ref<native_window> shared_gl_context_native_window;
49+
const utki::shared_ref<ruis::render::context> resource_loader_ruis_rendering_context;
50+
const utki::shared_ref<const ruis::render::context::shaders> common_shaders;
51+
const utki::shared_ref<const ruis::render::renderer::objects> common_render_objects;
52+
const utki::shared_ref<ruis::resource_loader> ruis_resource_loader;
53+
const utki::shared_ref<ruis::style_provider> ruis_style_provider;
54+
55+
std::map<
56+
native_window::window_id_type, //
57+
utki::shared_ref<app_window> //
58+
>
59+
windows;
60+
61+
public:
62+
std::vector<utki::shared_ref<app_window>> windows_to_destroy;
63+
64+
utki::shared_ref<ruis::updater> updater = utki::make_shared<ruis::updater>();
65+
66+
std::atomic_bool quit_flag = false;
67+
68+
application_glue(const utki::version_duplet& gl_version);
69+
70+
ruisapp::window& make_window(ruisapp::window_parameters window_params);
71+
void destroy_window(native_window::window_id_type id);
72+
73+
app_window* get_window(native_window::window_id_type id);
74+
75+
// render all windows if needed
76+
void render();
77+
78+
void apply_new_win_dims();
79+
};
80+
} // namespace
81+
82+
namespace {
83+
inline application_glue& get_glue(ruisapp::application& app)
84+
{
85+
return static_cast<application_glue&>(app.pimpl.get());
86+
}
87+
} // namespace
88+
89+
namespace {
90+
inline application_glue& get_glue()
91+
{
92+
return get_glue(ruisapp::application::inst());
993
}
94+
} // namespace

0 commit comments

Comments
 (0)