Created
August 6, 2023 23:52
-
-
Save RaphBlanchet/1e8ab14edb7ad49929487fec8360dd5f to your computer and use it in GitHub Desktop.
React Native Vision Camera x Reanimated v3 patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/react-native-vision-camera/ios/Frame Processor/FrameProcessorRuntimeManager.mm b/node_modules/react-native-vision-camera/ios/Frame Processor/FrameProcessorRuntimeManager.mm | |
index 3841b20..505f276 100644 | |
--- a/node_modules/react-native-vision-camera/ios/Frame Processor/FrameProcessorRuntimeManager.mm | |
+++ b/node_modules/react-native-vision-camera/ios/Frame Processor/FrameProcessorRuntimeManager.mm | |
@@ -19,22 +19,6 @@ | |
#import <React/RCTUIManager.h> | |
#import <ReactCommon/RCTTurboModuleManager.h> | |
-#ifndef VISION_CAMERA_DISABLE_FRAME_PROCESSORS | |
- #if __has_include(<RNReanimated/NativeReanimatedModule.h>) | |
- #if __has_include(<RNReanimated/RuntimeManager.h>) | |
- #import <RNReanimated/RuntimeManager.h> | |
- #import <RNReanimated/RuntimeDecorator.h> | |
- #import <RNReanimated/REAIOSErrorHandler.h> | |
- #import "VisionCameraScheduler.h" | |
- #define ENABLE_FRAME_PROCESSORS | |
- #else | |
- #warning Your react-native-reanimated version is not compatible with VisionCamera, Frame Processors are disabled. Make sure you're using reanimated 2.2.0 or above! | |
- #endif | |
- #else | |
- #warning The NativeReanimatedModule.h header could not be found, Frame Processors are disabled. If you want to use Frame Processors, make sure you install react-native-reanimated! | |
- #endif | |
-#endif | |
- | |
#import "FrameProcessorUtils.h" | |
#import "FrameProcessorCallback.h" | |
#import "../React Utils/MakeJSIRuntime.h" | |
@@ -51,154 +35,18 @@ @interface CameraView : UIView | |
@end | |
@implementation FrameProcessorRuntimeManager { | |
-#ifdef ENABLE_FRAME_PROCESSORS | |
- std::unique_ptr<reanimated::RuntimeManager> runtimeManager; | |
-#endif | |
__weak RCTBridge* weakBridge; | |
} | |
- (instancetype) initWithBridge:(RCTBridge*)bridge { | |
self = [super init]; | |
if (self) { | |
-#ifdef ENABLE_FRAME_PROCESSORS | |
- NSLog(@"FrameProcessorBindings: Creating Runtime Manager..."); | |
- weakBridge = bridge; | |
- | |
- auto runtime = vision::makeJSIRuntime(); | |
- reanimated::RuntimeDecorator::decorateRuntime(*runtime, "FRAME_PROCESSOR"); | |
- runtime->global().setProperty(*runtime, "_FRAME_PROCESSOR", jsi::Value(true)); | |
- | |
- auto callInvoker = bridge.jsCallInvoker; | |
- auto scheduler = std::make_shared<vision::VisionCameraScheduler>(callInvoker); | |
- runtimeManager = std::make_unique<reanimated::RuntimeManager>(std::move(runtime), | |
- std::make_shared<reanimated::REAIOSErrorHandler>(scheduler), | |
- scheduler); | |
- NSLog(@"FrameProcessorBindings: Runtime Manager created!"); | |
- | |
- NSLog(@"FrameProcessorBindings: Installing Frame Processor plugins..."); | |
- auto& visionRuntime = *runtimeManager->runtime; | |
- auto visionGlobal = visionRuntime.global(); | |
- | |
- for (NSString* pluginKey in [FrameProcessorPluginRegistry frameProcessorPlugins]) { | |
- auto pluginName = [pluginKey UTF8String]; | |
- | |
- NSLog(@"FrameProcessorBindings: Installing Frame Processor plugin \"%s\"...", pluginName); | |
- FrameProcessorPlugin callback = [[FrameProcessorPluginRegistry frameProcessorPlugins] valueForKey:pluginKey]; | |
- | |
- auto function = [callback, callInvoker](jsi::Runtime& runtime, | |
- const jsi::Value& thisValue, | |
- const jsi::Value* arguments, | |
- size_t count) -> jsi::Value { | |
- auto frameHostObject = arguments[0].asObject(runtime).asHostObject(runtime); | |
- auto frame = static_cast<FrameHostObject*>(frameHostObject.get()); | |
- | |
- auto args = convertJSICStyleArrayToNSArray(runtime, | |
- arguments + 1, // start at index 1 since first arg = Frame | |
- count - 1, // use smaller count | |
- callInvoker); | |
- id result = callback(frame->frame, args); | |
- | |
- return convertObjCObjectToJSIValue(runtime, result); | |
- }; | |
- | |
- visionGlobal.setProperty(visionRuntime, pluginName, jsi::Function::createFromHostFunction(visionRuntime, | |
- jsi::PropNameID::forAscii(visionRuntime, pluginName), | |
- 1, // frame | |
- function)); | |
- } | |
- | |
- NSLog(@"FrameProcessorBindings: Frame Processor plugins installed!"); | |
-#else | |
NSLog(@"Reanimated not found, Frame Processors are disabled."); | |
-#endif | |
} | |
return self; | |
} | |
- (void) installFrameProcessorBindings { | |
-#ifdef ENABLE_FRAME_PROCESSORS | |
- if (!weakBridge) { | |
- NSLog(@"FrameProcessorBindings: Failed to install Frame Processor Bindings - bridge was null!"); | |
- return; | |
- } | |
- | |
- NSLog(@"FrameProcessorBindings: Installing Frame Processor Bindings for Bridge..."); | |
- RCTCxxBridge *cxxBridge = (RCTCxxBridge *)weakBridge; | |
- if (!cxxBridge.runtime) { | |
- return; | |
- } | |
- | |
- jsi::Runtime& jsiRuntime = *(jsi::Runtime*)cxxBridge.runtime; | |
- NSLog(@"FrameProcessorBindings: Installing global functions..."); | |
- | |
- // setFrameProcessor(viewTag: number, frameProcessor: (frame: Frame) => void) | |
- auto setFrameProcessor = [self](jsi::Runtime& runtime, | |
- const jsi::Value& thisValue, | |
- const jsi::Value* arguments, | |
- size_t count) -> jsi::Value { | |
- NSLog(@"FrameProcessorBindings: Setting new frame processor..."); | |
- if (!arguments[0].isNumber()) throw jsi::JSError(runtime, "Camera::setFrameProcessor: First argument ('viewTag') must be a number!"); | |
- if (!arguments[1].isObject()) throw jsi::JSError(runtime, "Camera::setFrameProcessor: Second argument ('frameProcessor') must be a function!"); | |
- if (!runtimeManager || !runtimeManager->runtime) throw jsi::JSError(runtime, "Camera::setFrameProcessor: The RuntimeManager is not yet initialized!"); | |
- | |
- auto viewTag = arguments[0].asNumber(); | |
- NSLog(@"FrameProcessorBindings: Adapting Shareable value from function (conversion to worklet)..."); | |
- auto worklet = reanimated::ShareableValue::adapt(runtime, arguments[1], runtimeManager.get()); | |
- NSLog(@"FrameProcessorBindings: Successfully created worklet!"); | |
- | |
- RCTExecuteOnMainQueue([=]() { | |
- auto currentBridge = [RCTBridge currentBridge]; | |
- auto anonymousView = [currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]]; | |
- auto view = static_cast<CameraView*>(anonymousView); | |
- | |
- dispatch_async(CameraQueues.frameProcessorQueue, [=]() { | |
- NSLog(@"FrameProcessorBindings: Converting worklet to Objective-C callback..."); | |
- | |
- auto& rt = *runtimeManager->runtime; | |
- auto function = worklet->getValue(rt).asObject(rt).asFunction(rt); | |
- | |
- view.frameProcessorCallback = convertJSIFunctionToFrameProcessorCallback(rt, function); | |
- NSLog(@"FrameProcessorBindings: Frame processor set!"); | |
- }); | |
- }); | |
- | |
- return jsi::Value::undefined(); | |
- }; | |
- jsiRuntime.global().setProperty(jsiRuntime, "setFrameProcessor", jsi::Function::createFromHostFunction(jsiRuntime, | |
- jsi::PropNameID::forAscii(jsiRuntime, "setFrameProcessor"), | |
- 2, // viewTag, frameProcessor | |
- setFrameProcessor)); | |
- | |
- // unsetFrameProcessor(viewTag: number) | |
- auto unsetFrameProcessor = [](jsi::Runtime& runtime, | |
- const jsi::Value& thisValue, | |
- const jsi::Value* arguments, | |
- size_t count) -> jsi::Value { | |
- NSLog(@"FrameProcessorBindings: Removing frame processor..."); | |
- if (!arguments[0].isNumber()) throw jsi::JSError(runtime, "Camera::unsetFrameProcessor: First argument ('viewTag') must be a number!"); | |
- auto viewTag = arguments[0].asNumber(); | |
- | |
- RCTExecuteOnMainQueue(^{ | |
- auto currentBridge = [RCTBridge currentBridge]; | |
- if (!currentBridge) return; | |
- | |
- auto anonymousView = [currentBridge.uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]]; | |
- if (!anonymousView) return; | |
- | |
- auto view = static_cast<CameraView*>(anonymousView); | |
- view.frameProcessorCallback = nil; | |
- NSLog(@"FrameProcessorBindings: Frame processor removed!"); | |
- }); | |
- | |
- return jsi::Value::undefined(); | |
- }; | |
- jsiRuntime.global().setProperty(jsiRuntime, "unsetFrameProcessor", jsi::Function::createFromHostFunction(jsiRuntime, | |
- jsi::PropNameID::forAscii(jsiRuntime, "unsetFrameProcessor"), | |
- 1, // viewTag | |
- unsetFrameProcessor)); | |
- | |
- NSLog(@"FrameProcessorBindings: Finished installing bindings."); | |
-#endif | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment