#include #include #include #include #include namespace { using namespace psemek; android_LogPriority log_priority(log::level level) { switch (level) { case log::level::debug: return ANDROID_LOG_DEBUG; case log::level::info: return ANDROID_LOG_INFO; case log::level::warning: return ANDROID_LOG_WARN; case log::level::error: return ANDROID_LOG_ERROR; default: return ANDROID_LOG_UNKNOWN; } } struct sink_impl : log::sink { void put_message(log::message const & msg) override { __android_log_write(log_priority(msg.level), "psemek", msg.message.data()); } void flush() override {} }; template auto try_native(JNIEnv * env, F && f) try { return f(); } catch (std::exception const & e) { env->ThrowNew(env->FindClass("java/lang/Exception"), e.what()); __builtin_unreachable(); } catch (...) { env->ThrowNew(env->FindClass("java/lang/Exception"), "Unknown exception"); __builtin_unreachable(); } } extern "C" void Java_psemek_app_PsemekApplication_setupLogging(JNIEnv *, jclass) { psemek::log::add_sink(std::make_unique()); } extern "C" jlong Java_psemek_app_PsemekApplication_createNativeApp(JNIEnv * env, jclass) { return try_native(env, [&]{ auto factory = psemek::app::make_application_factory(); psemek::gfx::init(); psemek::app::application::context context; context.show_cursor = [](bool){}; context.vsync = [](bool){}; context.relative_mouse_mode = [](bool){}; context.windowed = [](bool){}; auto app = factory->create(factory->options(), context).release(); return reinterpret_cast(app); }); } extern "C" void Java_psemek_app_PsemekApplication_destroyNativeApp(JNIEnv *, jclass, jlong ptr) { delete reinterpret_cast(ptr); } extern "C" void Java_psemek_app_PsemekApplication_resizeNative(JNIEnv * env, jclass, jlong ptr, jint width, jint height) { try_native(env, [&]{ auto app = reinterpret_cast(ptr); app->on_event(psemek::app::resize_event{{width, height}}); }); } extern "C" void Java_psemek_app_PsemekApplication_touchDownNative(JNIEnv * env, jclass, jlong ptr, jint x, jint y) { try_native(env, [&]{ auto app = reinterpret_cast(ptr); app->on_event(psemek::app::touch_down_event{{x, y}}); }); } extern "C" void Java_psemek_app_PsemekApplication_touchUpNative(JNIEnv * env, jclass, jlong ptr, jint x, jint y) { try_native(env, [&]{ auto app = reinterpret_cast(ptr); app->on_event(psemek::app::touch_up_event{{x, y}}); }); } extern "C" void Java_psemek_app_PsemekApplication_touchMoveNative(JNIEnv * env, jclass, jlong ptr, jint x, jint y) { try_native(env, [&]{ auto app = reinterpret_cast(ptr); app->on_event(psemek::app::touch_move_event{{x, y}}); }); } extern "C" void Java_psemek_app_PsemekApplication_drawFrameNative(JNIEnv * env, jclass, jlong ptr) { try_native(env, [&]{ auto app = reinterpret_cast(ptr); app->update(); app->present(); }); }