d394f838bcd497495255dc14296313f546a7813f
[libs/core.git] / source / core / android / mainthread.cpp
1 #include <cstring>
2 #include <cstdlib>
3 #include <msp/fs/dir.h>
4 #include <msp/fs/path.h>
5 #include <msp/fs/utils.h>
6 #include "application.h"
7 #include "errorlogger.h"
8 #include "mainthread.h"
9
10 using namespace std;
11
12 namespace Msp {
13 namespace Android {
14
15 MainThread::MainThread(ANativeActivity *a):
16         asset_manager(a->assetManager),
17         int_data_path(a->internalDataPath),
18         starting_up(true)
19 {
20         attach_to_activity(a);
21         startup_mutex.lock();
22         launch();
23 }
24
25 void MainThread::attach_to_activity(ANativeActivity *a)
26 {
27         activity = a;
28         activity->callbacks->onDestroy = &activity_destroyed;
29         activity->callbacks->onNativeWindowCreated = &native_window_created;
30         activity->callbacks->onNativeWindowResized = &native_window_resized;
31         activity->callbacks->onNativeWindowDestroyed = &native_window_destroyed;
32         activity->callbacks->onInputQueueCreated = &input_queue_created;
33         activity->callbacks->onInputQueueDestroyed = &input_queue_destroyed;
34         activity->instance = this;
35 }
36
37 void MainThread::wait_for_app_created()
38 {
39         MutexLock lock(startup_mutex);
40 }
41
42 void MainThread::resume_startup()
43 {
44         if(starting_up)
45         {
46                 starting_up = false;
47                 startup_mutex.unlock();
48         }
49 }
50
51 void MainThread::main()
52 {
53         /* I have no idea how dependable this is, but it seems to be the only way
54         to get the package name aside from making a Java call through JNI */
55         char *appname = strdup(int_data_path[-2].c_str());
56         char *argv[] = { appname, 0 };
57         Msp::Android::ErrorLogger err_logger;
58         FS::chdir(FS::dirname(int_data_path));
59         Msp::Application::run(1, argv, this, &app_created);
60         free(appname);
61         if(activity)
62         {
63                 activity->callbacks->onDestroy = &end_process;
64                 ANativeActivity_finish(activity);
65         }
66         else
67                 end_process(0);
68 }
69
70 void MainThread::app_created(void *data)
71 {
72         reinterpret_cast<MainThread *>(data)->resume_startup();
73 }
74
75 void MainThread::activity_destroyed(ANativeActivity *activity)
76 {
77         reinterpret_cast<MainThread *>(activity->instance)->activity = 0;
78 }
79
80 void MainThread::native_window_created(ANativeActivity *activity, ANativeWindow *window)
81 {
82         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_created.emit(window);
83 }
84
85 void MainThread::native_window_resized(ANativeActivity *activity, ANativeWindow *window)
86 {
87         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_resized.emit(window);
88 }
89
90 void MainThread::native_window_destroyed(ANativeActivity *activity, ANativeWindow *window)
91 {
92         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_destroyed.emit(window);
93 }
94
95 void MainThread::input_queue_created(ANativeActivity *activity, AInputQueue *queue)
96 {
97         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_created.emit(queue);
98 }
99
100 void MainThread::input_queue_destroyed(ANativeActivity *activity, AInputQueue *queue)
101 {
102         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_destroyed.emit(queue);
103 }
104
105 void MainThread::end_process(ANativeActivity *)
106 {
107         exit(0);
108 }
109
110 } // namespace Android
111 } // namespace Msp