From 5855d4bae6798cbb32f8de07e3d8865c6fb805b6 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Fri, 3 May 2024 11:50:04 +0200 Subject: [PATCH 1/4] feat: Use `worklet(...)` to automatically detect `useFrameProcessor` dependencies --- package/example/ios/Podfile.lock | 4 ++-- package/example/package.json | 2 +- package/example/yarn.lock | 8 ++++---- package/package.json | 2 +- .../frame-processors/getWorkletDependencies.ts | 18 ++++++++++++++++++ package/src/hooks/useFrameProcessor.ts | 14 ++++++++------ package/src/skia/useSkiaFrameProcessor.ts | 12 ++++-------- package/yarn.lock | 8 ++++---- 8 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 package/src/frame-processors/getWorkletDependencies.ts diff --git a/package/example/ios/Podfile.lock b/package/example/ios/Podfile.lock index da2ed6afb2..5061253cc7 100644 --- a/package/example/ios/Podfile.lock +++ b/package/example/ios/Podfile.lock @@ -337,7 +337,7 @@ PODS: - react-native-video/Video (= 5.2.1) - react-native-video/Video (5.2.1): - React-Core - - react-native-worklets-core (1.2.0): + - react-native-worklets-core (1.3.0): - React - React-callinvoker - React-Core @@ -684,7 +684,7 @@ SPEC CHECKSUMS: react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89 react-native-skia: d368ae81d61c0253df36106ea76324b5a5519ddc react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253 - react-native-worklets-core: a316975bba20b73d47aa4d41bffb0ca984ba592e + react-native-worklets-core: 7a50c0c14005cc57df8583eabd99ea3f467fa277 React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d diff --git a/package/example/package.json b/package/example/package.json index 9b8df2180d..edeab38b2c 100644 --- a/package/example/package.json +++ b/package/example/package.json @@ -29,7 +29,7 @@ "react-native-static-safe-area-insets": "^2.2.0", "react-native-vector-icons": "^10.0.0", "react-native-video": "^5.2.1", - "react-native-worklets-core": "^1.2.0" + "react-native-worklets-core": "^1.3.0" }, "devDependencies": { "@babel/core": "^7.22.10", diff --git a/package/example/yarn.lock b/package/example/yarn.lock index cd7b27580a..473a18a76f 100644 --- a/package/example/yarn.lock +++ b/package/example/yarn.lock @@ -5233,10 +5233,10 @@ react-native-video@^5.2.1: prop-types "^15.7.2" shaka-player "^2.5.9" -react-native-worklets-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.2.0.tgz#155040a48d1e3f66107544867ec579c2f5044271" - integrity sha512-Uuf1Hg4V1w4I8eYNinwnnf+h+2YdQgwkUDQszY2yEEXWPWcZBWec0xjYn079RFRcKmGWuJ/zOtokjwy/IjJ9Fw== +react-native-worklets-core@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.0.tgz#218a4679ebc6d33dae37b70504a3b7ee5bacd0f1" + integrity sha512-rSutT5e2yD2+FilBeDum/BAenRSQCmYj5MtngfDhTkKpPtxJohKIx+b130OQAr8782Kcc4/sM2JZOGNhPAaRcQ== dependencies: string-hash-64 "^1.0.3" diff --git a/package/package.json b/package/package.json index f51dd7c4d7..71bf149831 100644 --- a/package/package.json +++ b/package/package.json @@ -98,7 +98,7 @@ "react-native": "^0.72.3", "react-native-builder-bob": "^0.21.3", "react-native-reanimated": "^3.8.1", - "react-native-worklets-core": "^1.2.0", + "react-native-worklets-core": "^1.3.0", "release-it": "^16.1.3", "typescript": "^5.1.6" }, diff --git a/package/src/frame-processors/getWorkletDependencies.ts b/package/src/frame-processors/getWorkletDependencies.ts new file mode 100644 index 0000000000..71f79895b9 --- /dev/null +++ b/package/src/frame-processors/getWorkletDependencies.ts @@ -0,0 +1,18 @@ +import type { DependencyList } from 'react' +import { WorkletsProxy } from '../dependencies/WorkletsProxy' + +type IWorklets = typeof WorkletsProxy +type Worklet = ReturnType + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnyFunc = (...args: any[]) => any + +export function getWorkletDependencies(func: TFunc): DependencyList { + if (__DEV__) { + // In debug, perform runtime checks to ensure the given func is a safe worklet, and throw an error otherwise + const worklet = WorkletsProxy.worklet(func) + return Object.values(worklet.__closure) + } + // in release, just cast and assume it's a worklet. if this crashes, the user saw it first in debug anyways. + return Object.values((func as unknown as Worklet).__closure) +} diff --git a/package/src/hooks/useFrameProcessor.ts b/package/src/hooks/useFrameProcessor.ts index a7348927be..002ec14c12 100644 --- a/package/src/hooks/useFrameProcessor.ts +++ b/package/src/hooks/useFrameProcessor.ts @@ -1,5 +1,5 @@ -import type { DependencyList } from 'react' import { useMemo } from 'react' +import { getWorkletDependencies } from '../frame-processors/getWorkletDependencies' import { withFrameRefCounting } from '../frame-processors/withFrameRefCounting' import type { ReadonlyFrameProcessor } from '../types/CameraProps' import type { Frame } from '../types/Frame' @@ -28,7 +28,6 @@ export function createFrameProcessor(frameProcessor: (frame: Frame) => void): Re * * @worklet * @param frameProcessor The Frame Processor - * @param dependencies The React dependencies which will be copied into the VisionCamera JS-Runtime. * @returns The memoized Frame Processor. * @example * ```ts @@ -36,10 +35,13 @@ export function createFrameProcessor(frameProcessor: (frame: Frame) => void): Re * 'worklet' * const faces = scanFaces(frame) * console.log(`Faces: ${faces}`) - * }, []) + * }) * ``` */ -export function useFrameProcessor(frameProcessor: (frame: Frame) => void, dependencies: DependencyList): ReadonlyFrameProcessor { - // eslint-disable-next-line react-hooks/exhaustive-deps - return useMemo(() => createFrameProcessor(frameProcessor), dependencies) +export function useFrameProcessor(frameProcessor: (frame: Frame) => void): ReadonlyFrameProcessor { + return useMemo( + () => createFrameProcessor(frameProcessor), + // eslint-disable-next-line react-hooks/exhaustive-deps + getWorkletDependencies(frameProcessor), + ) } diff --git a/package/src/skia/useSkiaFrameProcessor.ts b/package/src/skia/useSkiaFrameProcessor.ts index 30efc014ca..8b41dad195 100644 --- a/package/src/skia/useSkiaFrameProcessor.ts +++ b/package/src/skia/useSkiaFrameProcessor.ts @@ -1,5 +1,4 @@ import type { Frame, FrameInternal } from '../types/Frame' -import type { DependencyList } from 'react' import { useEffect, useMemo } from 'react' import type { Orientation } from '../types/Orientation' import type { DrawableFrameProcessor } from '../types/CameraProps' @@ -9,6 +8,7 @@ import type { SkCanvas, SkPaint, SkImage, SkSurface } from '@shopify/react-nativ import { SkiaProxy } from '../dependencies/SkiaProxy' import { withFrameRefCounting } from '../frame-processors/withFrameRefCounting' import { VisionCameraProxy } from '../frame-processors/VisionCameraProxy' +import { getWorkletDependencies } from '../frame-processors/getWorkletDependencies' /** * Represents a Camera Frame that can be directly drawn to using Skia. @@ -247,7 +247,6 @@ export function createSkiaFrameProcessor( * * @worklet * @param frameProcessor The Frame Processor - * @param dependencies The React dependencies which will be copied into the VisionCamera JS-Runtime. * @returns The memoized Skia Frame Processor. * @example * ```ts @@ -260,13 +259,10 @@ export function createSkiaFrameProcessor( * const rect = Skia.XYWHRect(face.x, face.y, face.width, face.height) * frame.drawRect(rect) * } - * }, []) + * }) * ``` */ -export function useSkiaFrameProcessor( - frameProcessor: (frame: DrawableFrame) => void, - dependencies: DependencyList, -): DrawableFrameProcessor { +export function useSkiaFrameProcessor(frameProcessor: (frame: DrawableFrame) => void): DrawableFrameProcessor { const surface = WorkletsProxy.useSharedValue({}) const offscreenTextures = WorkletsProxy.useSharedValue([]) @@ -292,6 +288,6 @@ export function useSkiaFrameProcessor( return useMemo( () => createSkiaFrameProcessor(frameProcessor, surface, offscreenTextures), // eslint-disable-next-line react-hooks/exhaustive-deps - dependencies, + getWorkletDependencies(frameProcessor), ) } diff --git a/package/yarn.lock b/package/yarn.lock index 39fcc4d245..906058ed6f 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -6744,10 +6744,10 @@ react-native-reanimated@^3.8.1: convert-source-map "^2.0.0" invariant "^2.2.4" -react-native-worklets-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.2.0.tgz#155040a48d1e3f66107544867ec579c2f5044271" - integrity sha512-Uuf1Hg4V1w4I8eYNinwnnf+h+2YdQgwkUDQszY2yEEXWPWcZBWec0xjYn079RFRcKmGWuJ/zOtokjwy/IjJ9Fw== +react-native-worklets-core@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.0.tgz#218a4679ebc6d33dae37b70504a3b7ee5bacd0f1" + integrity sha512-rSutT5e2yD2+FilBeDum/BAenRSQCmYj5MtngfDhTkKpPtxJohKIx+b130OQAr8782Kcc4/sM2JZOGNhPAaRcQ== dependencies: string-hash-64 "^1.0.3" From 0f67115cc69273e92be94f7e09ffa0d2802bfea4 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Fri, 3 May 2024 12:45:13 +0200 Subject: [PATCH 2/4] fix: Remove `useFrameProcessor` second arg --- package/example/src/CameraPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/example/src/CameraPage.tsx b/package/example/src/CameraPage.tsx index 28ae31146c..628a18acb6 100644 --- a/package/example/src/CameraPage.tsx +++ b/package/example/src/CameraPage.tsx @@ -187,7 +187,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement { examplePlugin(frame) exampleKotlinSwiftPlugin(frame) }) - }, []) + }) const videoHdr = format?.supportsVideoHdr && enableHdr const photoHdr = format?.supportsPhotoHdr && enableHdr && !videoHdr From a625eece2a7b5e190e96143b007464e832dc1227 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Wed, 8 May 2024 18:35:53 +0200 Subject: [PATCH 3/4] feat: Use `getWorkletDependencies` from worklets --- package/example/ios/Podfile.lock | 4 ++-- package/example/package.json | 2 +- package/example/yarn.lock | 8 ++++---- package/package.json | 6 +++--- .../frame-processors/getWorkletDependencies.ts | 18 ------------------ package/src/hooks/useFrameProcessor.ts | 4 ++-- package/src/skia/useSkiaFrameProcessor.ts | 3 +-- package/yarn.lock | 8 ++++---- 8 files changed, 17 insertions(+), 36 deletions(-) delete mode 100644 package/src/frame-processors/getWorkletDependencies.ts diff --git a/package/example/ios/Podfile.lock b/package/example/ios/Podfile.lock index 5061253cc7..690530576f 100644 --- a/package/example/ios/Podfile.lock +++ b/package/example/ios/Podfile.lock @@ -337,7 +337,7 @@ PODS: - react-native-video/Video (= 5.2.1) - react-native-video/Video (5.2.1): - React-Core - - react-native-worklets-core (1.3.0): + - react-native-worklets-core (1.3.2): - React - React-callinvoker - React-Core @@ -684,7 +684,7 @@ SPEC CHECKSUMS: react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89 react-native-skia: d368ae81d61c0253df36106ea76324b5a5519ddc react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253 - react-native-worklets-core: 7a50c0c14005cc57df8583eabd99ea3f467fa277 + react-native-worklets-core: ff4a4076ad86469e61ec8e39da2cb13c55da2385 React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d diff --git a/package/example/package.json b/package/example/package.json index edeab38b2c..2bf0e499ae 100644 --- a/package/example/package.json +++ b/package/example/package.json @@ -29,7 +29,7 @@ "react-native-static-safe-area-insets": "^2.2.0", "react-native-vector-icons": "^10.0.0", "react-native-video": "^5.2.1", - "react-native-worklets-core": "^1.3.0" + "react-native-worklets-core": "^1.3.2" }, "devDependencies": { "@babel/core": "^7.22.10", diff --git a/package/example/yarn.lock b/package/example/yarn.lock index 473a18a76f..45220b07d3 100644 --- a/package/example/yarn.lock +++ b/package/example/yarn.lock @@ -5233,10 +5233,10 @@ react-native-video@^5.2.1: prop-types "^15.7.2" shaka-player "^2.5.9" -react-native-worklets-core@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.0.tgz#218a4679ebc6d33dae37b70504a3b7ee5bacd0f1" - integrity sha512-rSutT5e2yD2+FilBeDum/BAenRSQCmYj5MtngfDhTkKpPtxJohKIx+b130OQAr8782Kcc4/sM2JZOGNhPAaRcQ== +react-native-worklets-core@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.2.tgz#0851ad7b524eae152d63adc20ad626eabecd9f26" + integrity sha512-wx2MdfiUP9gBluhtzrb5XeiAGxdnqVqosLCPIhP1sSF9EcgOKTBV4jxuRkYmZJ/DDcHvGPy0qwdqwyVtWAn3jQ== dependencies: string-hash-64 "^1.0.3" diff --git a/package/package.json b/package/package.json index 71bf149831..93cfd80f11 100644 --- a/package/package.json +++ b/package/package.json @@ -98,16 +98,16 @@ "react-native": "^0.72.3", "react-native-builder-bob": "^0.21.3", "react-native-reanimated": "^3.8.1", - "react-native-worklets-core": "^1.3.0", + "react-native-worklets-core": "^1.3.2", "release-it": "^16.1.3", "typescript": "^5.1.6" }, "peerDependencies": { - "@shopify/react-native-skia": "*", + "@shopify/react-native-skia": ">=1.2.3", "react": "*", "react-native": "*", "react-native-reanimated": "*", - "react-native-worklets-core": "*" + "react-native-worklets-core": ">=1.3.2" }, "peerDependenciesMeta": { "react-native-worklets-core": { diff --git a/package/src/frame-processors/getWorkletDependencies.ts b/package/src/frame-processors/getWorkletDependencies.ts deleted file mode 100644 index 71f79895b9..0000000000 --- a/package/src/frame-processors/getWorkletDependencies.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { DependencyList } from 'react' -import { WorkletsProxy } from '../dependencies/WorkletsProxy' - -type IWorklets = typeof WorkletsProxy -type Worklet = ReturnType - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnyFunc = (...args: any[]) => any - -export function getWorkletDependencies(func: TFunc): DependencyList { - if (__DEV__) { - // In debug, perform runtime checks to ensure the given func is a safe worklet, and throw an error otherwise - const worklet = WorkletsProxy.worklet(func) - return Object.values(worklet.__closure) - } - // in release, just cast and assume it's a worklet. if this crashes, the user saw it first in debug anyways. - return Object.values((func as unknown as Worklet).__closure) -} diff --git a/package/src/hooks/useFrameProcessor.ts b/package/src/hooks/useFrameProcessor.ts index 002ec14c12..f533e83d0b 100644 --- a/package/src/hooks/useFrameProcessor.ts +++ b/package/src/hooks/useFrameProcessor.ts @@ -1,8 +1,8 @@ import { useMemo } from 'react' -import { getWorkletDependencies } from '../frame-processors/getWorkletDependencies' import { withFrameRefCounting } from '../frame-processors/withFrameRefCounting' import type { ReadonlyFrameProcessor } from '../types/CameraProps' import type { Frame } from '../types/Frame' +import { WorkletsProxy } from '../dependencies/WorkletsProxy' /** * Create a new Frame Processor function which you can pass to the ``. @@ -42,6 +42,6 @@ export function useFrameProcessor(frameProcessor: (frame: Frame) => void): Reado return useMemo( () => createFrameProcessor(frameProcessor), // eslint-disable-next-line react-hooks/exhaustive-deps - getWorkletDependencies(frameProcessor), + WorkletsProxy.getWorkletDependencies(frameProcessor), ) } diff --git a/package/src/skia/useSkiaFrameProcessor.ts b/package/src/skia/useSkiaFrameProcessor.ts index 8b41dad195..32af5c08ca 100644 --- a/package/src/skia/useSkiaFrameProcessor.ts +++ b/package/src/skia/useSkiaFrameProcessor.ts @@ -8,7 +8,6 @@ import type { SkCanvas, SkPaint, SkImage, SkSurface } from '@shopify/react-nativ import { SkiaProxy } from '../dependencies/SkiaProxy' import { withFrameRefCounting } from '../frame-processors/withFrameRefCounting' import { VisionCameraProxy } from '../frame-processors/VisionCameraProxy' -import { getWorkletDependencies } from '../frame-processors/getWorkletDependencies' /** * Represents a Camera Frame that can be directly drawn to using Skia. @@ -288,6 +287,6 @@ export function useSkiaFrameProcessor(frameProcessor: (frame: DrawableFrame) => return useMemo( () => createSkiaFrameProcessor(frameProcessor, surface, offscreenTextures), // eslint-disable-next-line react-hooks/exhaustive-deps - getWorkletDependencies(frameProcessor), + WorkletsProxy.getWorkletDependencies(frameProcessor), ) } diff --git a/package/yarn.lock b/package/yarn.lock index 906058ed6f..8067b5b317 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -6744,10 +6744,10 @@ react-native-reanimated@^3.8.1: convert-source-map "^2.0.0" invariant "^2.2.4" -react-native-worklets-core@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.0.tgz#218a4679ebc6d33dae37b70504a3b7ee5bacd0f1" - integrity sha512-rSutT5e2yD2+FilBeDum/BAenRSQCmYj5MtngfDhTkKpPtxJohKIx+b130OQAr8782Kcc4/sM2JZOGNhPAaRcQ== +react-native-worklets-core@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.2.tgz#0851ad7b524eae152d63adc20ad626eabecd9f26" + integrity sha512-wx2MdfiUP9gBluhtzrb5XeiAGxdnqVqosLCPIhP1sSF9EcgOKTBV4jxuRkYmZJ/DDcHvGPy0qwdqwyVtWAn3jQ== dependencies: string-hash-64 "^1.0.3" From 8201273bce7bb9ec7e208a2bd3eee48f978582d9 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Wed, 8 May 2024 18:47:32 +0200 Subject: [PATCH 4/4] docs: Update docs to remove deps --- docs/docs/guides/EXPOSURE.mdx | 4 +-- .../FRAME_PROCESSORS_CREATE_OVERVIEW.mdx | 10 +++---- .../FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx | 2 +- .../guides/FRAME_PROCESSORS_INTERACTING.mdx | 10 +++---- docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx | 4 --- .../guides/FRAME_PROCESSOR_CREATE_FINAL.mdx | 2 +- docs/docs/guides/PIXEL_FORMATS.mdx | 2 +- docs/docs/guides/ZOOMING.mdx | 5 +--- package/.eslintrc.js | 8 ------ package/example/src/CameraPage.tsx | 2 +- package/example/src/views/CaptureButton.tsx | 27 +++++++++---------- package/src/types/CameraProps.ts | 2 +- package/src/types/Frame.ts | 4 +-- 13 files changed, 32 insertions(+), 50 deletions(-) diff --git a/docs/docs/guides/EXPOSURE.mdx b/docs/docs/guides/EXPOSURE.mdx index 563ea4a402..5ed2c5f4cb 100644 --- a/docs/docs/guides/EXPOSURE.mdx +++ b/docs/docs/guides/EXPOSURE.mdx @@ -49,12 +49,12 @@ Just like [`zoom`](zooming), this property can be animated using Reanimated. return interpolate(exposureSlider.value, [-1, 0, 1], [device.minExposure, 0, device.maxExposure]) - }, [exposureSlider, device]) + }) // 3. pass it as an animated prop const animatedProps = useAnimatedProps(() => ({ exposure: exposureValue.value - }), [exposureValue]) + })) // 4. render Camera return ( diff --git a/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx b/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx index ef8e77964a..a53781fcd2 100644 --- a/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx +++ b/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx @@ -21,7 +21,7 @@ function App() { // highlight-next-line const faces = detectFaces(frame) console.log(`Faces in Frame: ${faces}`) - }, []) + }) return ( @@ -91,7 +91,7 @@ const frameProcessor = useFrameProcessor((frame) => { // by downscaling the frame, the `detectObjects` function runs faster. const objects = detectObjects(resizedFrame) console.log(objects) -}, []) +}) ``` ### Parameters @@ -102,7 +102,7 @@ Frame Processors can also accept parameters, following the same type convention const frameProcessor = useFrameProcessor((frame) => { 'worklet' const faces = scanFaces(frame, { accuracy: 'fast' }) -}, []) +}) ``` ### Exceptions @@ -131,7 +131,7 @@ const frameProcessor = useFrameProcessor((frame) => { } catch (e) { console.log(`Error: ${e.message}`) } -}, []) +}) ``` ## What's possible? @@ -177,7 +177,7 @@ function App() { const frameProcessor = useFrameProcessor((frame) => { 'worklet' SomeAI.process(frame) // does not block frame processor, runs async - }, []) + }) useEffect(() => { SomeAI.addListener((results) => { diff --git a/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx b/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx index ff561d2e8c..dbe5e293dd 100644 --- a/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx +++ b/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx @@ -49,7 +49,7 @@ const frameProcessor = useFrameProcessor((frame) => { 'worklet' const result = global.myCppPlugin(frame) console.log(`C++ result: ${result}`) // <-- 42 -}, []) +}) ``` To include VisionCamera's C++ library in your plugin's C++ code, you need to link it and include the headers. diff --git a/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx b/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx index 72e4c42aea..b72f13260c 100644 --- a/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx +++ b/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx @@ -30,7 +30,7 @@ const frameProcessor = useFrameProcessor((frame) => { const objects = detectObjects(frame) const bananas = objects.filter((o) => o.type === targetObject) console.log(`Detected ${bananas} bananas!`) -}, [targetObject]) +}) ``` ### Shared Values @@ -45,7 +45,7 @@ const frameProcessor = useFrameProcessor((frame) => { 'worklet' const objects = detectObjects(frame) bananas.value = objects.filter((o) => o.type === 'banana') -}, [bananas]) +}) // Draw bananas in a Skia Canvas const onDraw = useDrawCallback((canvas) => { @@ -76,7 +76,7 @@ const frameProcessor = useFrameProcessor((frame) => { if (faces.length > 0) { onFaceDetected(faces[0]) } -}, [onFaceDetected]) +}) ``` ## Threading @@ -101,7 +101,7 @@ const frameProcessor = useFrameProcessor((frame) => { console.log("I'm running asynchronously, possibly at a lower FPS rate!") const faces = detectFaces(frame) }) -}, []) +}) ``` ### Running at a throttled FPS rate @@ -118,7 +118,7 @@ const frameProcessor = useFrameProcessor((frame) => { console.log("I'm running synchronously at 2 FPS!") const brightness = detectBrightness(frame) }) -}, []) +}) ``` #### 🚀 Next section: [Zooming](/docs/guides/zooming) (or [creating a Frame Processor Plugin](/docs/guides/frame-processors-plugins-overview)) diff --git a/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx b/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx index 4776272c32..b2fda6fda0 100644 --- a/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx +++ b/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx @@ -38,10 +38,6 @@ If you use native Frame Processor Plugins, make sure they are optimized for real - Prefer plugins that support **GPU acceleration**. For Tensorflow, this might be the CoreML or Metal GPU delegates - For operations such as resizing, **prefer GPU or CPU vector acceleration** (e.g. Accelerate/vImage) instead of just array loops -## ESLint react-hooks plugin - -If you are using the [react-hooks ESLint plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks), make sure to add `useFrameProcessor` and `useSkiaFrameProcessor` to `additionalHooks` inside your ESLint config so dependencies are detected properly. (See ["advanced configuration"](https://www.npmjs.com/package/eslint-plugin-react-hooks#advanced-configuration)) - ## Technical ### Frame Processors diff --git a/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx b/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx index b60a235e5a..53fc83ee2f 100644 --- a/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx +++ b/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx @@ -34,7 +34,7 @@ function App() { // highlight-next-line const faces = scanFaces(frame) console.log(`Faces in Frame: ${faces}`) - }, []) + }) return ( diff --git a/docs/docs/guides/PIXEL_FORMATS.mdx b/docs/docs/guides/PIXEL_FORMATS.mdx index 431cecefb3..c5a37283d2 100644 --- a/docs/docs/guides/PIXEL_FORMATS.mdx +++ b/docs/docs/guides/PIXEL_FORMATS.mdx @@ -38,7 +38,7 @@ function App() { const frameProcessor = useFrameProcessor((frame) => { 'worklet' console.log(frame.pixelFormat) // <-- "rgb" - }, []) + }) return ( ( - () => ({ zoom: zoom.value }), - [zoom] - ) + const animatedProps = useAnimatedProps(() => ({ zoom: zoom.value })) // highlight-end if (device == null) return diff --git a/package/.eslintrc.js b/package/.eslintrc.js index 56b2157d6d..462ad2f7a4 100644 --- a/package/.eslintrc.js +++ b/package/.eslintrc.js @@ -74,14 +74,6 @@ module.exports = { '@typescript-eslint/no-non-null-assertion': 'error', '@typescript-eslint/no-unnecessary-condition': 'error', '@typescript-eslint/consistent-type-imports': 'warn', - - // react hooks - 'react-hooks/exhaustive-deps': [ - 'error', - { - additionalHooks: '(useDerivedValue|useAnimatedStyle|useAnimatedProps|useWorkletCallback|useFrameProcessor|useSkiaFrameProcessor)', - }, - ], }, env: { node: true, diff --git a/package/example/src/CameraPage.tsx b/package/example/src/CameraPage.tsx index 628a18acb6..c9ede28f9d 100644 --- a/package/example/src/CameraPage.tsx +++ b/package/example/src/CameraPage.tsx @@ -92,7 +92,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement { return { zoom: z, } - }, [maxZoom, minZoom, zoom]) + }) //#endregion //#region Callbacks diff --git a/package/example/src/views/CaptureButton.tsx b/package/example/src/views/CaptureButton.tsx index ecd041da45..cf4b952288 100644 --- a/package/example/src/views/CaptureButton.tsx +++ b/package/example/src/views/CaptureButton.tsx @@ -196,20 +196,17 @@ const _CaptureButton: React.FC = ({ }) //#endregion - const shadowStyle = useAnimatedStyle( - () => ({ - transform: [ - { - scale: withSpring(isPressingButton.value ? 1 : 0, { - mass: 1, - damping: 35, - stiffness: 300, - }), - }, - ], - }), - [isPressingButton], - ) + const shadowStyle = useAnimatedStyle(() => ({ + transform: [ + { + scale: withSpring(isPressingButton.value ? 1 : 0, { + mass: 1, + damping: 35, + stiffness: 300, + }), + }, + ], + })) const buttonStyle = useAnimatedStyle(() => { let scale: number if (enabled) { @@ -246,7 +243,7 @@ const _CaptureButton: React.FC = ({ }, ], } - }, [enabled, isPressingButton]) + }) return ( * ``` diff --git a/package/src/types/Frame.ts b/package/src/types/Frame.ts index f558c51bf3..cf11c01ebf 100644 --- a/package/src/types/Frame.ts +++ b/package/src/types/Frame.ts @@ -10,7 +10,7 @@ import type { PixelFormat } from './PixelFormat' * const frameProcessor = useFrameProcessor((frame) => { * 'worklet' * console.log(`Frame: ${frame.width}x${frame.height} (${frame.pixelFormat})`) - * }, []) + * }) * ``` */ export interface Frame { @@ -73,7 +73,7 @@ export interface Frame { * const data = new Uint8Array(buffer) * console.log(`Pixel at 0,0: RGB(${data[0]}, ${data[1]}, ${data[2]})`) * } - * }, []) + * }) * ``` */ toArrayBuffer(): ArrayBuffer