UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

239 lines (208 loc) • 6.85 kB
'use strict'; import type React from 'react'; import type { IReanimatedModule, IWorkletsModule, LayoutAnimationBatchItem, ShadowNodeWrapper, ShareableRef, Value3D, ValueRotation, WorkletFunction, } from '../commonTypes'; import { ReanimatedError } from '../errors'; import { getShadowNodeWrapperFromRef } from '../fabricUtils'; import { checkCppVersion } from '../platform-specific/checkCppVersion'; import { jsVersion } from '../platform-specific/jsVersion'; import { isFabric } from '../PlatformChecker'; import type { WorkletRuntime } from '../runtimes'; import { ReanimatedTurboModule } from '../specs'; import { WorkletsModule } from '../worklets'; import type { ReanimatedModuleProxy } from './reanimatedModuleProxy'; export function createNativeReanimatedModule(): IReanimatedModule { return new NativeReanimatedModule(); } function assertSingleReanimatedInstance() { if ( global._REANIMATED_VERSION_JS !== undefined && global._REANIMATED_VERSION_JS !== jsVersion ) { throw new ReanimatedError( `Another instance of Reanimated was detected. See \`https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#another-instance-of-reanimated-was-detected\` for more details. Previous: ${global._REANIMATED_VERSION_JS}, current: ${jsVersion}.` ); } } class NativeReanimatedModule implements IReanimatedModule { /** * We keep the instance of `WorkletsModule` here to keep correct coupling of * the modules and initialization order. */ #workletsModule: IWorkletsModule; #reanimatedModuleProxy: ReanimatedModuleProxy; constructor() { this.#workletsModule = WorkletsModule; // These checks have to split since version checking depend on the execution order if (__DEV__) { assertSingleReanimatedInstance(); } global._REANIMATED_VERSION_JS = jsVersion; if (global.__reanimatedModuleProxy === undefined && ReanimatedTurboModule) { if (!ReanimatedTurboModule.installTurboModule()) { // This path means that React Native has failed on reload. // We don't want to throw any errors to not mislead the users // that the problem is related to Reanimated. // We install a DummyReanimatedModuleProxy instead. this.#reanimatedModuleProxy = new DummyReanimatedModuleProxy(); return; } } if (global.__reanimatedModuleProxy === undefined) { throw new ReanimatedError( `Native part of Reanimated doesn't seem to be initialized. See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#native-part-of-reanimated-doesnt-seem-to-be-initialized for more details.` ); } if (__DEV__) { checkCppVersion(); } this.#reanimatedModuleProxy = global.__reanimatedModuleProxy; } scheduleOnUI<T>(shareable: ShareableRef<T>) { return this.#reanimatedModuleProxy.scheduleOnUI(shareable); } executeOnUIRuntimeSync<T, R>(shareable: ShareableRef<T>): R { return this.#reanimatedModuleProxy.executeOnUIRuntimeSync(shareable); } createWorkletRuntime(name: string, initializer: ShareableRef<() => void>) { return this.#reanimatedModuleProxy.createWorkletRuntime(name, initializer); } scheduleOnRuntime<T>( workletRuntime: WorkletRuntime, shareableWorklet: ShareableRef<T> ) { return this.#reanimatedModuleProxy.scheduleOnRuntime( workletRuntime, shareableWorklet ); } registerSensor( sensorType: number, interval: number, iosReferenceFrame: number, handler: ShareableRef<(data: Value3D | ValueRotation) => void> ) { return this.#reanimatedModuleProxy.registerSensor( sensorType, interval, iosReferenceFrame, handler ); } unregisterSensor(sensorId: number) { return this.#reanimatedModuleProxy.unregisterSensor(sensorId); } registerEventHandler<T>( eventHandler: ShareableRef<T>, eventName: string, emitterReactTag: number ) { return this.#reanimatedModuleProxy.registerEventHandler( eventHandler, eventName, emitterReactTag ); } unregisterEventHandler(id: number) { return this.#reanimatedModuleProxy.unregisterEventHandler(id); } getViewProp<T>( viewTag: number, propName: string, component: React.Component | undefined, // required on Fabric callback?: (result: T) => void ) { let shadowNodeWrapper; if (isFabric()) { shadowNodeWrapper = getShadowNodeWrapperFromRef( component as React.Component ); return this.#reanimatedModuleProxy.getViewProp( shadowNodeWrapper, propName, callback ); } return this.#reanimatedModuleProxy.getViewProp(viewTag, propName, callback); } configureLayoutAnimationBatch( layoutAnimationsBatch: LayoutAnimationBatchItem[] ) { this.#reanimatedModuleProxy.configureLayoutAnimationBatch( layoutAnimationsBatch ); } setShouldAnimateExitingForTag(viewTag: number, shouldAnimate: boolean) { this.#reanimatedModuleProxy.setShouldAnimateExitingForTag( viewTag, shouldAnimate ); } enableLayoutAnimations(flag: boolean) { this.#reanimatedModuleProxy.enableLayoutAnimations(flag); } configureProps(uiProps: string[], nativeProps: string[]) { this.#reanimatedModuleProxy.configureProps(uiProps, nativeProps); } subscribeForKeyboardEvents( handler: ShareableRef<WorkletFunction>, isStatusBarTranslucent: boolean, isNavigationBarTranslucent: boolean ) { return this.#reanimatedModuleProxy.subscribeForKeyboardEvents( handler, isStatusBarTranslucent, isNavigationBarTranslucent ); } unsubscribeFromKeyboardEvents(listenerId: number) { this.#reanimatedModuleProxy.unsubscribeFromKeyboardEvents(listenerId); } markNodeAsRemovable(shadowNodeWrapper: ShadowNodeWrapper) { this.#reanimatedModuleProxy.markNodeAsRemovable(shadowNodeWrapper); } unmarkNodeAsRemovable(viewTag: number) { this.#reanimatedModuleProxy.unmarkNodeAsRemovable(viewTag); } } class DummyReanimatedModuleProxy implements ReanimatedModuleProxy { scheduleOnUI(): void {} executeOnUIRuntimeSync() { return null!; } createWorkletRuntime() { return null!; } scheduleOnRuntime(): void {} configureLayoutAnimationBatch(): void {} setShouldAnimateExitingForTag(): void {} enableLayoutAnimations(): void {} configureProps(): void {} subscribeForKeyboardEvents(): number { return -1; } unsubscribeFromKeyboardEvents(): void {} markNodeAsRemovable(): void {} unmarkNodeAsRemovable(): void {} registerSensor(): number { return -1; } unregisterSensor(): void {} registerEventHandler(): number { return -1; } unregisterEventHandler(): void {} getViewProp() { return null!; } }