Updated fbjni since its outdated

This commit is contained in:
Pritesh Nandgaonkar
2018-06-14 22:23:11 +01:00
parent 51c36cf2bd
commit c179078acd
3 changed files with 247 additions and 191 deletions

View File

@@ -32,13 +32,13 @@ target_include_directories(${PACKAGE_NAME} PUBLIC "./")
set(libjnihack_DIR ${CMAKE_SOURCE_DIR}/../libs/jni-hack/)
set(libfbjni_DIR ${CMAKE_SOURCE_DIR}/../libs/fbjni/src/main/cpp/include/)
set(libsonar_DIR ${CMAKE_SOURCE_DIR}/../xplat/)
set(third_party_ndk build/third-party-ndk)
set(third_party_ndk ${PROJECT_SOURCE_DIR}/build/third-party-ndk)
set(libfolly_DIR ${third_party_ndk}/folly/)
set(glog_DIR ${third_party_ndk}/glog)
set(BOOST_DIR ${third_party_ndk}/boost/boost_1_63_0/)
set(LIBEVENT_DIR ${third_party_ndk}/LibEvent/libevent-1.0.0/include/)
set(LIBEVENT_DIR ${third_party_ndk}/LibEvent/libevent-release-2.1.9/)
message(STATUS "AAAANDROID LIBEVENT_DIR => " ${LIBEVENT_DIR})
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
set(fbjni_build_DIR ${build_DIR}/fbjni/${ANDROID_ABI})
@@ -60,7 +60,9 @@ target_include_directories(${PACKAGE_NAME} PRIVATE
${glog_DIR}/glog-0.3.5/src/
${BOOST_DIR}
${BOOST_DIR}/../
${LIBEVENT_DIR}
${LIBEVENT_DIR}/
${LIBEVENT_DIR}/include/
${LIBEVENT_DIR}/include/event2
)
target_link_libraries(${PACKAGE_NAME} fb sonarcpp)

View File

@@ -5,14 +5,12 @@
* 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 {
@@ -25,13 +23,45 @@ public:
virtual ~BaseHybridClass() {}
};
struct FBEXPORT HybridData : public JavaClass<HybridData> {
struct 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
@@ -66,7 +96,7 @@ struct HybridTraits<
// convert to HybridClass* from jhybridobject
template <typename T>
struct FBEXPORT Convert<
struct 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;
@@ -91,7 +121,7 @@ struct RefReprType<T, typename std::enable_if<std::is_base_of<BaseHybridClass, T
}
template <typename T, typename Base = detail::BaseHybridClass>
class FBEXPORT HybridClass : public detail::HybridTraits<Base>::CxxBase {
class 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
@@ -108,6 +138,7 @@ public:
T* cthis();
friend class HybridClass;
friend T;
};
using jhybridobject = typename JavaPart::javaobject;
@@ -137,7 +168,7 @@ protected:
static local_ref<detail::HybridData> makeHybridData(std::unique_ptr<T> cxxPart) {
auto hybridData = detail::HybridData::create();
hybridData->setNativePointer(std::move(cxxPart));
setNativePointer(hybridData, std::move(cxxPart));
return hybridData;
}
@@ -146,6 +177,11 @@ protected:
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
@@ -159,8 +195,20 @@ public:
// C++ object fails, or any JNI methods throw.
template <typename... Args>
static local_ref<JavaPart> newObjectCxxArgs(Args&&... args) {
auto hybridData = makeCxxInstance(std::forward<Args>(args)...);
return JavaPart::newInstance(hybridData);
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;
}
// TODO? Create reusable interface for Allocatable classes and use it to
@@ -193,17 +241,23 @@ public:
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.
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;
return static_cast<T*>(result);
};
template <typename T, typename B>