Commit 565210be authored by Volker Krause's avatar Volker Krause
Browse files

Factor out JNI object wrapper for reuse in array iterators

parent 6e0b848a
Pipeline #181470 passed with stage
in 1 minute and 45 seconds
......@@ -61,7 +61,7 @@ ecm_generate_headers(KAndroidExtras_java_FORWARDING_HEADERS
ecm_generate_headers(KAndroidExtras_jni_FORWARDING_HEADERS
HEADER_NAMES
JniArray
JniCommon
JniObject
JniMethod
JniProperty
JniSignature
......
......@@ -8,6 +8,7 @@
#define KANDROIDEXTRAS_MANIFESTPERMISSIONM_H
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniObject>
#include <KAndroidExtras/JniProperty>
#include <KAndroidExtras/JavaTypes>
......
......@@ -8,6 +8,7 @@
#define KANDROIDEXTRAS_OPENABLECOLUMNS_H
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniObject>
#include <KAndroidExtras/JniProperty>
#include <KAndroidExtras/JavaTypes>
......
......@@ -7,8 +7,8 @@
// list all headers here that have no .cpp file
// this only serves as a guarantee that these headers actually compile
#include "jniarray.h"
#include "jnicommon.h"
#include "jnimethod.h"
#include "jniobject.h"
#include "jniproperty.h"
#include "jnisignature.h"
#include "jnitypes.h"
......
......@@ -7,6 +7,7 @@
#define KANDROIDEXTRAS_JNIMETHOD_H
#include "jniarray.h"
#include "jniobject.h"
#include "jnitypetraits.h"
#include <QAndroidJniObject>
......@@ -78,24 +79,6 @@ namespace Internal {
template <typename T> inline constexpr T toFinalCallArgument(T value) { return value; }
inline jobject toFinalCallArgument(const QAndroidJniObject &value) { return value.object(); }
// method return value wrapper for complex types we can implicitly convert
// this defers conversion until it's actually needed, so we can do direct JNI handle pass-through
// when chaining calls
template <typename RetT>
class ReturnValue {
public:
explicit inline ReturnValue(const QAndroidJniObject &v) : value(v) {}
inline operator QAndroidJniObject() const {
return value;
}
inline operator typename Jni::converter<RetT>::type() const {
return Jni::converter<RetT>::convert(value);
}
private:
QAndroidJniObject value;
};
// return type conversion
template <typename RetT>
struct call_return {
......@@ -103,12 +86,12 @@ namespace Internal {
static inline constexpr bool is_convertible = !std::is_same_v<typename Jni::converter<RetT>::type, void>;
typedef std::conditional_t<is_basic, RetT, QAndroidJniObject> JniReturnT;
typedef std::conditional_t<is_basic || !is_convertible, JniReturnT, ReturnValue<RetT>> CallReturnT;
typedef std::conditional_t<is_basic || !is_convertible, JniReturnT, Jni::Object<RetT>> CallReturnT;
static inline constexpr CallReturnT toReturnValue(JniReturnT value)
{
if constexpr (is_convertible) {
return ReturnValue<RetT>(value);
return Jni::Object<RetT>(value);
} else {
return value;
}
......
......@@ -7,14 +7,29 @@
#ifndef KANDROIDEXTRAS_JNICOMMON_H
#define KANDROIDEXTRAS_JNICOMMON_H
#include "jnitypetraits.h"
namespace KAndroidExtras {
namespace Jni {
/** Wrapper type for array return values (which we cannot specify using [] syntax). */
template <typename T> class Array;
}
/** Wrapper for JNI objects with a convertible C++ type.
* This provides implicit on-demand conversion to the C++ type, for types
* that don't have a manually defined wrapper.
*/
template <typename T>
class Object {
public:
explicit inline Object(const QAndroidJniObject &v) : m_handle(v) {}
inline operator QAndroidJniObject() const {
return m_handle;
}
inline operator typename Jni::converter<T>::type() const {
return Jni::converter<T>::convert(m_handle);
}
private:
QAndroidJniObject m_handle;
};
/** Annotates a class for holding JNI method or property wrappers.
*
......@@ -33,5 +48,6 @@ private: \
friend constexpr const char* KAndroidExtras::Jni::typeName<Class>();
}
}
#endif
......@@ -7,7 +7,6 @@
#ifndef KANDROIDEXTRAS_JNIPROPERTIES_H
#define KANDROIDEXTRAS_JNIPROPERTIES_H
#include "jnicommon.h"
#include "jnisignature.h"
#include "jnitypes.h"
#include "jnitypetraits.h"
......@@ -18,6 +17,10 @@
namespace KAndroidExtras {
namespace Jni {
template <typename T> class Array;
}
/** @cond internal */
namespace Internal {
......
......@@ -7,7 +7,6 @@
#ifndef KANDROIDEXTRAS_JNISIGNATURE_H
#define KANDROIDEXTRAS_JNISIGNATURE_H
#include "jnicommon.h"
#include "jnitypes.h"
#include <jni.h>
......@@ -16,6 +15,10 @@
namespace KAndroidExtras {
namespace Jni {
template <typename T> class Array;
}
/** @cond internal */
namespace Internal {
......
......@@ -7,7 +7,6 @@
#ifndef KANDROIDEXTRAS_JNITYPETRAITS_H
#define KANDROIDEXTRAS_JNITYPETRAITS_H
#include "jnicommon.h"
#include "jnitypes.h"
#include <QAndroidJniObject>
......@@ -18,6 +17,8 @@ namespace KAndroidExtras {
namespace Jni {
template <typename T> class Array;
/** Type trait to check whether @tparam T is a basic JNI type or an object type.
* Those two typically need different handling both with JNI API and with QAndroidJniObject API.
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment