feat: Replace *NativeMap
and *NativeArray
with Map<K,V>
and List<T>
for faster JSI -> JNI calls (#1720)
Replaces `ReadableNativeMap`/`WritableNativeMap` with `Map<String, Object>` and `ReadableNativeArray`/`WritableNativeArray` with `List<Object>`, making the JSI -> JNI conversion a bit faster and more logical. Also, we could now convert Array Buffers or HostObjects if we wanted to.
This commit is contained in:
parent
f87bc74de1
commit
dfb86e174b
@ -24,18 +24,19 @@ add_library(
|
|||||||
${PACKAGE_NAME}
|
${PACKAGE_NAME}
|
||||||
SHARED
|
SHARED
|
||||||
../cpp/JSITypedArray.cpp
|
../cpp/JSITypedArray.cpp
|
||||||
src/main/cpp/FrameHostObject.cpp
|
|
||||||
src/main/cpp/FrameProcessorPluginHostObject.cpp
|
|
||||||
src/main/cpp/JSIJNIConversion.cpp
|
|
||||||
src/main/cpp/VisionCamera.cpp
|
src/main/cpp/VisionCamera.cpp
|
||||||
src/main/cpp/VisionCameraProxy.cpp
|
# Frame Processor
|
||||||
|
src/main/cpp/frameprocessor/FrameHostObject.cpp
|
||||||
|
src/main/cpp/frameprocessor/FrameProcessorPluginHostObject.cpp
|
||||||
|
src/main/cpp/frameprocessor/JSIJNIConversion.cpp
|
||||||
|
src/main/cpp/frameprocessor/VisionCameraProxy.cpp
|
||||||
|
src/main/cpp/frameprocessor/java-bindings/JFrame.cpp
|
||||||
|
src/main/cpp/frameprocessor/java-bindings/JFrameProcessor.cpp
|
||||||
|
src/main/cpp/frameprocessor/java-bindings/JFrameProcessorPlugin.cpp
|
||||||
|
src/main/cpp/frameprocessor/java-bindings/JVisionCameraProxy.cpp
|
||||||
|
src/main/cpp/frameprocessor/java-bindings/JVisionCameraScheduler.cpp
|
||||||
|
# Skia Frame Processor
|
||||||
src/main/cpp/skia/SkiaRenderer.cpp
|
src/main/cpp/skia/SkiaRenderer.cpp
|
||||||
src/main/cpp/java-bindings/JFrame.cpp
|
|
||||||
src/main/cpp/java-bindings/JFrameProcessor.cpp
|
|
||||||
src/main/cpp/java-bindings/JFrameProcessorPlugin.cpp
|
|
||||||
src/main/cpp/java-bindings/JHashMap.cpp
|
|
||||||
src/main/cpp/java-bindings/JVisionCameraProxy.cpp
|
|
||||||
src/main/cpp/java-bindings/JVisionCameraScheduler.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Header Search Paths (includes)
|
# Header Search Paths (includes)
|
||||||
@ -44,6 +45,9 @@ target_include_directories(
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
"../cpp"
|
"../cpp"
|
||||||
"src/main/cpp"
|
"src/main/cpp"
|
||||||
|
"src/main/cpp/frameprocessor"
|
||||||
|
"src/main/cpp/frameprocessor/java-bindings"
|
||||||
|
"src/main/cpp/skia"
|
||||||
"${NODE_MODULES_DIR}/react-native/ReactCommon"
|
"${NODE_MODULES_DIR}/react-native/ReactCommon"
|
||||||
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
|
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
|
||||||
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/react/turbomodule" # <-- CallInvokerHolder JNI wrapper
|
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/react/turbomodule" # <-- CallInvokerHolder JNI wrapper
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <fbjni/fbjni.h>
|
#include <fbjni/fbjni.h>
|
||||||
#include "java-bindings/JVisionCameraScheduler.h"
|
#include "JVisionCameraScheduler.h"
|
||||||
#include "java-bindings/JFrameProcessor.h"
|
#include "JFrameProcessor.h"
|
||||||
#include "java-bindings/JVisionCameraProxy.h"
|
#include "JVisionCameraProxy.h"
|
||||||
#include "VisionCameraProxy.h"
|
#include "VisionCameraProxy.h"
|
||||||
#include "skia/SkiaRenderer.h"
|
#include "SkiaRenderer.h"
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
return facebook::jni::initialize(vm, [] {
|
return facebook::jni::initialize(vm, [] {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "java-bindings/JFrame.h"
|
#include "JFrame.h"
|
||||||
|
|
||||||
namespace vision {
|
namespace vision {
|
||||||
|
|
@ -34,7 +34,7 @@ jsi::Value FrameProcessorPluginHostObject::get(jsi::Runtime& runtime, const jsi:
|
|||||||
auto frame = frameHostObject->frame;
|
auto frame = frameHostObject->frame;
|
||||||
|
|
||||||
// Options are second argument (possibly undefined)
|
// Options are second argument (possibly undefined)
|
||||||
local_ref<react::ReadableNativeMap::javaobject> options = nullptr;
|
local_ref<JMap<jstring, jobject>> options = nullptr;
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
options = JSIJNIConversion::convertJSIObjectToJNIMap(runtime, arguments[1].asObject(runtime));
|
options = JSIJNIConversion::convertJSIObjectToJNIMap(runtime, arguments[1].asObject(runtime));
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include "java-bindings/JFrameProcessorPlugin.h"
|
#include "JFrameProcessorPlugin.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <fbjni/fbjni.h>
|
#include <fbjni/fbjni.h>
|
||||||
#include <vector>
|
#include <vector>
|
@ -13,25 +13,71 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <react/jni/NativeMap.h>
|
|
||||||
#include <react/jni/ReadableNativeMap.h>
|
|
||||||
#include <react/jni/WritableNativeMap.h>
|
|
||||||
|
|
||||||
#include <jsi/JSIDynamic.h>
|
|
||||||
#include <folly/dynamic.h>
|
|
||||||
|
|
||||||
#include "FrameHostObject.h"
|
#include "FrameHostObject.h"
|
||||||
#include "java-bindings/JFrame.h"
|
#include "JFrame.h"
|
||||||
#include "java-bindings/JArrayList.h"
|
|
||||||
#include "java-bindings/JHashMap.h"
|
|
||||||
|
|
||||||
namespace vision {
|
namespace vision {
|
||||||
|
|
||||||
using namespace facebook;
|
using namespace facebook;
|
||||||
|
|
||||||
jni::local_ref<react::ReadableNativeMap::javaobject> JSIJNIConversion::convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object) {
|
jni::local_ref<jni::JMap<jstring, jobject>> JSIJNIConversion::convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object) {
|
||||||
auto dynamic = jsi::dynamicFromValue(runtime, jsi::Value(runtime, object));
|
auto propertyNames = object.getPropertyNames(runtime);
|
||||||
return react::ReadableNativeMap::createWithContents(std::move(dynamic));
|
auto size = propertyNames.size(runtime);
|
||||||
|
auto hashMap = jni::JHashMap<jstring, jobject>::create();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
auto propName = propertyNames.getValueAtIndex(runtime, i).asString(runtime);
|
||||||
|
auto key = jni::make_jstring(propName.utf8(runtime));
|
||||||
|
auto value = object.getProperty(runtime, propName);
|
||||||
|
|
||||||
|
if (value.isNull() || value.isUndefined()) {
|
||||||
|
// null
|
||||||
|
|
||||||
|
hashMap->put(key, nullptr);
|
||||||
|
|
||||||
|
} else if (value.isBool()) {
|
||||||
|
// Boolean
|
||||||
|
|
||||||
|
auto boolean = value.getBool();
|
||||||
|
hashMap->put(key, jni::JBoolean::valueOf(boolean));
|
||||||
|
|
||||||
|
} else if (value.isNumber()) {
|
||||||
|
// Double
|
||||||
|
|
||||||
|
auto number = value.getNumber();
|
||||||
|
hashMap->put(key, jni::JDouble::valueOf(number));
|
||||||
|
|
||||||
|
} else if (value.isString()) {
|
||||||
|
// String
|
||||||
|
|
||||||
|
auto str = value.getString(runtime).utf8(runtime);
|
||||||
|
hashMap->put(key, jni::make_jstring(str));
|
||||||
|
|
||||||
|
} else if (value.isObject()) {
|
||||||
|
// Object
|
||||||
|
|
||||||
|
auto valueAsObject = value.getObject(runtime);
|
||||||
|
|
||||||
|
if (valueAsObject.isArray(runtime)) {
|
||||||
|
// List<Object>
|
||||||
|
|
||||||
|
} else if (valueAsObject.isHostObject(runtime)) {
|
||||||
|
throw std::runtime_error("You can't pass HostObjects here.");
|
||||||
|
} else {
|
||||||
|
// Map<String, Object>
|
||||||
|
|
||||||
|
auto map = convertJSIObjectToJNIMap(runtime, valueAsObject);
|
||||||
|
hashMap->put(key, map);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
auto stringRepresentation = value.toString(runtime).utf8(runtime);
|
||||||
|
throw std::runtime_error("Failed to convert jsi::Value to JNI value - unsupported type!" + stringRepresentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, const jni::local_ref<jobject>& object) {
|
jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, const jni::local_ref<jobject>& object) {
|
||||||
@ -66,10 +112,10 @@ jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, c
|
|||||||
|
|
||||||
return jsi::String::createFromUtf8(runtime, object->toString());
|
return jsi::String::createFromUtf8(runtime, object->toString());
|
||||||
|
|
||||||
} else if (object->isInstanceOf(JArrayList<jobject>::javaClassStatic())) {
|
} else if (object->isInstanceOf(JList<jobject>::javaClassStatic())) {
|
||||||
// ArrayList<E>
|
// List<E>
|
||||||
|
|
||||||
auto arrayList = static_ref_cast<JArrayList<jobject>>(object);
|
auto arrayList = static_ref_cast<JList<jobject>>(object);
|
||||||
auto size = arrayList->size();
|
auto size = arrayList->size();
|
||||||
|
|
||||||
auto result = jsi::Array(runtime, size);
|
auto result = jsi::Array(runtime, size);
|
||||||
@ -80,19 +126,10 @@ jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, c
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
} else if (object->isInstanceOf(react::ReadableArray::javaClassStatic())) {
|
} else if (object->isInstanceOf(JMap<jstring, jobject>::javaClassStatic())) {
|
||||||
// ReadableArray
|
// Map<K, V>
|
||||||
|
|
||||||
static const auto toArrayListFunc = react::ReadableArray::javaClassLocal()->getMethod<JArrayList<jobject>()>("toArrayList");
|
auto map = static_ref_cast<JMap<jstring, jobject>>(object);
|
||||||
|
|
||||||
// call recursive, this time ArrayList<E>
|
|
||||||
auto array = toArrayListFunc(object.get());
|
|
||||||
return convertJNIObjectToJSIValue(runtime, array);
|
|
||||||
|
|
||||||
} else if (object->isInstanceOf(JHashMap<jstring, jobject>::javaClassStatic())) {
|
|
||||||
// HashMap<K, V>
|
|
||||||
|
|
||||||
auto map = static_ref_cast<JHashMap<jstring, jobject>>(object);
|
|
||||||
|
|
||||||
auto result = jsi::Object(runtime);
|
auto result = jsi::Object(runtime);
|
||||||
for (const auto& entry : *map) {
|
for (const auto& entry : *map) {
|
||||||
@ -103,16 +140,7 @@ jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, c
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
} else if (object->isInstanceOf(react::ReadableMap::javaClassStatic())) {
|
} if (object->isInstanceOf(JFrame::javaClassStatic())) {
|
||||||
// ReadableMap
|
|
||||||
|
|
||||||
static const auto toHashMapFunc = react::ReadableMap::javaClassLocal()->getMethod<JHashMap<jstring, jobject>()>("toHashMap");
|
|
||||||
|
|
||||||
// call recursive, this time HashMap<K, V>
|
|
||||||
auto hashMap = toHashMapFunc(object.get());
|
|
||||||
return convertJNIObjectToJSIValue(runtime, hashMap);
|
|
||||||
|
|
||||||
} else if (object->isInstanceOf(JFrame::javaClassStatic())) {
|
|
||||||
// Frame
|
// Frame
|
||||||
auto frame = static_ref_cast<JFrame>(object);
|
auto frame = static_ref_cast<JFrame>(object);
|
||||||
|
|
@ -7,7 +7,6 @@
|
|||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <fbjni/fbjni.h>
|
#include <fbjni/fbjni.h>
|
||||||
#include <react/jni/ReadableNativeMap.h>
|
|
||||||
|
|
||||||
namespace vision {
|
namespace vision {
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ namespace JSIJNIConversion {
|
|||||||
|
|
||||||
using namespace facebook;
|
using namespace facebook;
|
||||||
|
|
||||||
jni::local_ref<react::ReadableNativeMap::javaobject> convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object);
|
jni::local_ref<jni::JMap<jstring, jobject>> convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object);
|
||||||
|
|
||||||
jsi::Value convertJNIObjectToJSIValue(jsi::Runtime& runtime, const jni::local_ref<jobject>& object);
|
jsi::Value convertJNIObjectToJSIValue(jsi::Runtime& runtime, const jni::local_ref<jobject>& object);
|
||||||
|
|
@ -5,8 +5,8 @@
|
|||||||
#include "VisionCameraProxy.h"
|
#include "VisionCameraProxy.h"
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
|
|
||||||
#include "java-bindings/JFrameProcessor.h"
|
#include "JFrameProcessor.h"
|
||||||
#include "java-bindings/JFrameProcessorPlugin.h"
|
#include "JFrameProcessorPlugin.h"
|
||||||
#include "JSIJNIConversion.h"
|
#include "JSIJNIConversion.h"
|
||||||
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
|
|
||||||
#include "java-bindings/JVisionCameraScheduler.h"
|
#include "JVisionCameraScheduler.h"
|
||||||
#include "java-bindings/JVisionCameraProxy.h"
|
#include "JVisionCameraProxy.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
@ -12,10 +12,10 @@ namespace vision {
|
|||||||
using namespace facebook;
|
using namespace facebook;
|
||||||
using namespace jni;
|
using namespace jni;
|
||||||
|
|
||||||
using TCallback = jobject(alias_ref<JFrame::javaobject>, alias_ref<react::ReadableNativeMap::javaobject> params);
|
using TCallback = jobject(alias_ref<JFrame::javaobject>, alias_ref<JMap<jstring, jobject>> params);
|
||||||
|
|
||||||
local_ref<jobject> JFrameProcessorPlugin::callback(const alias_ref<JFrame::javaobject>& frame,
|
local_ref<jobject> JFrameProcessorPlugin::callback(const alias_ref<JFrame::javaobject>& frame,
|
||||||
const alias_ref<react::ReadableNativeMap::javaobject>& params) const {
|
const alias_ref<JMap<jstring, jobject>>& params) const {
|
||||||
auto callbackMethod = getClass()->getMethod<TCallback>("callback");
|
auto callbackMethod = getClass()->getMethod<TCallback>("callback");
|
||||||
|
|
||||||
auto result = callbackMethod(self(), frame, params);
|
auto result = callbackMethod(self(), frame, params);
|
@ -7,7 +7,6 @@
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <fbjni/fbjni.h>
|
#include <fbjni/fbjni.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <react/jni/ReadableNativeMap.h>
|
|
||||||
|
|
||||||
#include "JFrame.h"
|
#include "JFrame.h"
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ struct JFrameProcessorPlugin : public JavaClass<JFrameProcessorPlugin> {
|
|||||||
* Call the plugin.
|
* Call the plugin.
|
||||||
*/
|
*/
|
||||||
local_ref<jobject> callback(const alias_ref<JFrame::javaobject>& frame,
|
local_ref<jobject> callback(const alias_ref<JFrame::javaobject>& frame,
|
||||||
const alias_ref<react::ReadableNativeMap::javaobject>& params) const;
|
const alias_ref<JMap<jstring, jobject>>& params) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vision
|
} // namespace vision
|
@ -9,7 +9,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <react/jni/ReadableNativeMap.h>
|
|
||||||
|
|
||||||
#include "FrameProcessorPluginHostObject.h"
|
#include "FrameProcessorPluginHostObject.h"
|
||||||
#include "JSITypedArray.h"
|
#include "JSITypedArray.h"
|
||||||
@ -24,7 +23,7 @@ namespace vision {
|
|||||||
using TSelf = local_ref<HybridClass<JVisionCameraProxy>::jhybriddata>;
|
using TSelf = local_ref<HybridClass<JVisionCameraProxy>::jhybriddata>;
|
||||||
using TJSCallInvokerHolder = jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>;
|
using TJSCallInvokerHolder = jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>;
|
||||||
using TScheduler = jni::alias_ref<JVisionCameraScheduler::javaobject>;
|
using TScheduler = jni::alias_ref<JVisionCameraScheduler::javaobject>;
|
||||||
using TOptions = jni::local_ref<react::ReadableNativeMap::javaobject>;
|
using TOptions = jni::local_ref<JMap<jstring, jobject>>;
|
||||||
|
|
||||||
JVisionCameraProxy::JVisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis,
|
JVisionCameraProxy::JVisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis,
|
||||||
jsi::Runtime* runtime,
|
jsi::Runtime* runtime,
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <fbjni/fbjni.h>
|
#include <fbjni/fbjni.h>
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <react/jni/ReadableNativeMap.h>
|
|
||||||
#include <ReactCommon/CallInvokerHolder.h>
|
#include <ReactCommon/CallInvokerHolder.h>
|
||||||
|
|
||||||
#include "JFrameProcessorPlugin.h"
|
#include "JFrameProcessorPlugin.h"
|
||||||
@ -34,7 +33,7 @@ class JVisionCameraProxy : public jni::HybridClass<JVisionCameraProxy> {
|
|||||||
const jsi::Object& frameProcessor);
|
const jsi::Object& frameProcessor);
|
||||||
void removeFrameProcessor(int viewTag);
|
void removeFrameProcessor(int viewTag);
|
||||||
jni::local_ref<JFrameProcessorPlugin::javaobject> getFrameProcessorPlugin(const std::string& name,
|
jni::local_ref<JFrameProcessorPlugin::javaobject> getFrameProcessorPlugin(const std::string& name,
|
||||||
jni::local_ref<react::ReadableNativeMap::javaobject> options);
|
jni::local_ref<JMap<jstring, jobject>> options);
|
||||||
|
|
||||||
jsi::Runtime* getJSRuntime() { return _runtime; }
|
jsi::Runtime* getJSRuntime() { return _runtime; }
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by Marc Rousavy on 24.06.21.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <fbjni/fbjni.h>
|
|
||||||
|
|
||||||
namespace vision {
|
|
||||||
|
|
||||||
using namespace facebook;
|
|
||||||
using namespace jni;
|
|
||||||
|
|
||||||
// TODO: Remove when fbjni 0.2.3 releases.
|
|
||||||
template <typename E = jobject>
|
|
||||||
struct JArrayList : JavaClass<JArrayList<E>, JList<E>> {
|
|
||||||
constexpr static auto kJavaDescriptor = "Ljava/util/ArrayList;";
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace vision
|
|
@ -1,20 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by Marc Rousavy on 25.06.21.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "JHashMap.h"
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <fbjni/fbjni.h>
|
|
||||||
|
|
||||||
namespace vision {
|
|
||||||
|
|
||||||
using namespace facebook;
|
|
||||||
using namespace jni;
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
local_ref<JHashMap<K, V>> JHashMap<K, V>::create() {
|
|
||||||
return JHashMap<K, V>::newInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace vision
|
|
@ -1,23 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by Marc Rousavy on 25.06.21.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <fbjni/fbjni.h>
|
|
||||||
|
|
||||||
namespace vision {
|
|
||||||
|
|
||||||
using namespace facebook;
|
|
||||||
using namespace jni;
|
|
||||||
|
|
||||||
// TODO: Remove when fbjni 0.2.3 releases.
|
|
||||||
template <typename K = jobject, typename V = jobject>
|
|
||||||
struct JHashMap : JavaClass<JHashMap<K, V>, JMap<K, V>> {
|
|
||||||
constexpr static auto kJavaDescriptor = "Ljava/util/HashMap;";
|
|
||||||
|
|
||||||
static local_ref<JHashMap<K, V>> create();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace vision
|
|
@ -4,7 +4,7 @@ import androidx.annotation.Keep;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.facebook.proguard.annotations.DoNotStrip;
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares a Frame Processor Plugin.
|
* Declares a Frame Processor Plugin.
|
||||||
@ -21,5 +21,5 @@ public abstract class FrameProcessorPlugin {
|
|||||||
*/
|
*/
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@Keep
|
@Keep
|
||||||
public abstract @Nullable Object callback(@NonNull Frame frame, @Nullable ReadableNativeMap params);
|
public abstract @Nullable Object callback(@NonNull Frame frame, @Nullable Map<String, Object> params);
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@ package com.mrousavy.camera.frameprocessor;
|
|||||||
|
|
||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.facebook.proguard.annotations.DoNotStrip;
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@Keep
|
@Keep
|
||||||
@ -24,7 +21,7 @@ public class FrameProcessorPluginRegistry {
|
|||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@Keep
|
@Keep
|
||||||
public static FrameProcessorPlugin getPlugin(String name, ReadableNativeMap options) {
|
public static FrameProcessorPlugin getPlugin(String name, Map<String, Object> options) {
|
||||||
PluginInitializer initializer = Plugins.get(name);
|
PluginInitializer initializer = Plugins.get(name);
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -33,6 +30,6 @@ public class FrameProcessorPluginRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface PluginInitializer {
|
public interface PluginInitializer {
|
||||||
FrameProcessorPlugin initializePlugin(@Nullable ReadableNativeMap options);
|
FrameProcessorPlugin initializePlugin(@Nullable Map<String, Object> options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import androidx.annotation.UiThread
|
|||||||
import com.facebook.jni.HybridData
|
import com.facebook.jni.HybridData
|
||||||
import com.facebook.proguard.annotations.DoNotStrip
|
import com.facebook.proguard.annotations.DoNotStrip
|
||||||
import com.facebook.react.bridge.ReactApplicationContext
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
import com.facebook.react.bridge.ReadableNativeMap
|
|
||||||
import com.facebook.react.bridge.UiThreadUtil
|
import com.facebook.react.bridge.UiThreadUtil
|
||||||
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
||||||
import com.facebook.react.uimanager.UIManagerHelper
|
import com.facebook.react.uimanager.UIManagerHelper
|
||||||
@ -14,7 +13,6 @@ import com.mrousavy.camera.CameraView
|
|||||||
import com.mrousavy.camera.ViewNotFoundError
|
import com.mrousavy.camera.ViewNotFoundError
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|
||||||
@Suppress("KotlinJniMissingFunction") // we use fbjni.
|
@Suppress("KotlinJniMissingFunction") // we use fbjni.
|
||||||
class VisionCameraProxy(context: ReactApplicationContext) {
|
class VisionCameraProxy(context: ReactApplicationContext) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -71,7 +69,7 @@ class VisionCameraProxy(context: ReactApplicationContext) {
|
|||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
@Keep
|
@Keep
|
||||||
fun getFrameProcessorPlugin(name: String, options: ReadableNativeMap): FrameProcessorPlugin {
|
fun getFrameProcessorPlugin(name: String, options: Map<String, Any>): FrameProcessorPlugin {
|
||||||
return FrameProcessorPluginRegistry.getPlugin(name, options)
|
return FrameProcessorPluginRegistry.getPlugin(name, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ Similar to a TurboModule, the Frame Processor Plugin Registry API automatically
|
|||||||
| `number` | `NSNumber*` (double) | `Double` |
|
| `number` | `NSNumber*` (double) | `Double` |
|
||||||
| `boolean` | `NSNumber*` (boolean) | `Boolean` |
|
| `boolean` | `NSNumber*` (boolean) | `Boolean` |
|
||||||
| `string` | `NSString*` | `String` |
|
| `string` | `NSString*` | `String` |
|
||||||
| `[]` | `NSArray*` | `ReadableNativeArray` |
|
| `[]` | `NSArray*` | `List<Object>` |
|
||||||
| `{}` | `NSDictionary*` | `ReadableNativeMap` |
|
| `{}` | `NSDictionary*` | `Map<String, Object>` |
|
||||||
| `undefined` / `null` | `nil` | `null` |
|
| `undefined` / `null` | `nil` | `null` |
|
||||||
| `(any, any) => void` | [`RCTResponseSenderBlock`][4] | `(Object, Object) -> void` |
|
| `(any, any) => void` | [`RCTResponseSenderBlock`][4] | `(Object, Object) -> void` |
|
||||||
| [`Frame`][1] | [`Frame*`][2] | [`Frame`][3] |
|
| [`Frame`][1] | [`Frame*`][2] | [`Frame`][3] |
|
||||||
|
@ -61,7 +61,7 @@ import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
|
|||||||
public class FaceDetectorFrameProcessorPlugin extends FrameProcessorPlugin {
|
public class FaceDetectorFrameProcessorPlugin extends FrameProcessorPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object callback(Frame frame, ReadableNativeMap arguments) {
|
public Object callback(Frame frame, Map<String, Object> arguments) {
|
||||||
// code goes here
|
// code goes here
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin
|
|||||||
|
|
||||||
class FaceDetectorFrameProcessorPlugin: FrameProcessorPlugin() {
|
class FaceDetectorFrameProcessorPlugin: FrameProcessorPlugin() {
|
||||||
|
|
||||||
override fun callback(frame: Frame, arguments: ReadableNativeMap): Any? {
|
override fun callback(frame: Frame, arguments: Map<String, Object>): Any? {
|
||||||
// code goes here
|
// code goes here
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -3,40 +3,40 @@ package com.mrousavy.camera.example;
|
|||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
|
||||||
import com.facebook.react.bridge.WritableNativeArray;
|
|
||||||
import com.facebook.react.bridge.WritableNativeMap;
|
|
||||||
import com.mrousavy.camera.frameprocessor.Frame;
|
import com.mrousavy.camera.frameprocessor.Frame;
|
||||||
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
|
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ExampleFrameProcessorPlugin extends FrameProcessorPlugin {
|
public class ExampleFrameProcessorPlugin extends FrameProcessorPlugin {
|
||||||
@Override
|
@Override
|
||||||
public Object callback(@NotNull Frame frame, @Nullable ReadableNativeMap params) {
|
public Object callback(@NotNull Frame frame, @Nullable Map<String, Object> params) {
|
||||||
HashMap<String, Object> hashMap = params != null ? params.toHashMap() : new HashMap<>();
|
if (params == null) return null;
|
||||||
Image image = frame.getImage();
|
Image image = frame.getImage();
|
||||||
|
|
||||||
Log.d("ExamplePlugin", image.getWidth() + " x " + image.getHeight() + " Image with format #" + image.getFormat() + ". Logging " + hashMap.size() + " parameters:");
|
Log.d("ExamplePlugin", image.getWidth() + " x " + image.getHeight() + " Image with format #" + image.getFormat() + ". Logging " + params.size() + " parameters:");
|
||||||
|
|
||||||
for (String key : hashMap.keySet()) {
|
for (String key : params.keySet()) {
|
||||||
Object value = hashMap.get(key);
|
Object value = params.get(key);
|
||||||
Log.d("ExamplePlugin", " -> " + (value == null ? "(null)" : value.toString() + " (" + value.getClass().getName() + ")"));
|
Log.d("ExamplePlugin", " -> " + (value == null ? "(null)" : value + " (" + value.getClass().getName() + ")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
WritableNativeMap map = new WritableNativeMap();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.putString("example_str", "Test");
|
map.put("example_str", "Test");
|
||||||
map.putBoolean("example_bool", true);
|
map.put("example_bool", true);
|
||||||
map.putDouble("example_double", 5.3);
|
map.put("example_double", 5.3);
|
||||||
|
|
||||||
WritableNativeArray array = new WritableNativeArray();
|
List<Object> array = new ArrayList<>();
|
||||||
array.pushString("Hello!");
|
array.add("Hello!");
|
||||||
array.pushBoolean(true);
|
array.add(true);
|
||||||
array.pushDouble(17.38);
|
array.add(17.38);
|
||||||
|
|
||||||
map.putArray("example_array", array);
|
map.put("example_array", array);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import com.facebook.react.PackageList;
|
|||||||
import com.facebook.react.ReactApplication;
|
import com.facebook.react.ReactApplication;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||||
|
Loading…
Reference in New Issue
Block a user