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();
}
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
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<MainThread *>(data)->resume_startup();
+}
+
+void MainThread::native_window_created(ANativeActivity *activity, ANativeWindow *window)
+{
+ reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_created.emit(window);
+}
+
+void MainThread::native_window_resized(ANativeActivity *activity, ANativeWindow *window)
+{
+ reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_resized.emit(window);
+}
+
+void MainThread::native_window_destroyed(ANativeActivity *activity, ANativeWindow *window)
+{
+ reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_destroyed.emit(window);
+}
+
+void MainThread::input_queue_created(ANativeActivity *activity, AInputQueue *queue)
+{
+ reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_created.emit(queue);
+}
+
+void MainThread::input_queue_destroyed(ANativeActivity *activity, AInputQueue *queue)
+{
+ reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_destroyed.emit(queue);
+}
+
} // namespace Android
} // namespace Msp
#define MSP_CORE_ANDROID_MAINTHREAD_H_
#include <android/native_activity.h>
+#include <sigc++/signal.h>
+#include "mutex.h"
#include "thread.h"
namespace Msp {
class MainThread: public Thread
{
+public:
+ sigc::signal<void, ANativeWindow *> signal_native_window_created;
+ sigc::signal<void, ANativeWindow *> signal_native_window_resized;
+ sigc::signal<void, ANativeWindow *> signal_native_window_destroyed;
+ sigc::signal<void, AInputQueue *> signal_input_queue_created;
+ sigc::signal<void, AInputQueue *> 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
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_)
{
return 1;
}
+ if(created_callback)
+ created_callback(data);
+
int result = app_->main();
Application *a = app_;
app_ = 0;
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_; }