From: Mikko Rasa Date: Sun, 12 Oct 2014 11:35:05 +0000 (+0300) Subject: Add window and input management signals for Android X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=commitdiff_plain;h=dd997d45dd774b1d6734a19c6eb6efdd6be14234 Add window and input management signals for Android The onCreate handler will now wait until either the main Application object is constructed or the MainThread's resume_startup function is called. This ensures that the application (or a library such as mspgui) can connect to the signals before they are emitted. --- diff --git a/source/core/android/main.cpp b/source/core/android/main.cpp index 86ed5be..2101563 100644 --- a/source/core/android/main.cpp +++ b/source/core/android/main.cpp @@ -2,5 +2,6 @@ extern "C" void ANativeActivity_onCreate(ANativeActivity *activity, void * /*saved_state*/, size_t /*state_size*/) { - new Msp::Android::MainThread(activity); + Msp::Android::MainThread *thread = new Msp::Android::MainThread(activity); + thread->wait_for_app_created(); } diff --git a/source/core/android/mainthread.cpp b/source/core/android/mainthread.cpp index 51fcafc..e07c837 100644 --- a/source/core/android/mainthread.cpp +++ b/source/core/android/mainthread.cpp @@ -10,11 +10,35 @@ namespace Msp { namespace Android { MainThread::MainThread(ANativeActivity *a): - activity(a) + activity(a), + starting_up(true) { + activity->callbacks->onNativeWindowCreated = &native_window_created; + activity->callbacks->onNativeWindowResized = &native_window_resized; + activity->callbacks->onNativeWindowDestroyed = &native_window_destroyed; + activity->callbacks->onInputQueueCreated = &input_queue_created; + activity->callbacks->onInputQueueDestroyed = &input_queue_destroyed; + activity->instance = this; + + startup_mutex.lock(); + launch(); } +void MainThread::wait_for_app_created() +{ + MutexLock lock(startup_mutex); +} + +void MainThread::resume_startup() +{ + if(starting_up) + { + starting_up = false; + startup_mutex.unlock(); + } +} + void MainThread::main() { /* I have no idea how dependable this is, but it seems to be the only way @@ -22,10 +46,40 @@ void MainThread::main() char *appname = strdup(FS::Path(activity->internalDataPath)[-2].c_str()); char *argv[] = { appname, 0 }; Msp::Android::ErrorLogger err_logger; - Msp::Application::run(1, argv, activity); + Msp::Application::run(1, argv, this, &app_created); free(appname); ANativeActivity_finish(activity); } +void MainThread::app_created(void *data) +{ + reinterpret_cast(data)->resume_startup(); +} + +void MainThread::native_window_created(ANativeActivity *activity, ANativeWindow *window) +{ + reinterpret_cast(activity->instance)->signal_native_window_created.emit(window); +} + +void MainThread::native_window_resized(ANativeActivity *activity, ANativeWindow *window) +{ + reinterpret_cast(activity->instance)->signal_native_window_resized.emit(window); +} + +void MainThread::native_window_destroyed(ANativeActivity *activity, ANativeWindow *window) +{ + reinterpret_cast(activity->instance)->signal_native_window_destroyed.emit(window); +} + +void MainThread::input_queue_created(ANativeActivity *activity, AInputQueue *queue) +{ + reinterpret_cast(activity->instance)->signal_input_queue_created.emit(queue); +} + +void MainThread::input_queue_destroyed(ANativeActivity *activity, AInputQueue *queue) +{ + reinterpret_cast(activity->instance)->signal_input_queue_destroyed.emit(queue); +} + } // namespace Android } // namespace Msp diff --git a/source/core/android/mainthread.h b/source/core/android/mainthread.h index 9d139bc..0330352 100644 --- a/source/core/android/mainthread.h +++ b/source/core/android/mainthread.h @@ -2,6 +2,8 @@ #define MSP_CORE_ANDROID_MAINTHREAD_H_ #include +#include +#include "mutex.h" #include "thread.h" namespace Msp { @@ -9,14 +11,34 @@ namespace Android { class MainThread: public Thread { +public: + sigc::signal signal_native_window_created; + sigc::signal signal_native_window_resized; + sigc::signal signal_native_window_destroyed; + sigc::signal signal_input_queue_created; + sigc::signal signal_input_queue_destroyed; + private: ANativeActivity *activity; + bool starting_up; + Mutex startup_mutex; public: MainThread(ANativeActivity *); + bool is_starting_up() const { return starting_up; } + void wait_for_app_created(); + void resume_startup(); + private: virtual void main(); + + static void app_created(void *); + static void native_window_created(ANativeActivity *, ANativeWindow *); + static void native_window_resized(ANativeActivity *, ANativeWindow *); + static void native_window_destroyed(ANativeActivity *, ANativeWindow *); + static void input_queue_created(ANativeActivity *, AInputQueue *); + static void input_queue_destroyed(ANativeActivity *, AInputQueue *); }; } // namespace Android diff --git a/source/core/application.cpp b/source/core/application.cpp index d5745ed..3a5561e 100644 --- a/source/core/application.cpp +++ b/source/core/application.cpp @@ -21,7 +21,7 @@ Application::Application(): throw logic_error("instance already exists"); } -int Application::run(int argc, char **argv, void *data) +int Application::run(int argc, char **argv, void *data, void (*created_callback)(void *)) { if(!starter_) { @@ -43,6 +43,9 @@ int Application::run(int argc, char **argv, void *data) return 1; } + if(created_callback) + created_callback(data); + int result = app_->main(); Application *a = app_; app_ = 0; diff --git a/source/core/application.h b/source/core/application.h index e1d3a8b..af18cea 100644 --- a/source/core/application.h +++ b/source/core/application.h @@ -42,7 +42,7 @@ public: This function can only be called once. The global main() function provided by the library normally does it automatically at program startup. */ - static int run(int, char **, void * =0); + static int run(int, char **, void * =0, void (*)(void *) = 0); static void *get_data() { return data_; }