Skip to content

Commit

Permalink
Support JArrayClass without ::javaobject and document its use (#20)
Browse files Browse the repository at this point in the history
Summary:
- Change the static_assert to allow JavaClass types.
- Change pointer cast in getElement to use JniType.
- In setElement, use new toPlainJniReference that converts JavaClass
  values to plain JNI references using ReprAccess.
- NOTE: Maybe we should do this last one in JMethod::operator() as well,
  since it currently passes JavaClass values directly to env->Invoke*

Pull Request resolved: facebookincubator/fbjni#20

Test Plan: CI

Reviewed By: mhorowitz

Differential Revision: D18121242

Pulled By: dreiss

fbshipit-source-id: 634e92ab55a3bbf05efac5ac61193fb27f4d1445
  • Loading branch information
dreiss authored and facebook-github-bot committed Oct 28, 2019
1 parent 73c7da6 commit 4c655fa
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
6 changes: 3 additions & 3 deletions first-party/fbjni/cxx/fbjni/detail/CoreClasses-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,16 @@ auto JArrayClass<T>::newArray(size_t size) -> local_ref<javaobject> {
}

template<typename T>
inline void JArrayClass<T>::setElement(size_t idx, const T& value) {
inline void JArrayClass<T>::setElement(size_t idx, T value) {
const auto env = Environment::current();
env->SetObjectArrayElement(this->self(), idx, value);
env->SetObjectArrayElement(this->self(), idx, detail::toPlainJniReference(value));
}

template<typename T>
inline local_ref<T> JArrayClass<T>::getElement(size_t idx) {
const auto env = Environment::current();
auto rawElement = env->GetObjectArrayElement(this->self(), idx);
return adopt_local(static_cast<T>(rawElement));
return adopt_local(static_cast<JniType<T>>(rawElement));
}

template<typename T>
Expand Down
8 changes: 5 additions & 3 deletions first-party/fbjni/cxx/fbjni/detail/CoreClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,10 @@ class JTypeArray : public JavaClass<JTypeArray, JArray, jobjectArray> {
template<typename T>
class JArrayClass : public JavaClass<JArrayClass<T>, detail::JTypeArray> {
public:
static_assert(is_plain_jni_reference<T>(), "");
// javaentry is the jni type of an entry in the array (i.e. jint).
static_assert(
IsPlainJniReference<JniType<T>>(),
"Element type must be a JNI reference or JavaClass type.");
// javaentry is the jni type of an entry in the array (i.e. JObject).
using javaentry = T;
// javaobject is the jni type of the array.
using javaobject = typename JavaClass<JArrayClass<T>, detail::JTypeArray>::javaobject;
Expand All @@ -431,7 +433,7 @@ class JArrayClass : public JavaClass<JArrayClass<T>, detail::JTypeArray> {

/// Assign an object to the array.
/// Typically you will use the shorthand (*ref)[idx]=value;
void setElement(size_t idx, const T& value);
void setElement(size_t idx, T value);

/// Read an object from the array.
/// Typically you will use the shorthand
Expand Down
10 changes: 10 additions & 0 deletions first-party/fbjni/cxx/fbjni/detail/MetaConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ inline JniType<T> callToJni(local_ref<T>&& sref) {
return sref.get();
}

template<typename T>
enable_if_t<IsPlainJniReference<T>(), T> toPlainJniReference(T obj) {
return obj;
}

template<typename T>
enable_if_t<IsJavaClassType<T>(), JniType<T>> toPlainJniReference(T repr) {
return ReprAccess<T>::get(repr);
}

// Normally, pass through types unmolested.
template <typename T, typename Enabled = void>
struct Convert {
Expand Down
1 change: 1 addition & 0 deletions first-party/fbjni/docs/quickref_toc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ basic_methods Basic method usage (Java to C++ and C++ to Java)
primitives Methods using Java primitives
strings Methods using Java Strings
primitive_arrays Working with arrays of primitives
class_arrays Working with arrays of objects
references References
nested_class Defining a nested class
inheritance Defining a child class
Expand Down
20 changes: 20 additions & 0 deletions first-party/fbjni/test/jni/doc_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ struct JDataHolder : JavaClass<JDataHolder> {
}
}
// END

local_ref<JString> getStr() {
static const auto cls = javaClassStatic();
static const auto sField = cls->getField<JString>("s");
return getFieldValue(sField);
}
};


Expand Down Expand Up @@ -222,6 +228,20 @@ struct DocTests : JavaClass<DocTests> {
}
// END

// SECTION class_arrays
static local_ref<JArrayClass<JString>> classArrays(
alias_ref<JClass> clazz,
alias_ref<JArrayClass<JDataHolder>> arr) {
size_t size = arr->size();
local_ref<JArrayClass<JString>> ret = JArrayClass<JString>::newArray(size);
for (int i = 0; i < size; ++i) {
local_ref<JString> str = arr->getElement(i)->getStr();
ret->setElement(i, *str);
}
return ret;
}
// END

// SECTION references
/* MARKDOWN
Expand Down

0 comments on commit 4c655fa

Please sign in to comment.