Skip to content

Commit 146faac

Browse files
committed
stuff
1 parent 399cf20 commit 146faac

10 files changed

Lines changed: 596 additions & 457 deletions

File tree

src/ruisapp/glue/android/application.cxx

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,109 @@
22

33
#include "android_globals.hxx"
44
#include "asset_file.hxx"
5+
#include "window.hxx"
56

67
application_glue::application_glue(utki::version_duplet gl_version) :
78
gl_version(std::move(gl_version))
89
{}
910

10-
app_window& application_glue::make_window(ruisapp::window_parameters window_params){
11+
app_window& application_glue::make_window(ruisapp::window_parameters window_params)
12+
{
13+
if (this->window.has_value()) {
14+
throw std::logic_error(
15+
"application::make_window(): one window already exists, only one window allowed on android"
16+
);
17+
}
18+
1119
utki::assert(!this->window.has_value(), SL);
1220

13-
// TODO:
21+
auto ruis_native_window = utki::make_shared<native_window>(this->gl_version, window_params);
22+
23+
// TODO: std::move(ruis_native_window)?
24+
auto rendering_context = utki::make_shared<ruis::render::opengles::context>(ruis_native_window);
25+
26+
auto ruis_context = utki::make_shared<ruis::context>(ruis::context::parameters{
27+
.post_to_ui_thread_function =
28+
[this](std::function<void()> procedure) {
29+
// TODO:
30+
// if (PostMessage(
31+
// NULL, // post message to UI thread's message queue
32+
// WM_USER,
33+
// 0, // no wParam
34+
// // NOLINTNEXTLINE(cppcoreguidelines-owning-memory, cppcoreguidelines-pro-type-reinterpret-cast)
35+
// reinterpret_cast<LPARAM>(new std::remove_reference_t<decltype(procedure)>(std::move(procedure)))
36+
// ) == 0)
37+
// {
38+
// throw std::runtime_error("PostMessage(): failed");
39+
// }
40+
},
41+
.updater = this->updater,
42+
.renderer = utki::make_shared<ruis::render::renderer>(
43+
rendering_context,
44+
this->rendering_context.get().make_shaders(),
45+
utki::make_shared<ruis::render::renderer::objects>(rendering_context)
46+
),
47+
.style_provider = this->ruis_style_provider,
48+
// TODO:
49+
// .units = ruis::units(
50+
// ruis_native_window.get().get_dots_per_inch(), //
51+
// ruis_native_window.get().get_dots_per_pp()
52+
// )
53+
});
54+
55+
auto ruisapp_window = utki::make_shared<app_window>(
56+
std::move(ruis_context), //
57+
std::move(ruis_native_window)
58+
);
59+
60+
// TODO: window surface will likely be created later, so defer setting viewport till that time?
61+
// ruisapp_window.get().gui.set_viewport( //
62+
// ruis::rect(
63+
// 0, //
64+
// 0,
65+
// ruis::real(window_params.dims.x()),
66+
// ruis::real(window_params.dims.y())
67+
// )
68+
// );
69+
70+
this->window = std::move(ruisapp_window);
1471

1572
utki::assert(this->window.has_value(), SL);
1673
return this->window.value();
1774
}
1875

19-
void application_glue::render(){
20-
if(this->window.has_value()){
76+
void application_glue::render()
77+
{
78+
if (this->window.has_value()) {
2179
this->window.value().render();
2280
}
2381
}
2482

83+
namespace {
84+
ruisapp::application::directories get_application_directories(std::string_view app_name)
85+
{
86+
auto& glob = get_glob();
87+
88+
auto storage_dir = papki::as_dir(glob.java_functions.get_storage_dir());
89+
90+
ruisapp::application::directories dirs;
91+
92+
dirs.cache = utki::cat(storage_dir, "cache/");
93+
dirs.config = utki::cat(storage_dir, "config/");
94+
dirs.state = utki::cat(storage_dir, "state/");
95+
96+
return dirs;
97+
}
98+
} // namespace
99+
100+
ruisapp::application::application(parameters params) :
101+
application(
102+
utki::make_unique<application_glue>(params.graphics_api_version), //
103+
get_application_directories(params.name),
104+
std::move(params)
105+
)
106+
{}
107+
25108
std::unique_ptr<papki::file> ruisapp::application::get_res_file(std::string_view path) const
26109
{
27110
utki::assert(globals_wrapper::native_activity, SL);
@@ -33,7 +116,8 @@ std::unique_ptr<papki::file> ruisapp::application::get_res_file(std::string_view
33116
);
34117
}
35118

36-
ruisapp::window& ruisapp::application::make_window(ruisapp::window_parameters window_params){
119+
ruisapp::window& ruisapp::application::make_window(ruisapp::window_parameters window_params)
120+
{
37121
auto& glue = get_glue(*this);
38122
return glue.make_window(std::move(window_params));
39123
}

src/ruisapp/glue/android/application.hxx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ class app_window : public ruisapp::window
1010
{
1111
public:
1212
utki::shared_ref<native_window> ruis_native_Window;
13-
1413
};
1514
} // namespace
1615

@@ -21,6 +20,7 @@ class application_glue : public utki::destructable
2120

2221
// Only one window on android.
2322
std::optional<app_window> window;
23+
2424
public:
2525
utki::shared_ref<ruis::updater> updater = utki::make_shared<ruis::updater>();
2626

@@ -30,17 +30,26 @@ public:
3030

3131
void render();
3232

33-
void create_window_surface(ANativeWindow& android_window){
34-
if(this->window.has_value()){
33+
void create_window_surface(ANativeWindow& android_window)
34+
{
35+
if (this->window.has_value()) {
3536
this->window.create_surface(android_window);
3637
}
3738
}
3839

39-
void destroy_window_surface(){
40-
if(this->window.has_value()){
40+
void destroy_window_surface()
41+
{
42+
if (this->window.has_value()) {
4143
this->window.value().destroy_surface();
4244
}
4345
}
46+
47+
app_window* get_window(){
48+
if(this->window.has_value()){
49+
return &this->window.value();
50+
}
51+
return nullptr;
52+
}
4453
};
4554
} // namespace
4655

src/ruisapp/glue/android/globals.cxx

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ void globals_wrapper::create(ANativeActivity* activity)
1111
globals_wrapper::native_activity = activity;
1212

1313
activity->instance = new globals_wrapper();
14+
15+
auto& glob = get_glob();
16+
17+
glob.app = ruisapp::application_factory::make_application(
18+
0, // argc
19+
nullptr // argv
20+
);
21+
22+
// On android it makes no sense if the app doesn't show any GUI, since it is not possible to
23+
// launch an android app as command line app.
24+
utki::assert(glob.app, SL);
25+
26+
// Set the main loop event flag to call the update() for the first time if there
27+
// were any updateables started during creating application
28+
// object.
29+
glob.main_loop_event_fd.set();
1430
} catch (...) {
1531
globals_wrapper::native_activity = nullptr;
1632
throw;
@@ -65,7 +81,7 @@ int on_update_timer_expired(
6581
if (dt == 0) {
6682
// do not arm the timer and do not clear the flag
6783
} else {
68-
glob.fd_flag.clear();
84+
glob.main_loop_event_fd.clear();
6985
glob.timer.arm(dt);
7086
}
7187

@@ -79,16 +95,12 @@ int on_update_timer_expired(
7995
}
8096
} // namespace
8197

82-
globals_wrapper() :
83-
app(std::move(ruisapp::application_factory::make_application(
84-
0, // argc
85-
nullptr // argv
86-
)))
98+
globals_wrapper()
8799
{
88100
// add timer descriptor to looper, this is needed for updatable to work
89101
if (ALooper_addFd(
90102
this->looper,
91-
this->fd_flag.get_fd(),
103+
this->main_loop_event_fd.get_fd(),
92104
ALOOPER_POLL_CALLBACK,
93105
ALOOPER_EVENT_INPUT,
94106
&on_update_timer_expired,
@@ -110,11 +122,6 @@ globals_wrapper() :
110122
{
111123
throw std::runtime_error("failed to add UI message queue descriptor to looper");
112124
}
113-
114-
// Set the fd_flag to call the update() for the first time if there
115-
// were any updateables started during creating application
116-
// object.
117-
this->fd_flag.set();
118125
}
119126

120127
~globals_wrapper()
@@ -125,9 +132,26 @@ globals_wrapper() :
125132
this->ui_queue.get_handle()
126133
);
127134

128-
// remove fd_flag from looper
135+
// remove main_loop_event_fd from looper
129136
ALooper_removeFd(
130137
this->looper, //
131-
this->fd_flag.get_fd()
138+
this->main_loop_event_fd.get_fd()
139+
);
140+
}
141+
142+
ruis::vector2 globals_wrapper::android_win_coords_to_ruis_win_rect_coords(
143+
const ruis::vector2& ruis_win_dims, //
144+
const ruis::vector2& p
145+
)
146+
{
147+
auto& glob = get_glob();
148+
149+
ruis::vector2 ret(
150+
p.x(), //
151+
p.y() - (glob.cur_window_dims.y() - ruis_win_dims.y())
132152
);
153+
// utki::log_debug([&](auto&o){o << "android_win_coords_to_ruis_win_rect_coords(): ret
154+
//= " << ret << std::endl;});
155+
using std::round;
156+
return round(ret);
133157
}

src/ruisapp/glue/android/globals.hxx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ struct globals_wrapper final {
4646
return l;
4747
}();
4848

49-
event_fd_wrapper fd_flag; // TODO: rename to main_loop_event_fd
49+
event_fd_wrapper main_loop_event_fd;
5050
linux_timer timer{[&]() {
51-
this->fd_flag.set();
51+
this->main_loop_event_fd.set();
5252
}};
5353

5454
nitki::queue ui_queue;
@@ -60,7 +60,16 @@ struct globals_wrapper final {
6060

6161
ruis::vector2 cur_window_dims(0, 0);
6262

63-
utki::unique_ref<ruisapp::application> app;
63+
ruis::vector2 android_win_coords_to_ruis_win_rect_coords(
64+
const ruis::vector2& ruis_win_dims, //
65+
const ruis::vector2& p
66+
);
67+
68+
// Application object constructor needs accessing the stuff from globals_wrapper,
69+
// so we need to postpone application object construction to be done after the
70+
// globals_wrapper object is set to the static native_activity pointer.
71+
// This is why we don't use unique_ref here.
72+
std::unique_ptr<ruisapp::application> app;
6473
};
6574
} // namespace
6675

0 commit comments

Comments
 (0)