commit changes in fbjni
This commit is contained in:
@@ -9,7 +9,7 @@ android {
|
||||
targetSdkVersion rootProject.targetSdkVersion
|
||||
|
||||
ndk {
|
||||
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
||||
abiFilters 'arm64-v8a', 'x86'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include <fb/assert.h>
|
||||
#include <fb/visibility.h>
|
||||
|
||||
#include "CoreClasses.h"
|
||||
|
||||
namespace facebook {
|
||||
@@ -23,45 +25,13 @@
|
||||
virtual ~BaseHybridClass() {}
|
||||
};
|
||||
|
||||
struct HybridData : public JavaClass<HybridData> {
|
||||
struct FBEXPORT HybridData : public JavaClass<HybridData> {
|
||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridData;";
|
||||
void setNativePointer(std::unique_ptr<BaseHybridClass> new_value);
|
||||
BaseHybridClass* getNativePointer();
|
||||
static local_ref<HybridData> create();
|
||||
};
|
||||
|
||||
class HybridDestructor : public JavaClass<HybridDestructor> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/HybridData$Destructor;";
|
||||
|
||||
detail::BaseHybridClass* getNativePointer();
|
||||
|
||||
void setNativePointer(std::unique_ptr<detail::BaseHybridClass> new_value);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
detail::BaseHybridClass* getNativePointer(T t) {
|
||||
return getHolder(t)->getNativePointer();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void setNativePointer(T t, std::unique_ptr<detail::BaseHybridClass> new_value) {
|
||||
getHolder(t)->setNativePointer(std::move(new_value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
local_ref<HybridDestructor> getHolder(T t) {
|
||||
static auto holderField = t->getClass()->template getField<HybridDestructor::javaobject>("mDestructor");
|
||||
return t->getFieldValue(holderField);
|
||||
}
|
||||
|
||||
// JavaClass for HybridClassBase
|
||||
struct HybridClassBase : public JavaClass<HybridClassBase> {
|
||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridClassBase;";
|
||||
|
||||
static bool isHybridClassBase(alias_ref<jclass> jclass) {
|
||||
return HybridClassBase::javaClassStatic()->isAssignableFrom(jclass);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base, typename Enabled = void>
|
||||
struct HybridTraits {
|
||||
// This static assert should actually always fail if we don't use one of the
|
||||
@@ -96,7 +66,7 @@
|
||||
|
||||
// convert to HybridClass* from jhybridobject
|
||||
template <typename T>
|
||||
struct Convert<
|
||||
struct FBEXPORT Convert<
|
||||
T, typename std::enable_if<
|
||||
std::is_base_of<BaseHybridClass, typename std::remove_pointer<T>::type>::value>::type> {
|
||||
typedef typename std::remove_pointer<T>::type::jhybridobject jniType;
|
||||
@@ -121,7 +91,7 @@
|
||||
}
|
||||
|
||||
template <typename T, typename Base = detail::BaseHybridClass>
|
||||
class HybridClass : public detail::HybridTraits<Base>::CxxBase {
|
||||
class FBEXPORT HybridClass : public detail::HybridTraits<Base>::CxxBase {
|
||||
public:
|
||||
struct JavaPart : JavaClass<JavaPart, typename detail::HybridTraits<Base>::JavaBase> {
|
||||
// At this point, T is incomplete, and so we cannot access
|
||||
@@ -138,7 +108,6 @@
|
||||
T* cthis();
|
||||
|
||||
friend class HybridClass;
|
||||
friend T;
|
||||
};
|
||||
|
||||
using jhybridobject = typename JavaPart::javaobject;
|
||||
@@ -168,7 +137,7 @@
|
||||
|
||||
static local_ref<detail::HybridData> makeHybridData(std::unique_ptr<T> cxxPart) {
|
||||
auto hybridData = detail::HybridData::create();
|
||||
setNativePointer(hybridData, std::move(cxxPart));
|
||||
hybridData->setNativePointer(std::move(cxxPart));
|
||||
return hybridData;
|
||||
}
|
||||
|
||||
@@ -177,11 +146,6 @@
|
||||
return makeHybridData(std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static void setCxxInstance(alias_ref<jhybridobject> o, Args&&... args) {
|
||||
setNativePointer(o, std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
|
||||
}
|
||||
|
||||
public:
|
||||
// Factory method for creating a hybrid object where the arguments
|
||||
// are used to initialize the C++ part directly without passing them
|
||||
@@ -195,20 +159,8 @@
|
||||
// C++ object fails, or any JNI methods throw.
|
||||
template <typename... Args>
|
||||
static local_ref<JavaPart> newObjectCxxArgs(Args&&... args) {
|
||||
static bool isHybrid = detail::HybridClassBase::isHybridClassBase(javaClassStatic());
|
||||
auto cxxPart = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
|
||||
local_ref<JavaPart> result;
|
||||
if (isHybrid) {
|
||||
result = JavaPart::newInstance();
|
||||
setNativePointer(result, std::move(cxxPart));
|
||||
}
|
||||
else {
|
||||
auto hybridData = makeHybridData(std::move(cxxPart));
|
||||
result = JavaPart::newInstance(hybridData);
|
||||
}
|
||||
|
||||
return result;
|
||||
auto hybridData = makeCxxInstance(std::forward<Args>(args)...);
|
||||
return JavaPart::newInstance(hybridData);
|
||||
}
|
||||
|
||||
// TODO? Create reusable interface for Allocatable classes and use it to
|
||||
@@ -241,23 +193,17 @@
|
||||
|
||||
template <typename T, typename B>
|
||||
inline T* HybridClass<T, B>::JavaPart::cthis() {
|
||||
detail::BaseHybridClass* result = 0;
|
||||
static bool isHybrid = detail::HybridClassBase::isHybridClassBase(this->getClass());
|
||||
if (isHybrid) {
|
||||
result = getNativePointer(this);
|
||||
} else {
|
||||
static auto field =
|
||||
HybridClass<T, B>::JavaPart::javaClassStatic()->template getField<detail::HybridData::javaobject>("mHybridData");
|
||||
auto hybridData = this->getFieldValue(field);
|
||||
if (!hybridData) {
|
||||
throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException");
|
||||
}
|
||||
|
||||
result = getNativePointer(hybridData);
|
||||
}
|
||||
|
||||
// I'd like to use dynamic_cast here, but -fno-rtti is the default.
|
||||
return static_cast<T*>(result);
|
||||
T* value = static_cast<T*>(hybridData->getNativePointer());
|
||||
// This would require some serious programmer error.
|
||||
FBASSERTMSGF(value != 0, "Incorrect C++ type in hybrid field");
|
||||
return value;
|
||||
};
|
||||
|
||||
template <typename T, typename B>
|
||||
|
||||
Reference in New Issue
Block a user