UNPKG

react-native-vision-camera

Version:

A powerful, high-performance React Native Camera library.

59 lines (55 loc) 2.12 kB
declare global { // eslint-disable-next-line no-var var __frameProcessorRunAtTargetFpsMap: Record<string, number | undefined> | undefined } function getLastFrameProcessorCall(frameProcessorFuncId: string): number { 'worklet' return global.__frameProcessorRunAtTargetFpsMap?.[frameProcessorFuncId] ?? 0 } function setLastFrameProcessorCall(frameProcessorFuncId: string, value: number): void { 'worklet' if (global.__frameProcessorRunAtTargetFpsMap == null) global.__frameProcessorRunAtTargetFpsMap = {} global.__frameProcessorRunAtTargetFpsMap[frameProcessorFuncId] = value } /** * Runs the given {@linkcode func} at the given target {@linkcode fps} rate. * * {@linkcode runAtTargetFps} still executes the given {@linkcode func} synchronously, * so this is only useful for throttling calls to a plugin or logger. * * For example, if you want to scan faces only once per second to avoid excessive * CPU usage, use {@linkcode runAtTargetFps runAtTargetFps(1, ...)}. * * @param fps The target FPS rate at which the given function should be executed * @param func The function to execute. * @returns The result of the function if it was executed, or `undefined` otherwise. * @worklet * @example * * ```ts * const frameProcessor = useFrameProcessor((frame) => { * 'worklet' * console.log('New Frame') * runAtTargetFps(5, () => { * 'worklet' * const faces = detectFaces(frame) * console.log(`Detected a new face: ${faces[0]}`) * }) * }) * ``` */ export function runAtTargetFps<T>(fps: number, func: () => T): T | undefined { 'worklet' // @ts-expect-error // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const funcId = func.__workletHash ?? '1' const targetIntervalMs = 1000 / fps // <-- 60 FPS => 16,6667ms interval const now = performance.now() const diffToLastCall = now - getLastFrameProcessorCall(funcId) if (diffToLastCall >= targetIntervalMs) { setLastFrameProcessorCall(funcId, now) // Last Frame Processor call is already so long ago that we want to make a new call return func() } return undefined }