chore: Remove semicolons (#1846)
* chore: Disable `semi` in Prettier * chore: Format w/o semi * Remove more `;` * Lint example * More ;
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import type { Frame, FrameInternal } from './Frame';
|
||||
import type { FrameProcessor } from './CameraProps';
|
||||
import { CameraRuntimeError } from './CameraError';
|
||||
import type { Frame, FrameInternal } from './Frame'
|
||||
import type { FrameProcessor } from './CameraProps'
|
||||
import { CameraRuntimeError } from './CameraError'
|
||||
|
||||
// only import typescript types
|
||||
import type TWorklets from 'react-native-worklets-core';
|
||||
import { CameraModule } from './NativeCameraModule';
|
||||
import { assertJSIAvailable } from './JSIHelper';
|
||||
import type TWorklets from 'react-native-worklets-core'
|
||||
import { CameraModule } from './NativeCameraModule'
|
||||
import { assertJSIAvailable } from './JSIHelper'
|
||||
|
||||
type BasicParameterType = string | number | boolean | undefined;
|
||||
type ParameterType = BasicParameterType | BasicParameterType[] | Record<string, BasicParameterType | undefined>;
|
||||
type BasicParameterType = string | number | boolean | undefined
|
||||
type ParameterType = BasicParameterType | BasicParameterType[] | Record<string, BasicParameterType | undefined>
|
||||
|
||||
interface FrameProcessorPlugin {
|
||||
/**
|
||||
@@ -17,96 +17,97 @@ interface FrameProcessorPlugin {
|
||||
* @param options (optional) Additional options. Options will be converted to a native dictionary
|
||||
* @returns (optional) A value returned from the native Frame Processor Plugin (or undefined)
|
||||
*/
|
||||
call: (frame: Frame, options?: Record<string, ParameterType>) => ParameterType;
|
||||
call: (frame: Frame, options?: Record<string, ParameterType>) => ParameterType
|
||||
}
|
||||
|
||||
interface TVisionCameraProxy {
|
||||
setFrameProcessor: (viewTag: number, frameProcessor: FrameProcessor) => void;
|
||||
removeFrameProcessor: (viewTag: number) => void;
|
||||
setFrameProcessor: (viewTag: number, frameProcessor: FrameProcessor) => void
|
||||
removeFrameProcessor: (viewTag: number) => void
|
||||
/**
|
||||
* Creates a new instance of a Frame Processor Plugin.
|
||||
* The Plugin has to be registered on the native side, otherwise this returns `undefined`
|
||||
*/
|
||||
getFrameProcessorPlugin: (name: string) => FrameProcessorPlugin | undefined;
|
||||
getFrameProcessorPlugin: (name: string) => FrameProcessorPlugin | undefined
|
||||
}
|
||||
|
||||
let hasWorklets = false;
|
||||
let isAsyncContextBusy = { value: false };
|
||||
let hasWorklets = false
|
||||
let isAsyncContextBusy = { value: false }
|
||||
let runOnAsyncContext = (_frame: Frame, _func: () => void): void => {
|
||||
throw new CameraRuntimeError(
|
||||
'system/frame-processors-unavailable',
|
||||
'Frame Processors are not available, react-native-worklets-core is not installed!',
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
assertJSIAvailable();
|
||||
assertJSIAvailable()
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { Worklets } = require('react-native-worklets-core') as typeof TWorklets;
|
||||
const { Worklets } = require('react-native-worklets-core') as typeof TWorklets
|
||||
|
||||
isAsyncContextBusy = Worklets.createSharedValue(false);
|
||||
const asyncContext = Worklets.createContext('VisionCamera.async');
|
||||
isAsyncContextBusy = Worklets.createSharedValue(false)
|
||||
const asyncContext = Worklets.createContext('VisionCamera.async')
|
||||
runOnAsyncContext = Worklets.createRunInContextFn((frame: Frame, func: () => void) => {
|
||||
'worklet';
|
||||
'worklet'
|
||||
try {
|
||||
// Call long-running function
|
||||
func();
|
||||
func()
|
||||
} finally {
|
||||
// Potentially delete Frame if we were the last ref
|
||||
(frame as FrameInternal).decrementRefCount();
|
||||
const internal = frame as FrameInternal
|
||||
internal.decrementRefCount()
|
||||
|
||||
isAsyncContextBusy.value = false;
|
||||
isAsyncContextBusy.value = false
|
||||
}
|
||||
}, asyncContext);
|
||||
hasWorklets = true;
|
||||
}, asyncContext)
|
||||
hasWorklets = true
|
||||
} catch (e) {
|
||||
// Worklets are not installed, so Frame Processors are disabled.
|
||||
}
|
||||
|
||||
let proxy: TVisionCameraProxy = {
|
||||
getFrameProcessorPlugin: () => {
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!');
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!')
|
||||
},
|
||||
removeFrameProcessor: () => {
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!');
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!')
|
||||
},
|
||||
setFrameProcessor: () => {
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!');
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Frame Processors are not enabled!')
|
||||
},
|
||||
};
|
||||
}
|
||||
if (hasWorklets) {
|
||||
// Install native Frame Processor Runtime Manager
|
||||
const result = CameraModule.installFrameProcessorBindings() as unknown;
|
||||
const result = CameraModule.installFrameProcessorBindings() as unknown
|
||||
if (result !== true)
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Failed to install Frame Processor JSI bindings!');
|
||||
throw new CameraRuntimeError('system/frame-processors-unavailable', 'Failed to install Frame Processor JSI bindings!')
|
||||
|
||||
// @ts-expect-error global is untyped, it's a C++ host-object
|
||||
proxy = global.VisionCameraProxy as TVisionCameraProxy;
|
||||
proxy = global.VisionCameraProxy as TVisionCameraProxy
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (proxy == null) {
|
||||
throw new CameraRuntimeError(
|
||||
'system/frame-processors-unavailable',
|
||||
'Failed to install VisionCameraProxy. Are Frame Processors properly enabled?',
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const VisionCameraProxy = proxy;
|
||||
export const VisionCameraProxy = proxy
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __frameProcessorRunAtTargetFpsMap: Record<string, number | undefined> | undefined;
|
||||
var __frameProcessorRunAtTargetFpsMap: Record<string, number | undefined> | undefined
|
||||
}
|
||||
|
||||
function getLastFrameProcessorCall(frameProcessorFuncId: string): number {
|
||||
'worklet';
|
||||
return global.__frameProcessorRunAtTargetFpsMap?.[frameProcessorFuncId] ?? 0;
|
||||
'worklet'
|
||||
return global.__frameProcessorRunAtTargetFpsMap?.[frameProcessorFuncId] ?? 0
|
||||
}
|
||||
function setLastFrameProcessorCall(frameProcessorFuncId: string, value: number): void {
|
||||
'worklet';
|
||||
if (global.__frameProcessorRunAtTargetFpsMap == null) global.__frameProcessorRunAtTargetFpsMap = {};
|
||||
global.__frameProcessorRunAtTargetFpsMap[frameProcessorFuncId] = value;
|
||||
'worklet'
|
||||
if (global.__frameProcessorRunAtTargetFpsMap == null) global.__frameProcessorRunAtTargetFpsMap = {}
|
||||
global.__frameProcessorRunAtTargetFpsMap[frameProcessorFuncId] = value
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,20 +135,20 @@ function setLastFrameProcessorCall(frameProcessorFuncId: string, value: number):
|
||||
* ```
|
||||
*/
|
||||
export function runAtTargetFps<T>(fps: number, func: () => T): T | undefined {
|
||||
'worklet';
|
||||
'worklet'
|
||||
// @ts-expect-error
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const funcId = func.__workletHash ?? '1';
|
||||
const funcId = func.__workletHash ?? '1'
|
||||
|
||||
const targetIntervalMs = 1000 / fps; // <-- 60 FPS => 16,6667ms interval
|
||||
const now = performance.now();
|
||||
const diffToLastCall = now - getLastFrameProcessorCall(funcId);
|
||||
const targetIntervalMs = 1000 / fps // <-- 60 FPS => 16,6667ms interval
|
||||
const now = performance.now()
|
||||
const diffToLastCall = now - getLastFrameProcessorCall(funcId)
|
||||
if (diffToLastCall >= targetIntervalMs) {
|
||||
setLastFrameProcessorCall(funcId, now);
|
||||
setLastFrameProcessorCall(funcId, now)
|
||||
// Last Frame Processor call is already so long ago that we want to make a new call
|
||||
return func();
|
||||
return func()
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,19 +176,20 @@ export function runAtTargetFps<T>(fps: number, func: () => T): T | undefined {
|
||||
* ```
|
||||
*/
|
||||
export function runAsync(frame: Frame, func: () => void): void {
|
||||
'worklet';
|
||||
'worklet'
|
||||
|
||||
if (isAsyncContextBusy.value) {
|
||||
// async context is currently busy, we cannot schedule new work in time.
|
||||
// drop this frame/runAsync call.
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Increment ref count by one
|
||||
(frame as FrameInternal).incrementRefCount();
|
||||
const internal = frame as FrameInternal
|
||||
internal.incrementRefCount()
|
||||
|
||||
isAsyncContextBusy.value = true;
|
||||
isAsyncContextBusy.value = true
|
||||
|
||||
// Call in separate background context
|
||||
runOnAsyncContext(frame, func);
|
||||
runOnAsyncContext(frame, func)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user