Skip to content

Add worklet() func that throws if value is not a worklet#187

Merged
mrousavy merged 4 commits into
mainfrom
feat/add-worklet-func
May 3, 2024
Merged

Add worklet() func that throws if value is not a worklet#187
mrousavy merged 4 commits into
mainfrom
feat/add-worklet-func

Conversation

@mrousavy
Copy link
Copy Markdown
Member

@mrousavy mrousavy commented May 3, 2024

Adds the worklet(...) and isWorklet(..) functions:

worklet(...)

const func = worklet(() => {
  'worklet'
  return "hello!"
})
context.runAsync(func)

This will do some runtime checking to ensure the given function is a worklet (uses __initData, __closure and __workletHash) and throws with some useful debugging information if it isn't.

I will use this in VisionCamera's useFrameProcessor function to make sure people pass in worklets (funcs with 'worklet' directive) and they installed the babel plugin properly. Otherwise the error is a bit cryptic, with this it's more clear what went wrong:

- ERROR  Error: The given function ("") is not a Worklet!
- - Make sure react-native-worklets-core is installed properly! 
- - Make sure to add the react-native-worklets-core babel plugin to your babel.config.js! 
- - Make sure that no other plugin overrides the react-native-worklets-core babel plugin! 
- - Make sure the function  is decorated with the 'worklet' directive! 
- Expected  to contain __workletHash and __initData, but  has these properties: 
- 
- This error is located at:
-     in App
-     in RCTView (created by View)
-     in View (created by AppContainer)
-     in RCTView (created by View)
-     in View (created by AppContainer)
-     in AppContainer
-     in WorkletsExample(RootComponent), js engine: hermes

Also, the returned type is useful because you can now safely access func.__workletHash or func.__closure.

isWorklet(...)

Same thing as worklet(...), but only returns false if the function is not a worklet instead of throwing an error.

Changes to useWorklet(..)

The useWorklet hook now uses worklet(..) underneath to ensure the user passed in a correct Worklet.

Also, I now removed the dependencies parameter by automatically using the values in func.__closure for the useMemo's dependencies. This is pretty cool because people often forgot to the hook dependencies in useFrameProcessor and wondered why it didn't update/re-build after a re-render.

@mrousavy
Copy link
Copy Markdown
Member Author

mrousavy commented May 3, 2024

@chrfalch some questions;

  1. Can we make the babel plugin automatically transpile functions to worklets when they are wrapped in a worklet(...) call? That way users could do:
    const func = worklet(() => {
      return "this is a worklet, without the directive!"
    })
    ...and skip adding the 'worklet' directive in these cases..
  2. Can we remove the legacy Reanimated code branches? The ones with __location and asString and stuff...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant