AUI Framework  master
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AJni.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14#include "Globals.h"
   15#include "GlobalRef.h"
   16#include "Converter.h"
   17#include "Signature.h"
   18#include "Env.h"
   19#include "ArrayView.h"
   20#include <AUI/Util/APreprocessor.h>
   21#include <AUI/Traits/strings.h>
   22#include <AUI/Common/AException.h>
   23
   30
   31
   52#define AUI_JNI_CLASS(path, name) \
   53class name ## _info: public ::aui::jni::GlobalRef { \
   54public:                           \
   55    static constexpr auto JAVA_CLASS_NAME = #path ## _asl;                        \
   56    [[nodiscard]] static constexpr auto getClassName() noexcept { return #path; } \
   57    [[nodiscard]] static auto getClass() noexcept { static ::aui::jni::GlobalRef t = ::aui::jni::env()->FindClass(getClassName()); AUI_ASSERTX(t.asClass() != nullptr, "no such class: " #path); return t.asClass(); } \
   58                                      \
   59};                                \
   60struct name: public name ## _info
   61
   83#define AUI_JNI_STATIC_METHOD(ret_t, name, args) \
   84    static ret_t name (AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES, _, args)) { \
   85        static_assert(::aui::jni::convertible<ret_t>, "return type is required to be convertible"); \
   86        auto clazz = getClass();                 \
   87        auto e = ::aui::jni::env();              \
   88        const char* signature = ::aui::jni::signature_v<ret_t (AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES, _, args))>; \
   89        static auto methodId = e->GetStaticMethodID(clazz, #name, signature);    \
   90        if (methodId == 0) {                          \
   91            throw AException("no such static jni method: {} {}"_format(#name, signature)); \
   92        }                                         \
   93        return ::aui::jni::callStaticMethod<ret_t>(clazz, methodId AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES_CONTENTS, _, args)); \
   94    }
   95
  117#define AUI_JNI_METHOD(ret_t, name, args) \
  118    ret_t name (AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES, _, args)) { \
  119        static_assert(::aui::jni::convertible<ret_t>, "return type is required to be convertible"); \
  120        auto clazz = getClass();                 \
  121        auto e = ::aui::jni::env();              \
  122        const char* signature = ::aui::jni::signature_v<ret_t (AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES, _, args))>; \
  123        static auto methodId = e->GetMethodID(clazz, #name, signature);    \
  124        if (methodId == 0) {                          \
  125            throw AException("no such jni method: {} {}"_format(#name, signature)); \
  126        }                                         \
  127        return ::aui::jni::callMethod<ret_t>(this->asObject(), methodId AUI_PP_FOR_EACH(AUI_JNI_INTERNAL_OMIT_BRACES_CONTENTS, _, args)); \
  128    }
  129
  130#define AUI_JNI_INTERNAL_OMIT_BRACES(i, b, c) AUI_PP_COMMA_IF(i) AUI_PP_IDENTITY c
  131
  132#define AUI_JNI_INTERNAL_OMIT_BRACES_CONTENTS(i, b, c) , AUI_PP_EMPTY c