chore: Change line width to 140 in C++

This commit is contained in:
Marc Rousavy 2023-09-01 19:39:25 +02:00
parent 033ddb8cff
commit 325fc4d2bb
36 changed files with 166 additions and 324 deletions

View File

@ -22,8 +22,7 @@ inline std::string getEglErrorIfAny() {
class OpenGLError : public std::runtime_error { class OpenGLError : public std::runtime_error {
public: public:
explicit OpenGLError(const std::string&& message) explicit OpenGLError(const std::string&& message) : std::runtime_error(message + getEglErrorIfAny()) {}
: std::runtime_error(message + getEglErrorIfAny()) {}
static inline void checkIfError(const std::string&& message) { static inline void checkIfError(const std::string&& message) {
auto error = getEglErrorIfAny(); auto error = getEglErrorIfAny();

View File

@ -17,9 +17,7 @@
namespace vision { namespace vision {
std::unique_ptr<OpenGLRenderer> std::unique_ptr<OpenGLRenderer> OpenGLRenderer::CreateWithWindowSurface(std::shared_ptr<OpenGLContext> context, ANativeWindow* surface) {
OpenGLRenderer::CreateWithWindowSurface(std::shared_ptr<OpenGLContext> context,
ANativeWindow* surface) {
return std::unique_ptr<OpenGLRenderer>(new OpenGLRenderer(std::move(context), surface)); return std::unique_ptr<OpenGLRenderer>(new OpenGLRenderer(std::move(context), surface));
} }

View File

@ -24,8 +24,7 @@ public:
* Note: The `surface` is considered moved, and the OpenGL context will release it when it is * Note: The `surface` is considered moved, and the OpenGL context will release it when it is
* being deleted. * being deleted.
*/ */
static std::unique_ptr<OpenGLRenderer> static std::unique_ptr<OpenGLRenderer> CreateWithWindowSurface(std::shared_ptr<OpenGLContext> context, ANativeWindow* surface);
CreateWithWindowSurface(std::shared_ptr<OpenGLContext> context, ANativeWindow* surface);
/** /**
* Destroy the OpenGL Context. This needs to be called on the same thread that `use()` was called. * Destroy the OpenGL Context. This needs to be called on the same thread that `use()` was called.
*/ */

View File

@ -19,13 +19,11 @@
namespace vision { namespace vision {
jni::local_ref<VideoPipeline::jhybriddata> jni::local_ref<VideoPipeline::jhybriddata> VideoPipeline::initHybrid(jni::alias_ref<jhybridobject> jThis, int width, int height) {
VideoPipeline::initHybrid(jni::alias_ref<jhybridobject> jThis, int width, int height) {
return makeCxxInstance(jThis, width, height); return makeCxxInstance(jThis, width, height);
} }
VideoPipeline::VideoPipeline(jni::alias_ref<jhybridobject> jThis, int width, int height) VideoPipeline::VideoPipeline(jni::alias_ref<jhybridobject> jThis, int width, int height) : _javaPart(jni::make_global(jThis)) {
: _javaPart(jni::make_global(jThis)) {
_width = width; _width = width;
_height = height; _height = height;
_context = OpenGLContext::CreateWithOffscreenSurface(); _context = OpenGLContext::CreateWithOffscreenSurface();
@ -108,14 +106,10 @@ void VideoPipeline::onFrame(jni::alias_ref<jni::JArrayFloat> transformMatrixPara
void VideoPipeline::registerNatives() { void VideoPipeline::registerNatives() {
registerHybrid({ registerHybrid({
makeNativeMethod("initHybrid", VideoPipeline::initHybrid), makeNativeMethod("initHybrid", VideoPipeline::initHybrid),
makeNativeMethod("setFrameProcessorOutputSurface", makeNativeMethod("setFrameProcessorOutputSurface", VideoPipeline::setFrameProcessorOutputSurface),
VideoPipeline::setFrameProcessorOutputSurface), makeNativeMethod("removeFrameProcessorOutputSurface", VideoPipeline::removeFrameProcessorOutputSurface),
makeNativeMethod("removeFrameProcessorOutputSurface", makeNativeMethod("setRecordingSessionOutputSurface", VideoPipeline::setRecordingSessionOutputSurface),
VideoPipeline::removeFrameProcessorOutputSurface), makeNativeMethod("removeRecordingSessionOutputSurface", VideoPipeline::removeRecordingSessionOutputSurface),
makeNativeMethod("setRecordingSessionOutputSurface",
VideoPipeline::setRecordingSessionOutputSurface),
makeNativeMethod("removeRecordingSessionOutputSurface",
VideoPipeline::removeRecordingSessionOutputSurface),
makeNativeMethod("getInputTextureId", VideoPipeline::getInputTextureId), makeNativeMethod("getInputTextureId", VideoPipeline::getInputTextureId),
makeNativeMethod("onBeforeFrame", VideoPipeline::onBeforeFrame), makeNativeMethod("onBeforeFrame", VideoPipeline::onBeforeFrame),
makeNativeMethod("onFrame", VideoPipeline::onFrame), makeNativeMethod("onFrame", VideoPipeline::onFrame),

View File

@ -21,8 +21,7 @@ using namespace facebook;
class VideoPipeline : public jni::HybridClass<VideoPipeline> { class VideoPipeline : public jni::HybridClass<VideoPipeline> {
public: public:
static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/core/VideoPipeline;"; static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/core/VideoPipeline;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis, int width, static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis, int width, int height);
int height);
static void registerNatives(); static void registerNatives();
public: public:

View File

@ -16,8 +16,7 @@ namespace vision {
using namespace facebook; using namespace facebook;
FrameHostObject::FrameHostObject(const jni::alias_ref<JFrame::javaobject>& frame) FrameHostObject::FrameHostObject(const jni::alias_ref<JFrame::javaobject>& frame) : frame(make_global(frame)) {}
: frame(make_global(frame)) {}
FrameHostObject::~FrameHostObject() { FrameHostObject::~FrameHostObject() {
// Hermes' Garbage Collector (Hades GC) calls destructors on a separate Thread // Hermes' Garbage Collector (Hades GC) calls destructors on a separate Thread
@ -51,29 +50,25 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
auto name = propName.utf8(runtime); auto name = propName.utf8(runtime);
if (name == "incrementRefCount") { if (name == "incrementRefCount") {
jsi::HostFunctionType incrementRefCount = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, jsi::HostFunctionType incrementRefCount = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args,
const jsi::Value* args,
size_t count) -> jsi::Value { size_t count) -> jsi::Value {
// Increment retain count by one. // Increment retain count by one.
this->frame->incrementRefCount(); this->frame->incrementRefCount();
return jsi::Value::undefined(); return jsi::Value::undefined();
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "incrementRefCount"), 0, incrementRefCount);
runtime, jsi::PropNameID::forUtf8(runtime, "incrementRefCount"), 0, incrementRefCount);
} }
if (name == "decrementRefCount") { if (name == "decrementRefCount") {
auto decrementRefCount = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, auto decrementRefCount = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args, size_t count) -> jsi::Value {
const jsi::Value* args, size_t count) -> jsi::Value {
// Decrement retain count by one. If the retain count is zero, the Frame gets closed. // Decrement retain count by one. If the retain count is zero, the Frame gets closed.
this->frame->decrementRefCount(); this->frame->decrementRefCount();
return jsi::Value::undefined(); return jsi::Value::undefined();
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "decrementRefCount"), 0, decrementRefCount);
runtime, jsi::PropNameID::forUtf8(runtime, "decrementRefCount"), 0, decrementRefCount);
} }
if (name == "toString") { if (name == "toString") {
jsi::HostFunctionType toString = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, jsi::HostFunctionType toString = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args,
const jsi::Value* args, size_t count) -> jsi::Value { size_t count) -> jsi::Value {
if (!this->frame) { if (!this->frame) {
return jsi::String::createFromUtf8(runtime, "[closed frame]"); return jsi::String::createFromUtf8(runtime, "[closed frame]");
} }
@ -82,16 +77,14 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
auto str = std::to_string(width) + " x " + std::to_string(height) + " Frame"; auto str = std::to_string(width) + " x " + std::to_string(height) + " Frame";
return jsi::String::createFromUtf8(runtime, str); return jsi::String::createFromUtf8(runtime, str);
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
} }
if (name == "toArrayBuffer") { if (name == "toArrayBuffer") {
jsi::HostFunctionType toArrayBuffer = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, jsi::HostFunctionType toArrayBuffer = [=](jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args,
const jsi::Value* args, size_t count) -> jsi::Value { size_t count) -> jsi::Value {
auto buffer = this->frame->toByteBuffer(); auto buffer = this->frame->toByteBuffer();
if (!buffer->isDirect()) { if (!buffer->isDirect()) {
throw std::runtime_error( throw std::runtime_error("Failed to get byte content of Frame - array is not direct ByteBuffer!");
"Failed to get byte content of Frame - array is not direct ByteBuffer!");
} }
auto size = buffer->getDirectSize(); auto size = buffer->getDirectSize();
@ -102,10 +95,8 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
} }
// Get from global JS cache // Get from global JS cache
auto arrayBufferCache = auto arrayBufferCache = runtime.global().getPropertyAsObject(runtime, ARRAYBUFFER_CACHE_PROP_NAME);
runtime.global().getPropertyAsObject(runtime, ARRAYBUFFER_CACHE_PROP_NAME); auto arrayBuffer = vision::getTypedArray(runtime, arrayBufferCache).get<vision::TypedArrayKind::Uint8ClampedArray>(runtime);
auto arrayBuffer = vision::getTypedArray(runtime, arrayBufferCache)
.get<vision::TypedArrayKind::Uint8ClampedArray>(runtime);
if (arrayBuffer.size(runtime) != size) { if (arrayBuffer.size(runtime) != size) {
arrayBuffer = vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray>(runtime, size); arrayBuffer = vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray>(runtime, size);
runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer); runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer);
@ -117,8 +108,7 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
return arrayBuffer; return arrayBuffer;
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toArrayBuffer"), 0, toArrayBuffer);
runtime, jsi::PropNameID::forUtf8(runtime, "toArrayBuffer"), 0, toArrayBuffer);
} }
if (name == "isValid") { if (name == "isValid") {

View File

@ -12,32 +12,27 @@ namespace vision {
using namespace facebook; using namespace facebook;
std::vector<jsi::PropNameID> std::vector<jsi::PropNameID> FrameProcessorPluginHostObject::getPropertyNames(jsi::Runtime& runtime) {
FrameProcessorPluginHostObject::getPropertyNames(jsi::Runtime& runtime) {
std::vector<jsi::PropNameID> result; std::vector<jsi::PropNameID> result;
result.push_back(jsi::PropNameID::forUtf8(runtime, std::string("call"))); result.push_back(jsi::PropNameID::forUtf8(runtime, std::string("call")));
return result; return result;
} }
jsi::Value FrameProcessorPluginHostObject::get(jsi::Runtime& runtime, jsi::Value FrameProcessorPluginHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propName) {
const jsi::PropNameID& propName) {
auto name = propName.utf8(runtime); auto name = propName.utf8(runtime);
if (name == "call") { if (name == "call") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "call"), 2, runtime, jsi::PropNameID::forUtf8(runtime, "call"), 2,
[=](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [=](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
// Frame is first argument // Frame is first argument
auto frameHostObject = auto frameHostObject = arguments[0].asObject(runtime).asHostObject<FrameHostObject>(runtime);
arguments[0].asObject(runtime).asHostObject<FrameHostObject>(runtime);
auto frame = frameHostObject->frame; auto frame = frameHostObject->frame;
// Options are second argument (possibly undefined) // Options are second argument (possibly undefined)
local_ref<JMap<jstring, jobject>> options = nullptr; local_ref<JMap<jstring, jobject>> options = nullptr;
if (count > 1) { if (count > 1) {
options = options = JSIJNIConversion::convertJSIObjectToJNIMap(runtime, arguments[1].asObject(runtime));
JSIJNIConversion::convertJSIObjectToJNIMap(runtime, arguments[1].asObject(runtime));
} }
// Call actual plugin // Call actual plugin

View File

@ -16,8 +16,7 @@ using namespace facebook;
class FrameProcessorPluginHostObject : public jsi::HostObject { class FrameProcessorPluginHostObject : public jsi::HostObject {
public: public:
explicit FrameProcessorPluginHostObject(jni::alias_ref<JFrameProcessorPlugin::javaobject> plugin) explicit FrameProcessorPluginHostObject(jni::alias_ref<JFrameProcessorPlugin::javaobject> plugin) : _plugin(make_global(plugin)) {}
: _plugin(make_global(plugin)) {}
~FrameProcessorPluginHostObject() {} ~FrameProcessorPluginHostObject() {}
public: public:

View File

@ -20,8 +20,7 @@ namespace vision {
using namespace facebook; using namespace facebook;
jni::local_ref<jni::JMap<jstring, jobject>> jni::local_ref<jni::JMap<jstring, jobject>> JSIJNIConversion::convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object) {
JSIJNIConversion::convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object) {
auto propertyNames = object.getPropertyNames(runtime); auto propertyNames = object.getPropertyNames(runtime);
auto size = propertyNames.size(runtime); auto size = propertyNames.size(runtime);
auto hashMap = jni::JHashMap<jstring, jobject>::create(); auto hashMap = jni::JHashMap<jstring, jobject>::create();
@ -67,16 +66,14 @@ JSIJNIConversion::convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Obj
} }
} else { } else {
auto stringRepresentation = value.toString(runtime).utf8(runtime); auto stringRepresentation = value.toString(runtime).utf8(runtime);
throw std::runtime_error("Failed to convert jsi::Value to JNI value - unsupported type!" + throw std::runtime_error("Failed to convert jsi::Value to JNI value - unsupported type!" + stringRepresentation);
stringRepresentation);
} }
} }
return hashMap; return hashMap;
} }
jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime& runtime, jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime& runtime, const jni::local_ref<jobject>& object) {
const jni::local_ref<jobject>& object) {
if (object == nullptr) { if (object == nullptr) {
// null // null
@ -84,22 +81,19 @@ jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime& runtime,
} else if (object->isInstanceOf(jni::JBoolean::javaClassStatic())) { } else if (object->isInstanceOf(jni::JBoolean::javaClassStatic())) {
// Boolean // Boolean
static const auto getBooleanFunc = static const auto getBooleanFunc = jni::findClassLocal("java/lang/Boolean")->getMethod<jboolean()>("booleanValue");
jni::findClassLocal("java/lang/Boolean")->getMethod<jboolean()>("booleanValue");
auto boolean = getBooleanFunc(object.get()); auto boolean = getBooleanFunc(object.get());
return jsi::Value(boolean == true); return jsi::Value(boolean == true);
} else if (object->isInstanceOf(jni::JDouble::javaClassStatic())) { } else if (object->isInstanceOf(jni::JDouble::javaClassStatic())) {
// Double // Double
static const auto getDoubleFunc = static const auto getDoubleFunc = jni::findClassLocal("java/lang/Double")->getMethod<jdouble()>("doubleValue");
jni::findClassLocal("java/lang/Double")->getMethod<jdouble()>("doubleValue");
auto d = getDoubleFunc(object.get()); auto d = getDoubleFunc(object.get());
return jsi::Value(d); return jsi::Value(d);
} else if (object->isInstanceOf(jni::JInteger::javaClassStatic())) { } else if (object->isInstanceOf(jni::JInteger::javaClassStatic())) {
// Integer // Integer
static const auto getIntegerFunc = static const auto getIntegerFunc = jni::findClassLocal("java/lang/Integer")->getMethod<jint()>("intValue");
jni::findClassLocal("java/lang/Integer")->getMethod<jint()>("intValue");
auto i = getIntegerFunc(object.get()); auto i = getIntegerFunc(object.get());
return jsi::Value(i); return jsi::Value(i);
} else if (object->isInstanceOf(jni::JString::javaClassStatic())) { } else if (object->isInstanceOf(jni::JString::javaClassStatic())) {

View File

@ -14,11 +14,9 @@ namespace JSIJNIConversion {
using namespace facebook; using namespace facebook;
jni::local_ref<jni::JMap<jstring, jobject>> convertJSIObjectToJNIMap(jsi::Runtime& runtime, jni::local_ref<jni::JMap<jstring, jobject>> convertJSIObjectToJNIMap(jsi::Runtime& runtime, const jsi::Object& object);
const jsi::Object& object);
jsi::Value convertJNIObjectToJSIValue(jsi::Runtime& runtime, jsi::Value convertJNIObjectToJSIValue(jsi::Runtime& runtime, const jni::local_ref<jobject>& object);
const jni::local_ref<jobject>& object);
} // namespace JSIJNIConversion } // namespace JSIJNIConversion

View File

@ -27,8 +27,7 @@ namespace vision {
using namespace facebook; using namespace facebook;
VisionCameraProxy::VisionCameraProxy( VisionCameraProxy::VisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::javaobject>& javaProxy) {
const jni::alias_ref<JVisionCameraProxy::javaobject>& javaProxy) {
_javaProxy = make_global(javaProxy); _javaProxy = make_global(javaProxy);
} }
@ -42,8 +41,7 @@ std::vector<jsi::PropNameID> VisionCameraProxy::getPropertyNames(jsi::Runtime& r
return result; return result;
} }
void VisionCameraProxy::setFrameProcessor(int viewTag, jsi::Runtime& runtime, void VisionCameraProxy::setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& object) {
const jsi::Object& object) {
_javaProxy->cthis()->setFrameProcessor(viewTag, runtime, object); _javaProxy->cthis()->setFrameProcessor(viewTag, runtime, object);
} }
@ -51,9 +49,7 @@ void VisionCameraProxy::removeFrameProcessor(int viewTag) {
_javaProxy->cthis()->removeFrameProcessor(viewTag); _javaProxy->cthis()->removeFrameProcessor(viewTag);
} }
jsi::Value VisionCameraProxy::getFrameProcessorPlugin(jsi::Runtime& runtime, jsi::Value VisionCameraProxy::getFrameProcessorPlugin(jsi::Runtime& runtime, const std::string& name, const jsi::Object& jsOptions) {
const std::string& name,
const jsi::Object& jsOptions) {
auto options = JSIJNIConversion::convertJSIObjectToJNIMap(runtime, jsOptions); auto options = JSIJNIConversion::convertJSIObjectToJNIMap(runtime, jsOptions);
auto plugin = _javaProxy->cthis()->getFrameProcessorPlugin(name, options); auto plugin = _javaProxy->cthis()->getFrameProcessorPlugin(name, options);
@ -68,8 +64,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "setFrameProcessor") { if (name == "setFrameProcessor") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "setFrameProcessor"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "setFrameProcessor"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
auto viewTag = arguments[0].asNumber(); auto viewTag = arguments[0].asNumber();
auto object = arguments[1].asObject(runtime); auto object = arguments[1].asObject(runtime);
this->setFrameProcessor(static_cast<int>(viewTag), runtime, object); this->setFrameProcessor(static_cast<int>(viewTag), runtime, object);
@ -79,8 +74,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "removeFrameProcessor") { if (name == "removeFrameProcessor") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "removeFrameProcessor"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "removeFrameProcessor"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
auto viewTag = arguments[0].asNumber(); auto viewTag = arguments[0].asNumber();
this->removeFrameProcessor(static_cast<int>(viewTag)); this->removeFrameProcessor(static_cast<int>(viewTag));
return jsi::Value::undefined(); return jsi::Value::undefined();
@ -89,8 +83,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "getFrameProcessorPlugin") { if (name == "getFrameProcessorPlugin") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "getFrameProcessorPlugin"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "getFrameProcessorPlugin"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
if (count < 1 || !arguments[0].isString()) { if (count < 1 || !arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument needs to be a string (pluginName)!"); throw jsi::JSError(runtime, "First argument needs to be a string (pluginName)!");
} }
@ -104,13 +97,11 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
return jsi::Value::undefined(); return jsi::Value::undefined();
} }
void VisionCameraInstaller::install(jni::alias_ref<jni::JClass>, void VisionCameraInstaller::install(jni::alias_ref<jni::JClass>, jni::alias_ref<JVisionCameraProxy::javaobject> proxy) {
jni::alias_ref<JVisionCameraProxy::javaobject> proxy) {
// global.VisionCameraProxy // global.VisionCameraProxy
auto visionCameraProxy = std::make_shared<VisionCameraProxy>(proxy); auto visionCameraProxy = std::make_shared<VisionCameraProxy>(proxy);
jsi::Runtime& runtime = *proxy->cthis()->getJSRuntime(); jsi::Runtime& runtime = *proxy->cthis()->getJSRuntime();
runtime.global().setProperty(runtime, "VisionCameraProxy", runtime.global().setProperty(runtime, "VisionCameraProxy", jsi::Object::createFromHostObject(runtime, visionCameraProxy));
jsi::Object::createFromHostObject(runtime, visionCameraProxy));
} }
} // namespace vision } // namespace vision

View File

@ -28,8 +28,7 @@ public:
private: private:
void setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& frameProcessor); void setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& frameProcessor);
void removeFrameProcessor(int viewTag); void removeFrameProcessor(int viewTag);
jsi::Value getFrameProcessorPlugin(jsi::Runtime& runtime, const std::string& name, jsi::Value getFrameProcessorPlugin(jsi::Runtime& runtime, const std::string& name, const jsi::Object& options);
const jsi::Object& options);
private: private:
jni::global_ref<JVisionCameraProxy::javaobject> _javaProxy; jni::global_ref<JVisionCameraProxy::javaobject> _javaProxy;
@ -38,14 +37,11 @@ private:
class VisionCameraInstaller : public jni::JavaClass<VisionCameraInstaller> { class VisionCameraInstaller : public jni::JavaClass<VisionCameraInstaller> {
public: public:
static auto constexpr kJavaDescriptor = static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/VisionCameraInstaller;";
"Lcom/mrousavy/camera/frameprocessor/VisionCameraInstaller;";
static void registerNatives() { static void registerNatives() {
javaClassStatic()->registerNatives( javaClassStatic()->registerNatives({makeNativeMethod("install", VisionCameraInstaller::install)});
{makeNativeMethod("install", VisionCameraInstaller::install)});
} }
static void install(jni::alias_ref<jni::JClass> clazz, static void install(jni::alias_ref<jni::JClass> clazz, jni::alias_ref<JVisionCameraProxy::javaobject> proxy);
jni::alias_ref<JVisionCameraProxy::javaobject> proxy);
}; };
} // namespace vision } // namespace vision

View File

@ -22,8 +22,7 @@ void JFrameProcessor::registerNatives() {
using TSelf = jni::local_ref<JFrameProcessor::javaobject>; using TSelf = jni::local_ref<JFrameProcessor::javaobject>;
JFrameProcessor::JFrameProcessor(std::shared_ptr<RNWorklet::JsiWorklet> worklet, JFrameProcessor::JFrameProcessor(std::shared_ptr<RNWorklet::JsiWorklet> worklet, std::shared_ptr<RNWorklet::JsiWorkletContext> context) {
std::shared_ptr<RNWorklet::JsiWorkletContext> context) {
_workletContext = std::move(context); _workletContext = std::move(context);
_workletInvoker = std::make_shared<RNWorklet::WorkletInvoker>(worklet); _workletInvoker = std::make_shared<RNWorklet::WorkletInvoker>(worklet);
} }
@ -33,8 +32,7 @@ TSelf JFrameProcessor::create(const std::shared_ptr<RNWorklet::JsiWorklet>& work
return JFrameProcessor::newObjectCxxArgs(worklet, context); return JFrameProcessor::newObjectCxxArgs(worklet, context);
} }
void JFrameProcessor::callWithFrameHostObject( void JFrameProcessor::callWithFrameHostObject(const std::shared_ptr<FrameHostObject>& frameHostObject) const {
const std::shared_ptr<FrameHostObject>& frameHostObject) const {
// Call the Frame Processor on the Worklet Runtime // Call the Frame Processor on the Worklet Runtime
jsi::Runtime& runtime = _workletContext->getWorkletRuntime(); jsi::Runtime& runtime = _workletContext->getWorkletRuntime();
@ -50,11 +48,8 @@ void JFrameProcessor::callWithFrameHostObject(
const std::string& message = jsError.getMessage(); const std::string& message = jsError.getMessage();
_workletContext->invokeOnJsThread([message](jsi::Runtime& jsRuntime) { _workletContext->invokeOnJsThread([message](jsi::Runtime& jsRuntime) {
auto logFn = jsRuntime.global() auto logFn = jsRuntime.global().getPropertyAsObject(jsRuntime, "console").getPropertyAsFunction(jsRuntime, "error");
.getPropertyAsObject(jsRuntime, "console") logFn.call(jsRuntime, jsi::String::createFromUtf8(jsRuntime, "Frame Processor threw an error: " + message));
.getPropertyAsFunction(jsRuntime, "error");
logFn.call(jsRuntime, jsi::String::createFromUtf8(
jsRuntime, "Frame Processor threw an error: " + message));
}); });
} }
} }

View File

@ -25,9 +25,8 @@ struct JFrameProcessor : public jni::HybridClass<JFrameProcessor> {
public: public:
static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/FrameProcessor;"; static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/FrameProcessor;";
static void registerNatives(); static void registerNatives();
static jni::local_ref<JFrameProcessor::javaobject> static jni::local_ref<JFrameProcessor::javaobject> create(const std::shared_ptr<RNWorklet::JsiWorklet>& worklet,
create(const std::shared_ptr<RNWorklet::JsiWorklet>& worklet, const std::shared_ptr<RNWorklet::JsiWorkletContext>& context);
const std::shared_ptr<RNWorklet::JsiWorkletContext>& context);
public: public:
/** /**
@ -37,8 +36,7 @@ public:
private: private:
// Private constructor. Use `create(..)` to create new instances. // Private constructor. Use `create(..)` to create new instances.
explicit JFrameProcessor(std::shared_ptr<RNWorklet::JsiWorklet> worklet, explicit JFrameProcessor(std::shared_ptr<RNWorklet::JsiWorklet> worklet, std::shared_ptr<RNWorklet::JsiWorkletContext> context);
std::shared_ptr<RNWorklet::JsiWorkletContext> context);
private: private:
void callWithFrameHostObject(const std::shared_ptr<FrameHostObject>& frameHostObject) const; void callWithFrameHostObject(const std::shared_ptr<FrameHostObject>& frameHostObject) const;

View File

@ -14,9 +14,8 @@ using namespace jni;
using TCallback = jobject(alias_ref<JFrame::javaobject>, alias_ref<JMap<jstring, jobject>> params); using TCallback = jobject(alias_ref<JFrame::javaobject>, alias_ref<JMap<jstring, jobject>> params);
local_ref<jobject> local_ref<jobject> JFrameProcessorPlugin::callback(const alias_ref<JFrame::javaobject>& frame,
JFrameProcessorPlugin::callback(const alias_ref<JFrame::javaobject>& frame, const alias_ref<JMap<jstring, jobject>>& 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);

View File

@ -16,15 +16,13 @@ using namespace facebook;
using namespace jni; using namespace jni;
struct JFrameProcessorPlugin : public JavaClass<JFrameProcessorPlugin> { struct JFrameProcessorPlugin : public JavaClass<JFrameProcessorPlugin> {
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/FrameProcessorPlugin;";
"Lcom/mrousavy/camera/frameprocessor/FrameProcessorPlugin;";
public: public:
/** /**
* 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<JMap<jstring, jobject>>& params) const;
const alias_ref<JMap<jstring, jobject>>& params) const;
}; };
} // namespace vision } // namespace vision

View File

@ -25,10 +25,9 @@ using TJSCallInvokerHolder = jni::alias_ref<facebook::react::CallInvokerHolder::
using TScheduler = jni::alias_ref<JVisionCameraScheduler::javaobject>; using TScheduler = jni::alias_ref<JVisionCameraScheduler::javaobject>;
using TOptions = jni::local_ref<JMap<jstring, jobject>>; using TOptions = jni::local_ref<JMap<jstring, jobject>>;
JVisionCameraProxy::JVisionCameraProxy( JVisionCameraProxy::JVisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis, jsi::Runtime* runtime,
const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis, jsi::Runtime* runtime, const std::shared_ptr<facebook::react::CallInvoker>& callInvoker,
const std::shared_ptr<facebook::react::CallInvoker>& callInvoker, const jni::global_ref<JVisionCameraScheduler::javaobject>& scheduler) {
const jni::global_ref<JVisionCameraScheduler::javaobject>& scheduler) {
_javaPart = make_global(javaThis); _javaPart = make_global(javaThis);
_runtime = runtime; _runtime = runtime;
@ -43,8 +42,7 @@ JVisionCameraProxy::JVisionCameraProxy(
// Run on Frame Processor Worklet Runtime // Run on Frame Processor Worklet Runtime
scheduler->cthis()->dispatchAsync([f = std::move(f)]() { f(); }); scheduler->cthis()->dispatchAsync([f = std::move(f)]() { f(); });
}; };
_workletContext = std::make_shared<RNWorklet::JsiWorkletContext>("VisionCamera", runtime, runOnJS, _workletContext = std::make_shared<RNWorklet::JsiWorkletContext>("VisionCamera", runtime, runOnJS, runOnWorklet);
runOnWorklet);
__android_log_write(ANDROID_LOG_INFO, TAG, "Worklet Context created!"); __android_log_write(ANDROID_LOG_INFO, TAG, "Worklet Context created!");
#else #else
__android_log_write(ANDROID_LOG_INFO, TAG, "Frame Processors are disabled!"); __android_log_write(ANDROID_LOG_INFO, TAG, "Frame Processors are disabled!");
@ -60,13 +58,10 @@ JVisionCameraProxy::~JVisionCameraProxy() {
#endif #endif
} }
void JVisionCameraProxy::setFrameProcessor(int viewTag, jsi::Runtime& runtime, void JVisionCameraProxy::setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& frameProcessorObject) {
const jsi::Object& frameProcessorObject) {
#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS #if VISION_CAMERA_ENABLE_FRAME_PROCESSORS
auto frameProcessorType = auto frameProcessorType = frameProcessorObject.getProperty(runtime, "type").asString(runtime).utf8(runtime);
frameProcessorObject.getProperty(runtime, "type").asString(runtime).utf8(runtime); auto worklet = std::make_shared<RNWorklet::JsiWorklet>(runtime, frameProcessorObject.getProperty(runtime, "frameProcessor"));
auto worklet = std::make_shared<RNWorklet::JsiWorklet>(
runtime, frameProcessorObject.getProperty(runtime, "frameProcessor"));
jni::local_ref<JFrameProcessor::javaobject> frameProcessor; jni::local_ref<JFrameProcessor::javaobject> frameProcessor;
if (frameProcessorType == "frame-processor") { if (frameProcessorType == "frame-processor") {
@ -75,9 +70,7 @@ void JVisionCameraProxy::setFrameProcessor(int viewTag, jsi::Runtime& runtime,
throw std::runtime_error("Unknown FrameProcessor.type passed! Received: " + frameProcessorType); throw std::runtime_error("Unknown FrameProcessor.type passed! Received: " + frameProcessorType);
} }
auto setFrameProcessorMethod = auto setFrameProcessorMethod = javaClassLocal()->getMethod<void(int, alias_ref<JFrameProcessor::javaobject>)>("setFrameProcessor");
javaClassLocal()->getMethod<void(int, alias_ref<JFrameProcessor::javaobject>)>(
"setFrameProcessor");
setFrameProcessorMethod(_javaPart, viewTag, frameProcessor); setFrameProcessorMethod(_javaPart, viewTag, frameProcessor);
#else #else
throw std::runtime_error("system/frame-processors-unavailable: Frame Processors are disabled!"); throw std::runtime_error("system/frame-processors-unavailable: Frame Processors are disabled!");
@ -89,11 +82,9 @@ void JVisionCameraProxy::removeFrameProcessor(int viewTag) {
removeFrameProcessorMethod(_javaPart, viewTag); removeFrameProcessorMethod(_javaPart, viewTag);
} }
local_ref<JFrameProcessorPlugin::javaobject> local_ref<JFrameProcessorPlugin::javaobject> JVisionCameraProxy::getFrameProcessorPlugin(const std::string& name, TOptions options) {
JVisionCameraProxy::getFrameProcessorPlugin(const std::string& name, TOptions options) {
auto getFrameProcessorPluginMethod = auto getFrameProcessorPluginMethod =
javaClassLocal()->getMethod<JFrameProcessorPlugin(local_ref<jstring>, TOptions)>( javaClassLocal()->getMethod<JFrameProcessorPlugin(local_ref<jstring>, TOptions)>("getFrameProcessorPlugin");
"getFrameProcessorPlugin");
return getFrameProcessorPluginMethod(_javaPart, make_jstring(name), std::move(options)); return getFrameProcessorPluginMethod(_javaPart, make_jstring(name), std::move(options));
} }
@ -101,8 +92,7 @@ void JVisionCameraProxy::registerNatives() {
registerHybrid({makeNativeMethod("initHybrid", JVisionCameraProxy::initHybrid)}); registerHybrid({makeNativeMethod("initHybrid", JVisionCameraProxy::initHybrid)});
} }
TSelf JVisionCameraProxy::initHybrid(alias_ref<jhybridobject> jThis, jlong jsRuntimePointer, TSelf JVisionCameraProxy::initHybrid(alias_ref<jhybridobject> jThis, jlong jsRuntimePointer, TJSCallInvokerHolder jsCallInvokerHolder,
TJSCallInvokerHolder jsCallInvokerHolder,
const TScheduler& scheduler) { const TScheduler& scheduler) {
__android_log_write(ANDROID_LOG_INFO, TAG, "Initializing VisionCameraProxy..."); __android_log_write(ANDROID_LOG_INFO, TAG, "Initializing VisionCameraProxy...");

View File

@ -30,8 +30,8 @@ public:
void setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& frameProcessor); void setFrameProcessor(int viewTag, jsi::Runtime& runtime, const jsi::Object& frameProcessor);
void removeFrameProcessor(int viewTag); void removeFrameProcessor(int viewTag);
jni::local_ref<JFrameProcessorPlugin::javaobject> jni::local_ref<JFrameProcessorPlugin::javaobject> getFrameProcessorPlugin(const std::string& name,
getFrameProcessorPlugin(const std::string& name, jni::local_ref<JMap<jstring, jobject>> options); jni::local_ref<JMap<jstring, jobject>> options);
jsi::Runtime* getJSRuntime() { jsi::Runtime* getJSRuntime() {
return _runtime; return _runtime;
@ -48,14 +48,12 @@ private:
static auto constexpr TAG = "VisionCameraProxy"; static auto constexpr TAG = "VisionCameraProxy";
static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/VisionCameraProxy;"; static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/VisionCameraProxy;";
explicit JVisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis, explicit JVisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::jhybridobject>& javaThis, jsi::Runtime* jsRuntime,
jsi::Runtime* jsRuntime,
const std::shared_ptr<facebook::react::CallInvoker>& jsCallInvoker, const std::shared_ptr<facebook::react::CallInvoker>& jsCallInvoker,
const jni::global_ref<JVisionCameraScheduler::javaobject>& scheduler); const jni::global_ref<JVisionCameraScheduler::javaobject>& scheduler);
static jni::local_ref<jhybriddata> static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaThis, jlong jsRuntimePointer,
initHybrid(jni::alias_ref<jhybridobject> javaThis, jlong jsRuntimePointer, jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder, const jni::alias_ref<JVisionCameraScheduler::javaobject>& scheduler);
const jni::alias_ref<JVisionCameraScheduler::javaobject>& scheduler);
}; };
} // namespace vision } // namespace vision

View File

@ -25,8 +25,7 @@ using namespace facebook;
*/ */
class JVisionCameraScheduler : public jni::HybridClass<JVisionCameraScheduler> { class JVisionCameraScheduler : public jni::HybridClass<JVisionCameraScheduler> {
public: public:
static auto constexpr kJavaDescriptor = static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/VisionCameraScheduler;";
"Lcom/mrousavy/camera/frameprocessor/VisionCameraScheduler;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static void registerNatives(); static void registerNatives();
@ -39,8 +38,7 @@ private:
std::queue<std::function<void()>> _jobs; std::queue<std::function<void()>> _jobs;
std::mutex _mutex; std::mutex _mutex;
explicit JVisionCameraScheduler(jni::alias_ref<JVisionCameraScheduler::jhybridobject> jThis) explicit JVisionCameraScheduler(jni::alias_ref<JVisionCameraScheduler::jhybridobject> jThis) : _javaPart(jni::make_global(jThis)) {}
: _javaPart(jni::make_global(jThis)) {}
// Schedules a call to `trigger` on the VisionCamera FP Thread // Schedules a call to `trigger` on the VisionCamera FP Thread
void scheduleTrigger(); void scheduleTrigger();

View File

@ -6,7 +6,7 @@ Standard: c++14
# Indentation # Indentation
IndentWidth: 2 IndentWidth: 2
ColumnLimit: 100 ColumnLimit: 140
# Includes # Includes
SortIncludes: true SortIncludes: true

View File

@ -81,16 +81,14 @@ void invalidateArrayBufferCache(jsi::Runtime& runtime) {
TypedArrayKind getTypedArrayKindForName(const std::string& name); TypedArrayKind getTypedArrayKindForName(const std::string& name);
TypedArrayBase::TypedArrayBase(jsi::Runtime& runtime, size_t size, TypedArrayKind kind) TypedArrayBase::TypedArrayBase(jsi::Runtime& runtime, size_t size, TypedArrayKind kind)
: TypedArrayBase( : TypedArrayBase(runtime, runtime.global()
runtime, runtime.global() .getProperty(runtime, propNameIDCache.getConstructorNameProp(runtime, kind))
.getProperty(runtime, propNameIDCache.getConstructorNameProp(runtime, kind)) .asObject(runtime)
.asObject(runtime) .asFunction(runtime)
.asFunction(runtime) .callAsConstructor(runtime, {static_cast<double>(size)})
.callAsConstructor(runtime, {static_cast<double>(size)}) .asObject(runtime)) {}
.asObject(runtime)) {}
TypedArrayBase::TypedArrayBase(jsi::Runtime& runtime, const jsi::Object& obj) TypedArrayBase::TypedArrayBase(jsi::Runtime& runtime, const jsi::Object& obj) : jsi::Object(jsi::Value(runtime, obj).asObject(runtime)) {}
: jsi::Object(jsi::Value(runtime, obj).asObject(runtime)) {}
TypedArrayKind TypedArrayBase::getKind(jsi::Runtime& runtime) const { TypedArrayKind TypedArrayBase::getKind(jsi::Runtime& runtime) const {
auto constructorName = this->getProperty(runtime, propNameIDCache.get(runtime, Prop::Constructor)) auto constructorName = this->getProperty(runtime, propNameIDCache.get(runtime, Prop::Constructor))
@ -174,13 +172,11 @@ std::vector<uint8_t> arrayBufferToVector(jsi::Runtime& runtime, jsi::Object& jsO
auto jsArrayBuffer = jsObj.getArrayBuffer(runtime); auto jsArrayBuffer = jsObj.getArrayBuffer(runtime);
uint8_t* dataBlock = jsArrayBuffer.data(runtime); uint8_t* dataBlock = jsArrayBuffer.data(runtime);
size_t blockSize = size_t blockSize = jsArrayBuffer.getProperty(runtime, propNameIDCache.get(runtime, Prop::ByteLength)).asNumber();
jsArrayBuffer.getProperty(runtime, propNameIDCache.get(runtime, Prop::ByteLength)).asNumber();
return std::vector<uint8_t>(dataBlock, dataBlock + blockSize); return std::vector<uint8_t>(dataBlock, dataBlock + blockSize);
} }
void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vector<uint8_t> data, void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vector<uint8_t> data, size_t offset) {
size_t offset) {
uint8_t* dataBlock = buffer.data(runtime); uint8_t* dataBlock = buffer.data(runtime);
size_t blockSize = buffer.size(runtime); size_t blockSize = buffer.size(runtime);
if (data.size() > blockSize) { if (data.size() > blockSize) {
@ -189,28 +185,22 @@ void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vec
std::copy(data.begin(), data.end(), dataBlock + offset); std::copy(data.begin(), data.end(), dataBlock + offset);
} }
template <TypedArrayKind T> template <TypedArrayKind T> TypedArray<T>::TypedArray(jsi::Runtime& runtime, size_t size) : TypedArrayBase(runtime, size, T) {}
TypedArray<T>::TypedArray(jsi::Runtime& runtime, size_t size) : TypedArrayBase(runtime, size, T) {}
template <TypedArrayKind T> template <TypedArrayKind T>
TypedArray<T>::TypedArray(jsi::Runtime& runtime, std::vector<ContentType<T>> data) TypedArray<T>::TypedArray(jsi::Runtime& runtime, std::vector<ContentType<T>> data) : TypedArrayBase(runtime, data.size(), T) {
: TypedArrayBase(runtime, data.size(), T) {
update(runtime, data); update(runtime, data);
} }
template <TypedArrayKind T> template <TypedArrayKind T> TypedArray<T>::TypedArray(TypedArrayBase&& base) : TypedArrayBase(std::move(base)) {}
TypedArray<T>::TypedArray(TypedArrayBase&& base) : TypedArrayBase(std::move(base)) {}
template <TypedArrayKind T> template <TypedArrayKind T> std::vector<ContentType<T>> TypedArray<T>::toVector(jsi::Runtime& runtime) {
std::vector<ContentType<T>> TypedArray<T>::toVector(jsi::Runtime& runtime) { auto start = reinterpret_cast<ContentType<T>*>(getBuffer(runtime).data(runtime) + byteOffset(runtime));
auto start =
reinterpret_cast<ContentType<T>*>(getBuffer(runtime).data(runtime) + byteOffset(runtime));
auto end = start + size(runtime); auto end = start + size(runtime);
return std::vector<ContentType<T>>(start, end); return std::vector<ContentType<T>>(start, end);
} }
template <TypedArrayKind T> template <TypedArrayKind T> void TypedArray<T>::update(jsi::Runtime& runtime, const std::vector<ContentType<T>>& data) {
void TypedArray<T>::update(jsi::Runtime& runtime, const std::vector<ContentType<T>>& data) {
if (data.size() != size(runtime)) { if (data.size() != size(runtime)) {
throw jsi::JSError(runtime, "TypedArray can only be updated with a vector of the same size"); throw jsi::JSError(runtime, "TypedArray can only be updated with a vector of the same size");
} }
@ -218,8 +208,7 @@ void TypedArray<T>::update(jsi::Runtime& runtime, const std::vector<ContentType<
std::copy(data.begin(), data.end(), reinterpret_cast<ContentType<T>*>(rawData)); std::copy(data.begin(), data.end(), reinterpret_cast<ContentType<T>*>(rawData));
} }
template <TypedArrayKind T> template <TypedArrayKind T> void TypedArray<T>::updateUnsafe(jsi::Runtime& runtime, ContentType<T>* data, size_t length) {
void TypedArray<T>::updateUnsafe(jsi::Runtime& runtime, ContentType<T>* data, size_t length) {
if (length != size(runtime)) { if (length != size(runtime)) {
throw jsi::JSError(runtime, "TypedArray can only be updated with an array of the same size"); throw jsi::JSError(runtime, "TypedArray can only be updated with an array of the same size");
} }
@ -231,8 +220,7 @@ template <TypedArrayKind T> uint8_t* TypedArray<T>::data(jsi::Runtime& runtime)
return getBuffer(runtime).data(runtime) + byteOffset(runtime); return getBuffer(runtime).data(runtime) + byteOffset(runtime);
} }
const jsi::PropNameID& PropNameIDCache::getConstructorNameProp(jsi::Runtime& runtime, const jsi::PropNameID& PropNameIDCache::getConstructorNameProp(jsi::Runtime& runtime, TypedArrayKind kind) {
TypedArrayKind kind) {
switch (kind) { switch (kind) {
case TypedArrayKind::Int8Array: case TypedArrayKind::Int8Array:
return get(runtime, Prop::Int8Array); return get(runtime, Prop::Int8Array);
@ -256,9 +244,7 @@ const jsi::PropNameID& PropNameIDCache::getConstructorNameProp(jsi::Runtime& run
} }
jsi::PropNameID PropNameIDCache::createProp(jsi::Runtime& runtime, Prop prop) { jsi::PropNameID PropNameIDCache::createProp(jsi::Runtime& runtime, Prop prop) {
auto create = [&](const std::string& propName) { auto create = [&](const std::string& propName) { return jsi::PropNameID::forUtf8(runtime, propName); };
return jsi::PropNameID::forUtf8(runtime, propName);
};
switch (prop) { switch (prop) {
case Prop::Buffer: case Prop::Buffer:
return create("buffer"); return create("buffer");

View File

@ -97,8 +97,7 @@ bool isTypedArray(jsi::Runtime& runtime, const jsi::Object& jsObj);
TypedArrayBase getTypedArray(jsi::Runtime& runtime, const jsi::Object& jsObj); TypedArrayBase getTypedArray(jsi::Runtime& runtime, const jsi::Object& jsObj);
std::vector<uint8_t> arrayBufferToVector(jsi::Runtime& runtime, jsi::Object& jsObj); std::vector<uint8_t> arrayBufferToVector(jsi::Runtime& runtime, jsi::Object& jsObj);
void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vector<uint8_t> data, void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vector<uint8_t> data, size_t offset);
size_t offset);
template <TypedArrayKind T> class TypedArray : public TypedArrayBase { template <TypedArrayKind T> class TypedArray : public TypedArrayBase {
public: public:

View File

@ -14,22 +14,12 @@
@interface RCT_EXTERN_REMAP_MODULE (CameraView, CameraViewManager, RCTViewManager) @interface RCT_EXTERN_REMAP_MODULE (CameraView, CameraViewManager, RCTViewManager)
// Module Functions // Module Functions
RCT_EXTERN_METHOD(getCameraPermissionStatus RCT_EXTERN_METHOD(getCameraPermissionStatus : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
: (RCTPromiseResolveBlock)resolve reject RCT_EXTERN_METHOD(getMicrophonePermissionStatus : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
: (RCTPromiseRejectBlock)reject); RCT_EXTERN_METHOD(requestCameraPermission : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(getMicrophonePermissionStatus RCT_EXTERN_METHOD(requestMicrophonePermission : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(requestCameraPermission
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(requestMicrophonePermission
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(getAvailableCameraDevices RCT_EXTERN_METHOD(getAvailableCameraDevices : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject);
// Camera View Properties // Camera View Properties
RCT_EXPORT_VIEW_PROPERTY(isActive, BOOL); RCT_EXPORT_VIEW_PROPERTY(isActive, BOOL);
@ -73,10 +63,7 @@ RCT_EXTERN_METHOD(resumeRecording
: (nonnull NSNumber*)node resolve : (nonnull NSNumber*)node resolve
: (RCTPromiseResolveBlock)resolve reject : (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject); : (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(stopRecording RCT_EXTERN_METHOD(stopRecording : (nonnull NSNumber*)node resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject);
: (nonnull NSNumber*)node resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject);
RCT_EXTERN_METHOD(takePhoto RCT_EXTERN_METHOD(takePhoto
: (nonnull NSNumber*)node options : (nonnull NSNumber*)node options
: (NSDictionary*)options resolve : (NSDictionary*)options resolve

View File

@ -14,8 +14,7 @@
@interface Frame : NSObject @interface Frame : NSObject
- (instancetype _Nonnull)initWithBuffer:(CMSampleBufferRef _Nonnull)buffer - (instancetype _Nonnull)initWithBuffer:(CMSampleBufferRef _Nonnull)buffer orientation:(UIImageOrientation)orientation;
orientation:(UIImageOrientation)orientation;
@property(nonatomic, readonly) CMSampleBufferRef _Nonnull buffer; @property(nonatomic, readonly) CMSampleBufferRef _Nonnull buffer;
@property(nonatomic, readonly) UIImageOrientation orientation; @property(nonatomic, readonly) UIImageOrientation orientation;

View File

@ -15,8 +15,7 @@
UIImageOrientation orientation; UIImageOrientation orientation;
} }
- (instancetype)initWithBuffer:(CMSampleBufferRef _Nonnull)buffer - (instancetype)initWithBuffer:(CMSampleBufferRef _Nonnull)buffer orientation:(UIImageOrientation)orientation {
orientation:(UIImageOrientation)orientation {
self = [super init]; self = [super init];
if (self) { if (self) {
_buffer = buffer; _buffer = buffer;

View File

@ -46,12 +46,10 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
auto width = CVPixelBufferGetWidth(imageBuffer); auto width = CVPixelBufferGetWidth(imageBuffer);
auto height = CVPixelBufferGetHeight(imageBuffer); auto height = CVPixelBufferGetHeight(imageBuffer);
NSMutableString* string = NSMutableString* string = [NSMutableString stringWithFormat:@"%lu x %lu Frame", width, height];
[NSMutableString stringWithFormat:@"%lu x %lu Frame", width, height];
return jsi::String::createFromUtf8(runtime, string.UTF8String); return jsi::String::createFromUtf8(runtime, string.UTF8String);
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
runtime, jsi::PropNameID::forUtf8(runtime, "toString"), 0, toString);
} }
if (name == "incrementRefCount") { if (name == "incrementRefCount") {
auto incrementRefCount = JSI_HOST_FUNCTION_LAMBDA { auto incrementRefCount = JSI_HOST_FUNCTION_LAMBDA {
@ -59,8 +57,7 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
CFRetain(frame.buffer); CFRetain(frame.buffer);
return jsi::Value::undefined(); return jsi::Value::undefined();
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "incrementRefCount"), 0, incrementRefCount);
runtime, jsi::PropNameID::forUtf8(runtime, "incrementRefCount"), 0, incrementRefCount);
} }
if (name == "decrementRefCount") { if (name == "decrementRefCount") {
auto decrementRefCount = JSI_HOST_FUNCTION_LAMBDA { auto decrementRefCount = JSI_HOST_FUNCTION_LAMBDA {
@ -69,8 +66,7 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
CFRelease(frame.buffer); CFRelease(frame.buffer);
return jsi::Value::undefined(); return jsi::Value::undefined();
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "decrementRefCount"), 0, decrementRefCount);
runtime, jsi::PropNameID::forUtf8(runtime, "decrementRefCount"), 0, decrementRefCount);
} }
if (name == "toArrayBuffer") { if (name == "toArrayBuffer") {
auto toArrayBuffer = JSI_HOST_FUNCTION_LAMBDA { auto toArrayBuffer = JSI_HOST_FUNCTION_LAMBDA {
@ -82,19 +78,15 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
static constexpr auto ARRAYBUFFER_CACHE_PROP_NAME = "__frameArrayBufferCache"; static constexpr auto ARRAYBUFFER_CACHE_PROP_NAME = "__frameArrayBufferCache";
if (!runtime.global().hasProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME)) { if (!runtime.global().hasProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME)) {
vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray> arrayBuffer(runtime, vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray> arrayBuffer(runtime, arraySize);
arraySize);
runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer); runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer);
} }
auto arrayBufferCache = auto arrayBufferCache = runtime.global().getPropertyAsObject(runtime, ARRAYBUFFER_CACHE_PROP_NAME);
runtime.global().getPropertyAsObject(runtime, ARRAYBUFFER_CACHE_PROP_NAME); auto arrayBuffer = vision::getTypedArray(runtime, arrayBufferCache).get<vision::TypedArrayKind::Uint8ClampedArray>(runtime);
auto arrayBuffer = vision::getTypedArray(runtime, arrayBufferCache)
.get<vision::TypedArrayKind::Uint8ClampedArray>(runtime);
if (arrayBuffer.size(runtime) != arraySize) { if (arrayBuffer.size(runtime) != arraySize) {
arrayBuffer = arrayBuffer = vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray>(runtime, arraySize);
vision::TypedArray<vision::TypedArrayKind::Uint8ClampedArray>(runtime, arraySize);
runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer); runtime.global().setProperty(runtime, ARRAYBUFFER_CACHE_PROP_NAME, arrayBuffer);
} }
@ -105,13 +97,11 @@ jsi::Value FrameHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pr
return arrayBuffer; return arrayBuffer;
}; };
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "toArrayBuffer"), 0, toArrayBuffer);
runtime, jsi::PropNameID::forUtf8(runtime, "toArrayBuffer"), 0, toArrayBuffer);
} }
if (name == "isValid") { if (name == "isValid") {
auto isValid = frame != nil && frame.buffer != nil && CFGetRetainCount(frame.buffer) > 0 && auto isValid = frame != nil && frame.buffer != nil && CFGetRetainCount(frame.buffer) > 0 && CMSampleBufferIsValid(frame.buffer);
CMSampleBufferIsValid(frame.buffer);
return jsi::Value(isValid); return jsi::Value(isValid);
} }
if (name == "width") { if (name == "width") {

View File

@ -46,11 +46,8 @@ using namespace facebook;
auto message = jsError.getMessage(); auto message = jsError.getMessage();
_workletContext->invokeOnJsThread([message](jsi::Runtime& jsRuntime) { _workletContext->invokeOnJsThread([message](jsi::Runtime& jsRuntime) {
auto logFn = jsRuntime.global() auto logFn = jsRuntime.global().getPropertyAsObject(jsRuntime, "console").getPropertyAsFunction(jsRuntime, "error");
.getPropertyAsObject(jsRuntime, "console") logFn.call(jsRuntime, jsi::String::createFromUtf8(jsRuntime, "Frame Processor threw an error: " + message));
.getPropertyAsFunction(jsRuntime, "error");
logFn.call(jsRuntime, jsi::String::createFromUtf8(
jsRuntime, "Frame Processor threw an error: " + message));
}); });
} }
} }

View File

@ -12,10 +12,8 @@
@implementation FrameProcessorPlugin @implementation FrameProcessorPlugin
- (id _Nullable)callback:(Frame* _Nonnull)frame withArguments:(NSDictionary* _Nullable)arguments { - (id _Nullable)callback:(Frame* _Nonnull)frame withArguments:(NSDictionary* _Nullable)arguments {
[NSException [NSException raise:NSInternalInconsistencyException
raise:NSInternalInconsistencyException format:@"Frame Processor Plugin does not override the `callback(frame:withArguments:)` method!"];
format:
@"Frame Processor Plugin does not override the `callback(frame:withArguments:)` method!"];
return nil; return nil;
} }

View File

@ -17,8 +17,7 @@ using namespace facebook;
class FrameProcessorPluginHostObject : public jsi::HostObject { class FrameProcessorPluginHostObject : public jsi::HostObject {
public: public:
explicit FrameProcessorPluginHostObject(FrameProcessorPlugin* plugin, explicit FrameProcessorPluginHostObject(FrameProcessorPlugin* plugin, std::shared_ptr<react::CallInvoker> callInvoker)
std::shared_ptr<react::CallInvoker> callInvoker)
: _plugin(plugin), _callInvoker(callInvoker) {} : _plugin(plugin), _callInvoker(callInvoker) {}
~FrameProcessorPluginHostObject() {} ~FrameProcessorPluginHostObject() {}

View File

@ -14,33 +14,28 @@
using namespace facebook; using namespace facebook;
std::vector<jsi::PropNameID> std::vector<jsi::PropNameID> FrameProcessorPluginHostObject::getPropertyNames(jsi::Runtime& runtime) {
FrameProcessorPluginHostObject::getPropertyNames(jsi::Runtime& runtime) {
std::vector<jsi::PropNameID> result; std::vector<jsi::PropNameID> result;
result.push_back(jsi::PropNameID::forUtf8(runtime, std::string("call"))); result.push_back(jsi::PropNameID::forUtf8(runtime, std::string("call")));
return result; return result;
} }
jsi::Value FrameProcessorPluginHostObject::get(jsi::Runtime& runtime, jsi::Value FrameProcessorPluginHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propName) {
const jsi::PropNameID& propName) {
auto name = propName.utf8(runtime); auto name = propName.utf8(runtime);
if (name == "call") { if (name == "call") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "call"), 2, runtime, jsi::PropNameID::forUtf8(runtime, "call"), 2,
[=](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [=](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
// Frame is first argument // Frame is first argument
auto frameHostObject = auto frameHostObject = arguments[0].asObject(runtime).asHostObject<FrameHostObject>(runtime);
arguments[0].asObject(runtime).asHostObject<FrameHostObject>(runtime);
Frame* frame = frameHostObject->frame; Frame* frame = frameHostObject->frame;
// Options are second argument (possibly undefined) // Options are second argument (possibly undefined)
NSDictionary* options = nil; NSDictionary* options = nil;
if (count > 1) { if (count > 1) {
auto optionsObject = arguments[1].asObject(runtime); auto optionsObject = arguments[1].asObject(runtime);
options = JSINSObjectConversion::convertJSIObjectToNSDictionary(runtime, optionsObject, options = JSINSObjectConversion::convertJSIObjectToNSDictionary(runtime, optionsObject, _callInvoker);
_callInvoker);
} }
// Call actual Frame Processor Plugin // Call actual Frame Processor Plugin

View File

@ -14,13 +14,10 @@
@interface FrameProcessorPluginRegistry : NSObject @interface FrameProcessorPluginRegistry : NSObject
typedef FrameProcessorPlugin* _Nonnull (^PluginInitializerFunction)( typedef FrameProcessorPlugin* _Nonnull (^PluginInitializerFunction)(NSDictionary* _Nullable options);
NSDictionary* _Nullable options);
+ (void)addFrameProcessorPlugin:(NSString* _Nonnull)name + (void)addFrameProcessorPlugin:(NSString* _Nonnull)name withInitializer:(PluginInitializerFunction _Nonnull)pluginInitializer;
withInitializer:(PluginInitializerFunction _Nonnull)pluginInitializer;
+ (FrameProcessorPlugin* _Nullable)getPlugin:(NSString* _Nonnull)name + (FrameProcessorPlugin* _Nullable)getPlugin:(NSString* _Nonnull)name withOptions:(NSDictionary* _Nullable)options;
withOptions:(NSDictionary* _Nullable)options;
@end @end

View File

@ -19,10 +19,8 @@
return plugins; return plugins;
} }
+ (void)addFrameProcessorPlugin:(NSString*)name + (void)addFrameProcessorPlugin:(NSString*)name withInitializer:(PluginInitializerFunction)pluginInitializer {
withInitializer:(PluginInitializerFunction)pluginInitializer { BOOL alreadyExists = [[FrameProcessorPluginRegistry frameProcessorPlugins] valueForKey:name] != nil;
BOOL alreadyExists =
[[FrameProcessorPluginRegistry frameProcessorPlugins] valueForKey:name] != nil;
NSAssert(!alreadyExists, NSAssert(!alreadyExists,
@"Tried to add a Frame Processor Plugin with a name that already exists! Either choose " @"Tried to add a Frame Processor Plugin with a name that already exists! Either choose "
@"unique names, or " @"unique names, or "
@ -32,10 +30,8 @@
[[FrameProcessorPluginRegistry frameProcessorPlugins] setValue:pluginInitializer forKey:name]; [[FrameProcessorPluginRegistry frameProcessorPlugins] setValue:pluginInitializer forKey:name];
} }
+ (FrameProcessorPlugin*)getPlugin:(NSString* _Nonnull)name + (FrameProcessorPlugin*)getPlugin:(NSString* _Nonnull)name withOptions:(NSDictionary* _Nullable)options {
withOptions:(NSDictionary* _Nullable)options { PluginInitializerFunction initializer = [[FrameProcessorPluginRegistry frameProcessorPlugins] objectForKey:name];
PluginInitializerFunction initializer =
[[FrameProcessorPluginRegistry frameProcessorPlugins] objectForKey:name];
if (initializer == nil) { if (initializer == nil) {
return nil; return nil;
} }

View File

@ -39,27 +39,23 @@ jsi::Value convertObjCObjectToJSIValue(jsi::Runtime& runtime, id value);
NSString* convertJSIStringToNSString(jsi::Runtime& runtime, const jsi::String& value); NSString* convertJSIStringToNSString(jsi::Runtime& runtime, const jsi::String& value);
// any... -> NSArray // any... -> NSArray
NSArray* convertJSICStyleArrayToNSArray(jsi::Runtime& runtime, const jsi::Value* array, NSArray* convertJSICStyleArrayToNSArray(jsi::Runtime& runtime, const jsi::Value* array, size_t length,
size_t length, std::shared_ptr<CallInvoker> jsInvoker); std::shared_ptr<CallInvoker> jsInvoker);
// NSArray -> any... // NSArray -> any...
jsi::Value* convertNSArrayToJSICStyleArray(jsi::Runtime& runtime, NSArray* array); jsi::Value* convertNSArrayToJSICStyleArray(jsi::Runtime& runtime, NSArray* array);
// [] -> NSArray // [] -> NSArray
NSArray* convertJSIArrayToNSArray(jsi::Runtime& runtime, const jsi::Array& value, NSArray* convertJSIArrayToNSArray(jsi::Runtime& runtime, const jsi::Array& value, std::shared_ptr<CallInvoker> jsInvoker);
std::shared_ptr<CallInvoker> jsInvoker);
// {} -> NSDictionary // {} -> NSDictionary
NSDictionary* convertJSIObjectToNSDictionary(jsi::Runtime& runtime, const jsi::Object& value, NSDictionary* convertJSIObjectToNSDictionary(jsi::Runtime& runtime, const jsi::Object& value, std::shared_ptr<CallInvoker> jsInvoker);
std::shared_ptr<CallInvoker> jsInvoker);
// any -> id // any -> id
id convertJSIValueToObjCObject(jsi::Runtime& runtime, const jsi::Value& value, id convertJSIValueToObjCObject(jsi::Runtime& runtime, const jsi::Value& value, std::shared_ptr<CallInvoker> jsInvoker);
std::shared_ptr<CallInvoker> jsInvoker);
// (any...) => any -> (void)(id, id) // (any...) => any -> (void)(id, id)
RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime& runtime, RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime& runtime, const jsi::Function& value,
const jsi::Function& value,
std::shared_ptr<CallInvoker> jsInvoker); std::shared_ptr<CallInvoker> jsInvoker);
} // namespace JSINSObjectConversion } // namespace JSINSObjectConversion

View File

@ -85,8 +85,8 @@ NSString* convertJSIStringToNSString(jsi::Runtime& runtime, const jsi::String& v
return [NSString stringWithUTF8String:value.utf8(runtime).c_str()]; return [NSString stringWithUTF8String:value.utf8(runtime).c_str()];
} }
NSArray* convertJSICStyleArrayToNSArray(jsi::Runtime& runtime, const jsi::Value* array, NSArray* convertJSICStyleArrayToNSArray(jsi::Runtime& runtime, const jsi::Value* array, size_t length,
size_t length, std::shared_ptr<CallInvoker> jsInvoker) { std::shared_ptr<CallInvoker> jsInvoker) {
if (length < 1) if (length < 1)
return @[]; return @[];
NSMutableArray* result = [NSMutableArray new]; NSMutableArray* result = [NSMutableArray new];
@ -105,21 +105,17 @@ jsi::Value* convertNSArrayToJSICStyleArray(jsi::Runtime& runtime, NSArray* array
return result; return result;
} }
NSArray* convertJSIArrayToNSArray(jsi::Runtime& runtime, const jsi::Array& value, NSArray* convertJSIArrayToNSArray(jsi::Runtime& runtime, const jsi::Array& value, std::shared_ptr<CallInvoker> jsInvoker) {
std::shared_ptr<CallInvoker> jsInvoker) {
size_t size = value.size(runtime); size_t size = value.size(runtime);
NSMutableArray* result = [NSMutableArray new]; NSMutableArray* result = [NSMutableArray new];
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
// Insert kCFNull when it's `undefined` value to preserve the indices. // Insert kCFNull when it's `undefined` value to preserve the indices.
[result [result addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker) ?: (id)kCFNull];
addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker)
?: (id)kCFNull];
} }
return [result copy]; return [result copy];
} }
NSDictionary* convertJSIObjectToNSDictionary(jsi::Runtime& runtime, const jsi::Object& value, NSDictionary* convertJSIObjectToNSDictionary(jsi::Runtime& runtime, const jsi::Object& value, std::shared_ptr<CallInvoker> jsInvoker) {
std::shared_ptr<CallInvoker> jsInvoker) {
jsi::Array propertyNames = value.getPropertyNames(runtime); jsi::Array propertyNames = value.getPropertyNames(runtime);
size_t size = propertyNames.size(runtime); size_t size = propertyNames.size(runtime);
NSMutableDictionary* result = [NSMutableDictionary new]; NSMutableDictionary* result = [NSMutableDictionary new];
@ -134,8 +130,7 @@ NSDictionary* convertJSIObjectToNSDictionary(jsi::Runtime& runtime, const jsi::O
return [result copy]; return [result copy];
} }
id convertJSIValueToObjCObject(jsi::Runtime& runtime, const jsi::Value& value, id convertJSIValueToObjCObject(jsi::Runtime& runtime, const jsi::Value& value, std::shared_ptr<CallInvoker> jsInvoker) {
std::shared_ptr<CallInvoker> jsInvoker) {
if (value.isUndefined() || value.isNull()) { if (value.isUndefined() || value.isNull()) {
return nil; return nil;
} }
@ -169,8 +164,7 @@ id convertJSIValueToObjCObject(jsi::Runtime& runtime, const jsi::Value& value,
throw std::runtime_error("Unsupported jsi::jsi::Value kind"); throw std::runtime_error("Unsupported jsi::jsi::Value kind");
} }
RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime& runtime, RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime& runtime, const jsi::Function& value,
const jsi::Function& value,
std::shared_ptr<CallInvoker> jsInvoker) { std::shared_ptr<CallInvoker> jsInvoker) {
auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker); auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker);
RCTBlockGuard* blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() { RCTBlockGuard* blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() {
@ -198,8 +192,7 @@ RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime& runtime,
} }
const jsi::Value* args = convertNSArrayToJSICStyleArray(strongWrapper2->runtime(), responses); const jsi::Value* args = convertNSArrayToJSICStyleArray(strongWrapper2->runtime(), responses);
strongWrapper2->callback().call(strongWrapper2->runtime(), args, strongWrapper2->callback().call(strongWrapper2->runtime(), args, static_cast<size_t>(responses.count));
static_cast<size_t>(responses.count));
strongWrapper2->destroy(); strongWrapper2->destroy();
delete[] args; delete[] args;

View File

@ -20,8 +20,7 @@ using namespace facebook;
class VisionCameraProxy : public jsi::HostObject { class VisionCameraProxy : public jsi::HostObject {
public: public:
explicit VisionCameraProxy(jsi::Runtime& runtime, explicit VisionCameraProxy(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker> callInvoker);
std::shared_ptr<react::CallInvoker> callInvoker);
~VisionCameraProxy(); ~VisionCameraProxy();
public: public:
@ -31,8 +30,7 @@ public:
private: private:
void setFrameProcessor(jsi::Runtime& runtime, int viewTag, const jsi::Object& frameProcessor); void setFrameProcessor(jsi::Runtime& runtime, int viewTag, const jsi::Object& frameProcessor);
void removeFrameProcessor(jsi::Runtime& runtime, int viewTag); void removeFrameProcessor(jsi::Runtime& runtime, int viewTag);
jsi::Value getFrameProcessorPlugin(jsi::Runtime& runtime, std::string name, jsi::Value getFrameProcessorPlugin(jsi::Runtime& runtime, std::string name, const jsi::Object& options);
const jsi::Object& options);
private: private:
std::shared_ptr<RNWorklet::JsiWorkletContext> _workletContext; std::shared_ptr<RNWorklet::JsiWorkletContext> _workletContext;

View File

@ -37,8 +37,7 @@ __attribute__((objc_runtime_name("_TtC12VisionCamera10CameraView")))
using namespace facebook; using namespace facebook;
VisionCameraProxy::VisionCameraProxy(jsi::Runtime& runtime, VisionCameraProxy::VisionCameraProxy(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker> callInvoker) {
std::shared_ptr<react::CallInvoker> callInvoker) {
_callInvoker = callInvoker; _callInvoker = callInvoker;
NSLog(@"VisionCameraProxy: Creating Worklet Context..."); NSLog(@"VisionCameraProxy: Creating Worklet Context...");
@ -51,8 +50,7 @@ VisionCameraProxy::VisionCameraProxy(jsi::Runtime& runtime,
dispatch_async(CameraQueues.videoQueue, [f = std::move(f)]() { f(); }); dispatch_async(CameraQueues.videoQueue, [f = std::move(f)]() { f(); });
}; };
_workletContext = std::make_shared<RNWorklet::JsiWorkletContext>("VisionCamera", &runtime, _workletContext = std::make_shared<RNWorklet::JsiWorkletContext>("VisionCamera", &runtime, runOnJS, runOnWorklet);
runOnJS, runOnWorklet);
NSLog(@"VisionCameraProxy: Worklet Context Created!"); NSLog(@"VisionCameraProxy: Worklet Context Created!");
} }
@ -71,23 +69,18 @@ std::vector<jsi::PropNameID> VisionCameraProxy::getPropertyNames(jsi::Runtime& r
return result; return result;
} }
void VisionCameraProxy::setFrameProcessor(jsi::Runtime& runtime, int viewTag, void VisionCameraProxy::setFrameProcessor(jsi::Runtime& runtime, int viewTag, const jsi::Object& object) {
const jsi::Object& object) {
auto frameProcessorType = object.getProperty(runtime, "type").asString(runtime).utf8(runtime); auto frameProcessorType = object.getProperty(runtime, "type").asString(runtime).utf8(runtime);
auto worklet = std::make_shared<RNWorklet::JsiWorklet>( auto worklet = std::make_shared<RNWorklet::JsiWorklet>(runtime, object.getProperty(runtime, "frameProcessor"));
runtime, object.getProperty(runtime, "frameProcessor"));
RCTExecuteOnMainQueue(^{ RCTExecuteOnMainQueue(^{
auto currentBridge = [RCTBridge currentBridge]; auto currentBridge = [RCTBridge currentBridge];
auto anonymousView = auto anonymousView = [currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]];
[currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]];
auto view = static_cast<CameraView*>(anonymousView); auto view = static_cast<CameraView*>(anonymousView);
if (frameProcessorType == "frame-processor") { if (frameProcessorType == "frame-processor") {
view.frameProcessor = [[FrameProcessor alloc] initWithWorklet:worklet view.frameProcessor = [[FrameProcessor alloc] initWithWorklet:worklet context:_workletContext];
context:_workletContext];
} else { } else {
throw std::runtime_error("Unknown FrameProcessor.type passed! Received: " + throw std::runtime_error("Unknown FrameProcessor.type passed! Received: " + frameProcessorType);
frameProcessorType);
} }
}); });
} }
@ -95,20 +88,16 @@ void VisionCameraProxy::setFrameProcessor(jsi::Runtime& runtime, int viewTag,
void VisionCameraProxy::removeFrameProcessor(jsi::Runtime& runtime, int viewTag) { void VisionCameraProxy::removeFrameProcessor(jsi::Runtime& runtime, int viewTag) {
RCTExecuteOnMainQueue(^{ RCTExecuteOnMainQueue(^{
auto currentBridge = [RCTBridge currentBridge]; auto currentBridge = [RCTBridge currentBridge];
auto anonymousView = auto anonymousView = [currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]];
[currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]];
auto view = static_cast<CameraView*>(anonymousView); auto view = static_cast<CameraView*>(anonymousView);
view.frameProcessor = nil; view.frameProcessor = nil;
}); });
} }
jsi::Value VisionCameraProxy::getFrameProcessorPlugin(jsi::Runtime& runtime, std::string name, jsi::Value VisionCameraProxy::getFrameProcessorPlugin(jsi::Runtime& runtime, std::string name, const jsi::Object& options) {
const jsi::Object& options) {
NSString* key = [NSString stringWithUTF8String:name.c_str()]; NSString* key = [NSString stringWithUTF8String:name.c_str()];
NSDictionary* optionsObjc = NSDictionary* optionsObjc = JSINSObjectConversion::convertJSIObjectToNSDictionary(runtime, options, _callInvoker);
JSINSObjectConversion::convertJSIObjectToNSDictionary(runtime, options, _callInvoker); FrameProcessorPlugin* plugin = [FrameProcessorPluginRegistry getPlugin:key withOptions:optionsObjc];
FrameProcessorPlugin* plugin = [FrameProcessorPluginRegistry getPlugin:key
withOptions:optionsObjc];
if (plugin == nil) { if (plugin == nil) {
return jsi::Value::undefined(); return jsi::Value::undefined();
} }
@ -123,8 +112,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "setFrameProcessor") { if (name == "setFrameProcessor") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "setFrameProcessor"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "setFrameProcessor"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
auto viewTag = arguments[0].asNumber(); auto viewTag = arguments[0].asNumber();
auto object = arguments[1].asObject(runtime); auto object = arguments[1].asObject(runtime);
this->setFrameProcessor(runtime, static_cast<int>(viewTag), object); this->setFrameProcessor(runtime, static_cast<int>(viewTag), object);
@ -134,8 +122,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "removeFrameProcessor") { if (name == "removeFrameProcessor") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "removeFrameProcessor"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "removeFrameProcessor"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
auto viewTag = arguments[0].asNumber(); auto viewTag = arguments[0].asNumber();
this->removeFrameProcessor(runtime, static_cast<int>(viewTag)); this->removeFrameProcessor(runtime, static_cast<int>(viewTag));
return jsi::Value::undefined(); return jsi::Value::undefined();
@ -144,8 +131,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
if (name == "getFrameProcessorPlugin") { if (name == "getFrameProcessorPlugin") {
return jsi::Function::createFromHostFunction( return jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forUtf8(runtime, "getFrameProcessorPlugin"), 1, runtime, jsi::PropNameID::forUtf8(runtime, "getFrameProcessorPlugin"), 1,
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
size_t count) -> jsi::Value {
if (count < 1 || !arguments[0].isString()) { if (count < 1 || !arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument needs to be a string (pluginName)!"); throw jsi::JSError(runtime, "First argument needs to be a string (pluginName)!");
} }
@ -170,8 +156,7 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
// global.VisionCameraProxy // global.VisionCameraProxy
auto visionCameraProxy = std::make_shared<VisionCameraProxy>(runtime, bridge.jsCallInvoker); auto visionCameraProxy = std::make_shared<VisionCameraProxy>(runtime, bridge.jsCallInvoker);
runtime.global().setProperty(runtime, "VisionCameraProxy", runtime.global().setProperty(runtime, "VisionCameraProxy", jsi::Object::createFromHostObject(runtime, visionCameraProxy));
jsi::Object::createFromHostObject(runtime, visionCameraProxy));
return YES; return YES;
} }