Skip to content

Commit

Permalink
Merge pull request #577 from nmassey/fix-worklets
Browse files Browse the repository at this point in the history
fix: gesture `onStart`, `onUpdate`, and `onEnd` (et al) should be worklets
  • Loading branch information
dohooo authored Sep 11, 2024
2 parents 32c8c36 + 17621ca commit 91a54a0
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/many-ads-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-native-reanimated-carousel': patch
---

fix: make gesture onStart/onUpdate/onEnd (et al) callbacks run as worklets again
23 changes: 23 additions & 0 deletions src/hooks/usePanGestureProxy.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,29 @@ describe("Using RNGH v2 gesture API", () => {
expect.objectContaining({ translationX: 20 }),
);
});

it("does not include console.error in the output", () => {
// if react-native-gesture-handler detects that some handlers are
// workletized and some are not, it will log an error to the
// console. We'd like to make sure that this doesn't happen.

// The error that would be shown looks like:
// [react-native-gesture-handler] Some of the callbacks in the gesture are worklets and some are not. Either make sure that all calbacks are marked as 'worklet' if you wish to run them on the UI thread or use '.runOnJS(true)' modifier on the gesture explicitly to run all callbacks on the JS thread.

const panHandlers = mockedEventHandlers();
const panHandlersFromUser = mockedEventHandlersFromUser();

jest.spyOn(console, "error");

render(<SingleHandler handlers={panHandlers} handlersFromUser={panHandlersFromUser} treatStartAsUpdate />);
fireGestureHandler<PanGesture>(getByGestureTestId("pan"), [
{ state: State.BEGAN },
{ state: State.ACTIVE },
{ state: State.END },
]);

expect(console.error).not.toBeCalled();
});
});

describe("Event list validation", () => {
Expand Down
40 changes: 39 additions & 1 deletion src/hooks/usePanGestureProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,32 @@ export const usePanGestureProxy = (

// Save the original gesture callbacks
const originalGestures = {
onBegin: gesture.onBegin,
onStart: gesture.onStart,
onUpdate: gesture.onUpdate,
onEnd: gesture.onEnd,
onFinalize: gesture.onFinalize,
};

// Save the user defined gesture callbacks
const userDefinedConflictGestures: {
onBegin?: Parameters<(typeof gesture)["onBegin"]>[0]
onStart?: Parameters<(typeof gesture)["onStart"]>[0]
onUpdate?: Parameters<(typeof gesture)["onUpdate"]>[0]
onEnd?: Parameters<(typeof gesture)["onEnd"]>[0]
onFinalize?: Parameters<(typeof gesture)["onFinalize"]>[0]
} = {
onBegin: undefined,
onStart: undefined,
onUpdate: undefined,
onEnd: undefined,
onFinalize: undefined,
};

const fakeOnBegin: typeof gesture.onBegin = (cb) => {
// Using fakeOnBegin to save the user defined callback
userDefinedConflictGestures.onBegin = cb;
return gesture;
};

const fakeOnStart: typeof gesture.onStart = (cb) => {
Expand All @@ -61,40 +73,66 @@ export const usePanGestureProxy = (
return gesture;
};

const fakeOnFinalize: typeof gesture.onFinalize = (cb) => {
// Using fakeOnFinalize to save the user defined callback
userDefinedConflictGestures.onFinalize = cb;
return gesture;
};

// Setup the fake callbacks
gesture.onBegin = fakeOnBegin;
gesture.onStart = fakeOnStart;
gesture.onUpdate = fakeOnUpdate;
gesture.onEnd = fakeOnEnd;
gesture.onFinalize = fakeOnFinalize;

if (onConfigurePanGesture)
// Get the gesture with the user defined configuration
onConfigurePanGesture(gesture);

// Restore the original callbacks
gesture.onBegin = originalGestures.onBegin;
gesture.onStart = originalGestures.onStart;
gesture.onUpdate = originalGestures.onUpdate;
gesture.onEnd = originalGestures.onEnd;
gesture.onFinalize = originalGestures.onFinalize;

// Setup the original callbacks with the user defined callbacks
gesture
.onBegin((e) => {
"worklet";

if (userDefinedConflictGestures.onBegin)
userDefinedConflictGestures.onBegin(e);
})
.onStart((e) => {
"worklet";
onGestureStart(e);

if (userDefinedConflictGestures.onStart)
userDefinedConflictGestures.onStart(e);
})
.onUpdate((e) => {
"worklet";
onGestureUpdate(e);

if (userDefinedConflictGestures.onUpdate)
userDefinedConflictGestures.onUpdate(e);
})
.onEnd((e, success) => {
"worklet";
onGestureEnd(e, success);

if (userDefinedConflictGestures.onEnd)
userDefinedConflictGestures.onEnd(e, success);
});
})
.onFinalize((e, success) => {
"worklet";

if (userDefinedConflictGestures.onFinalize)
userDefinedConflictGestures.onFinalize(e, success);
})
;

return gesture;
}, [
Expand Down

0 comments on commit 91a54a0

Please sign in to comment.