mirror of https://github.com/axmolengine/axmol.git
153 lines
6.7 KiB
C++
153 lines
6.7 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cassert>
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include <jni.h>
|
|
|
|
namespace jni
|
|
{
|
|
template < class W > struct Wrapper;
|
|
|
|
template < class W, class U >
|
|
auto Wrap(U&& u)
|
|
{
|
|
return Wrapper<W>().Wrap(std::forward<U>(u));
|
|
}
|
|
|
|
template < class W >
|
|
auto Unwrap(W&& w)
|
|
{
|
|
return Wrapper<typename std::decay<W>::type>().Unwrap(std::forward<W>(w));
|
|
}
|
|
|
|
template < class T >
|
|
using UnwrappedType = decltype(Unwrap<T>(std::declval<T>()));
|
|
|
|
|
|
template < class T >
|
|
struct PrimitiveTypeWrapper
|
|
{
|
|
T Wrap(T t) const { return t; }
|
|
T Unwrap(T t) const { return t; }
|
|
};
|
|
|
|
template <> struct Wrapper< jboolean > : PrimitiveTypeWrapper< jboolean > {};
|
|
template <> struct Wrapper< jbyte > : PrimitiveTypeWrapper< jbyte > {};
|
|
template <> struct Wrapper< jchar > : PrimitiveTypeWrapper< jchar > {};
|
|
template <> struct Wrapper< jshort > : PrimitiveTypeWrapper< jshort > {};
|
|
template <> struct Wrapper< jint > : PrimitiveTypeWrapper< jint > {};
|
|
template <> struct Wrapper< jlong > : PrimitiveTypeWrapper< jlong > {};
|
|
template <> struct Wrapper< jfloat > : PrimitiveTypeWrapper< jfloat > {};
|
|
template <> struct Wrapper< jdouble > : PrimitiveTypeWrapper< jdouble > {};
|
|
|
|
|
|
template <>
|
|
struct Wrapper<const char16_t*>
|
|
{
|
|
const char16_t* Wrap(const jchar* s) const { return reinterpret_cast<const char16_t*>(s); }
|
|
const jchar* Unwrap(const char16_t* s) const { return reinterpret_cast<const jchar*>(s); }
|
|
};
|
|
|
|
template <>
|
|
struct Wrapper<char16_t*>
|
|
{
|
|
char16_t* Wrap(jchar* s) const { return reinterpret_cast<char16_t*>(s); }
|
|
jchar* Unwrap(char16_t* s) const { return reinterpret_cast<jchar*>(s); }
|
|
};
|
|
|
|
|
|
template <>
|
|
struct Wrapper<jsize>
|
|
{
|
|
jsize Wrap(::jsize s) const
|
|
{
|
|
if (s < 0)
|
|
throw std::range_error("::jsize < 0");
|
|
return static_cast<jsize>(s);
|
|
}
|
|
|
|
::jsize Unwrap(jsize s) const
|
|
{
|
|
if (s > std::numeric_limits<::jsize>::max())
|
|
throw std::range_error("jsize > max");
|
|
return static_cast<::jsize>(s);
|
|
}
|
|
};
|
|
|
|
|
|
template < class W, class U >
|
|
struct ReferenceTypeWrapper
|
|
{
|
|
W* Wrap(U u) const { return reinterpret_cast<W*>(u); }
|
|
U Unwrap(W* w) const { return reinterpret_cast<U>(w); }
|
|
};
|
|
|
|
template <> struct Wrapper< jobject* > : ReferenceTypeWrapper< jobject, ::jobject > {};
|
|
template <> struct Wrapper< jclass* > : ReferenceTypeWrapper< jclass, ::jclass > {};
|
|
template <> struct Wrapper< jstring* > : ReferenceTypeWrapper< jstring, ::jstring > {};
|
|
template <> struct Wrapper< jthrowable* > : ReferenceTypeWrapper< jthrowable, ::jthrowable > {};
|
|
|
|
template <> struct Wrapper< jarray< jobject >* > : ReferenceTypeWrapper< jarray< jobject >, ::jobjectArray > {};
|
|
template <> struct Wrapper< jarray< jboolean >* > : ReferenceTypeWrapper< jarray< jboolean >, ::jbooleanArray > {};
|
|
template <> struct Wrapper< jarray< jbyte >* > : ReferenceTypeWrapper< jarray< jbyte >, ::jbyteArray > {};
|
|
template <> struct Wrapper< jarray< jchar >* > : ReferenceTypeWrapper< jarray< jchar >, ::jcharArray > {};
|
|
template <> struct Wrapper< jarray< jshort >* > : ReferenceTypeWrapper< jarray< jshort >, ::jshortArray > {};
|
|
template <> struct Wrapper< jarray< jint >* > : ReferenceTypeWrapper< jarray< jint >, ::jintArray > {};
|
|
template <> struct Wrapper< jarray< jlong >* > : ReferenceTypeWrapper< jarray< jlong >, ::jlongArray > {};
|
|
template <> struct Wrapper< jarray< jfloat >* > : ReferenceTypeWrapper< jarray< jfloat >, ::jfloatArray > {};
|
|
template <> struct Wrapper< jarray< jdouble >* > : ReferenceTypeWrapper< jarray< jdouble >, ::jdoubleArray > {};
|
|
|
|
template <> struct Wrapper< jfieldID* > : ReferenceTypeWrapper< jfieldID, ::jfieldID > {};
|
|
template <> struct Wrapper< jmethodID* > : ReferenceTypeWrapper< jmethodID, ::jmethodID > {};
|
|
|
|
|
|
// Allow references to be unwrapped to pointers to the underlying type, but not the
|
|
// reverse, because dereferences should be explicit, with null checks where necessary.
|
|
|
|
template < class W, class U >
|
|
struct ReferenceTypeUnwrapper
|
|
{
|
|
U Unwrap(W& w) const { return reinterpret_cast<U>(&w); }
|
|
};
|
|
|
|
template <> struct Wrapper< jobject > : ReferenceTypeUnwrapper< jobject, ::jobject > {};
|
|
template <> struct Wrapper< jclass > : ReferenceTypeUnwrapper< jclass, ::jclass > {};
|
|
template <> struct Wrapper< jstring > : ReferenceTypeUnwrapper< jstring, ::jstring > {};
|
|
template <> struct Wrapper< jthrowable > : ReferenceTypeUnwrapper< jthrowable, ::jthrowable > {};
|
|
|
|
template <> struct Wrapper< jarray< jobject > > : ReferenceTypeUnwrapper< jarray< jobject >, ::jobjectArray > {};
|
|
template <> struct Wrapper< jarray< jboolean > > : ReferenceTypeUnwrapper< jarray< jboolean >, ::jbooleanArray > {};
|
|
template <> struct Wrapper< jarray< jbyte > > : ReferenceTypeUnwrapper< jarray< jbyte >, ::jbyteArray > {};
|
|
template <> struct Wrapper< jarray< jchar > > : ReferenceTypeUnwrapper< jarray< jchar >, ::jcharArray > {};
|
|
template <> struct Wrapper< jarray< jshort > > : ReferenceTypeUnwrapper< jarray< jshort >, ::jshortArray > {};
|
|
template <> struct Wrapper< jarray< jint > > : ReferenceTypeUnwrapper< jarray< jint >, ::jintArray > {};
|
|
template <> struct Wrapper< jarray< jlong > > : ReferenceTypeUnwrapper< jarray< jlong >, ::jlongArray > {};
|
|
template <> struct Wrapper< jarray< jfloat > > : ReferenceTypeUnwrapper< jarray< jfloat >, ::jfloatArray > {};
|
|
template <> struct Wrapper< jarray< jdouble > > : ReferenceTypeUnwrapper< jarray< jdouble >, ::jdoubleArray > {};
|
|
|
|
template <> struct Wrapper< jfieldID > : ReferenceTypeUnwrapper< jfieldID, ::jfieldID > {};
|
|
template <> struct Wrapper< jmethodID > : ReferenceTypeUnwrapper< jmethodID, ::jmethodID > {};
|
|
|
|
|
|
template < class T, class R, class... Args >
|
|
struct Wrapper< JNINativeMethod< R (JNIEnv*, T*, Args...) > >
|
|
{
|
|
::JNINativeMethod Unwrap(JNINativeMethod<R (JNIEnv*, T*, Args...)> method) const
|
|
{
|
|
return { const_cast<char*>(method.name), const_cast<char*>(method.signature), reinterpret_cast<void*>(method.fnPtr) };
|
|
}
|
|
};
|
|
|
|
|
|
template <>
|
|
struct Wrapper<version>
|
|
{
|
|
version Wrap(::jint v) const { return static_cast<version>(v); }
|
|
::jint Unwrap(version v) const { return static_cast<::jint>(v); }
|
|
};
|
|
}
|