psemek/libs/android/source/native_app.cpp

117 lines
2.8 KiB
C++

#include <jni.h>
#include <android/log.h>
#include <psemek/app/application.hpp>
#include <psemek/gfx/init.hpp>
#include <psemek/log/log.hpp>
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
{}
};
}
extern "C" void Java_psemek_app_PsemekApplication_setupLogging(JNIEnv *, jclass)
{
psemek::log::add_sink(std::make_unique<sink_impl>());
}
extern "C" jlong Java_psemek_app_PsemekApplication_createNativeApp(JNIEnv * env, jclass) try
{
auto factory = psemek::app::make_application_factory();
psemek::gfx::init();
psemek::app::application::context context;
auto app = factory->create(factory->options(), context).release();
return reinterpret_cast<jlong>(app);
}
catch (std::exception const & e)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), e.what());
return 0;
}
catch (...)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unknown exception");
return 0;
}
extern "C" void Java_psemek_app_PsemekApplication_destroyNativeApp(JNIEnv *, jclass, jlong ptr)
{
delete reinterpret_cast<psemek::app::application *>(ptr);
}
extern "C" void Java_psemek_app_PsemekApplication_resizeNative(JNIEnv * env, jclass, jlong ptr, jint width, jint height) try
{
auto app = reinterpret_cast<psemek::app::application *>(ptr);
app->on_event(psemek::app::resize_event{{width, height}});
}
catch (std::exception const & e)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), e.what());
}
catch (...)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unknown exception");
}
extern "C" void Java_psemek_app_PsemekApplication_touchNative(JNIEnv * env, jclass, jlong ptr, jint x, jint y) try
{
auto app = reinterpret_cast<psemek::app::application *>(ptr);
app->on_event(psemek::app::touch_event{{x, y}});
}
catch (std::exception const & e)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), e.what());
}
catch (...)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unknown exception");
}
extern "C" void Java_psemek_app_PsemekApplication_drawFrameNative(JNIEnv * env, jclass, jlong ptr) try
{
auto app = reinterpret_cast<psemek::app::application *>(ptr);
app->update();
app->present();
}
catch (std::exception const & e)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), e.what());
}
catch (...)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unknown exception");
}