Commit 2ebca550 authored by Volker Krause's avatar Volker Krause
Browse files

Replace the special treatment of java::lang::String with a conversion trait

This extends the specialization of the property wrappers to anything we
have a matching native type for, including application custom types.
parent ed8cb6e1
......@@ -6,6 +6,7 @@
#include <kandroidextras/androidtypes.h>
#include <kandroidextras/jnisignature.h>
#include <kandroidextras/javatypes.h>
#include <QtTest/qtest.h>
......
......@@ -11,6 +11,7 @@
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniProperty>
#include <KAndroidExtras/JavaTypes>
#include <QAndroidJniObject>
......
......@@ -9,6 +9,7 @@
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniProperty>
#include <KAndroidExtras/JavaTypes>
namespace KAndroidExtras {
......
......@@ -9,6 +9,7 @@
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniProperty>
#include <KAndroidExtras/JavaTypes>
namespace KAndroidExtras {
......
......@@ -8,6 +8,7 @@
#include <KAndroidExtras/AndroidTypes>
#include <KAndroidExtras/JniSignature>
#include <KAndroidExtras/JavaTypes>
#include <QAndroidJniObject>
#include <QUrl>
......
......@@ -8,12 +8,25 @@
#define KANDROIDEXTRAS_JAVATYPES_H
#include <KAndroidExtras/JniTypes>
#include <KAndroidExtras/JniTypeTraits>
namespace KAndroidExtras {
JNI_TYPE(java, io, File)
JNI_TYPE(java, lang, String)
JNI_TYPE(java, util, Locale)
namespace Jni {
template <> struct converter<QString> {
typedef java::lang::String type;
static inline QAndroidJniObject convert(const QString &value) { return QAndroidJniObject::fromString(value); }
};
template <> struct converter<java::lang::String> {
typedef QString type;
static inline QString convert(const QAndroidJniObject &value) { return value.toString(); }
};
}
}
#endif // KANDROIDEXTRAS_JAVATYPES_H
......
......@@ -40,21 +40,17 @@ private: \
template <typename PropType, typename ClassType, typename NameHolder, bool BasicType> struct StaticProperty {};
template <typename PropType, typename ClassType, typename NameHolder>
struct StaticProperty<PropType, ClassType, NameHolder, false> {
inline operator QAndroidJniObject() const
inline QAndroidJniObject get() const
{
return QAndroidJniObject::getStaticObjectField(Jni::typeName<ClassType>(), Jni::typeName<NameHolder>(), Jni::signature<PropType>());
}
};
template <typename ClassType, typename NameHolder>
struct StaticProperty<java::lang::String, ClassType, NameHolder, false> {
inline operator QAndroidJniObject() const
{
return QAndroidJniObject::getStaticObjectField(Jni::typeName<ClassType>(), Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>());
return get();
}
inline operator QString() const
inline operator typename Jni::converter<PropType>::type() const
{
return QAndroidJniObject::getStaticObjectField(Jni::typeName<ClassType>(), Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>()).toString();
return Jni::converter<PropType>::convert(get());
}
};
......@@ -80,37 +76,30 @@ protected:
template <typename PropType, typename ClassType, typename NameHolder, typename OffsetHolder, bool BasicType> struct Property {};
template <typename PropType, typename ClassType, typename NameHolder, typename OffsetHolder>
class Property<PropType, ClassType, NameHolder, OffsetHolder, false> : public PropertyBase<ClassType, OffsetHolder> {
private:
struct _jni_NoType {};
public:
inline operator QAndroidJniObject() const
inline QAndroidJniObject get() const
{
return this->handle().getObjectField(Jni::typeName<NameHolder>(), Jni::signature<PropType>());
}
inline Property& operator=(const QAndroidJniObject &value)
{
this->handle().setField(Jni::typeName<NameHolder>(), Jni::signature<PropType>(), value.object());
return *this;
}
};
template <typename ClassType, typename NameHolder, typename OffsetHolder>
class Property<java::lang::String, ClassType, NameHolder, OffsetHolder, false> : public PropertyBase<ClassType, OffsetHolder> {
public:
inline operator QAndroidJniObject() const
{
return this->handle().getObjectField(Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>());
return get();
}
inline operator QString() const
inline operator typename Jni::converter<PropType>::type() const
{
return this->handle().getObjectField(Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>()).toString();
return Jni::converter<PropType>::convert(get());
}
inline Property& operator=(const QAndroidJniObject &value)
{
this->handle().setField(Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>(), value.object());
this->handle().setField(Jni::typeName<NameHolder>(), Jni::signature<PropType>(), value.object());
return *this;
}
inline Property& operator=(const QString &value)
inline Property& operator=(const typename std::conditional<std::is_same_v<typename Jni::converter<PropType>::type, void>, _jni_NoType, typename Jni::converter<PropType>::type>::type &value)
{
this->handle().setField(Jni::typeName<NameHolder>(), Jni::signature<java::lang::String>(), QAndroidJniObject::fromString(value).object());
this->handle().setField(Jni::typeName<NameHolder>(), Jni::signature<PropType>(), Jni::reverse_converter<PropType>::type::convert(value).object());
return *this;
}
};
......
......@@ -61,9 +61,6 @@ namespace KAndroidExtras {
/** Macro to define a nested Java class with its corresponding JNI signature string. */
#define JNI_NESTED_TYPE(...) JNI_NESTED_TYPE_(PP_NARG(__VA_ARGS__), "", __VA_ARGS__)
// defined here rather than as part of the java.* bindings as this is de-facto a basic built-in type
JNI_TYPE(java, lang, String)
namespace Jni
{
/** Returns the JNI type name of the given template argument. */
......
......@@ -7,6 +7,8 @@
#ifndef KANDROIDEXTRAS_JNITYPETRAITS_H
#define KANDROIDEXTRAS_JNITYPETRAITS_H
#include "jnitypes.h"
#include <QAndroidJniObject>
#include <type_traits>
......@@ -28,6 +30,15 @@ template <> struct is_basic_type<jlong> : std::true_type {};
template <> struct is_basic_type<jfloat> : std::true_type {};
template <> struct is_basic_type<jdouble> : std::true_type {};
template <typename T> struct converter {
typedef void type;
};
template <typename T> struct reverse_converter {
typedef converter<typename converter<T>::type> type;
};
}
}
......
Markdown is supported
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